wined3d: Simplify shader selection.
This commit is contained in:
parent
5190792b33
commit
d74cb4571b
|
@ -5821,14 +5821,10 @@ static void set_bumpmat_arbfp(struct wined3d_context *context, const struct wine
|
||||||
|
|
||||||
if (use_ps(state))
|
if (use_ps(state))
|
||||||
{
|
{
|
||||||
|
/* The pixel shader has to know the bump env matrix. Do a constants
|
||||||
|
* update. */
|
||||||
if (stage && (state->pixel_shader->reg_maps.bumpmat & (1 << stage)))
|
if (stage && (state->pixel_shader->reg_maps.bumpmat & (1 << stage)))
|
||||||
{
|
context->load_constants = 1;
|
||||||
/* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
|
|
||||||
* anyway
|
|
||||||
*/
|
|
||||||
if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT))
|
|
||||||
context_apply_state(context, state, STATE_PIXELSHADERCONSTANT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(device->shader_backend == &arb_program_shader_backend) {
|
if(device->shader_backend == &arb_program_shader_backend) {
|
||||||
/* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants */
|
/* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants */
|
||||||
|
@ -5861,14 +5857,10 @@ static void tex_bumpenvlum_arbfp(struct wined3d_context *context,
|
||||||
|
|
||||||
if (use_ps(state))
|
if (use_ps(state))
|
||||||
{
|
{
|
||||||
|
/* The pixel shader has to know the luminance offset. Do a constants
|
||||||
|
* update. */
|
||||||
if (stage && (state->pixel_shader->reg_maps.luminanceparams & (1 << stage)))
|
if (stage && (state->pixel_shader->reg_maps.luminanceparams & (1 << stage)))
|
||||||
{
|
context->load_constants = 1;
|
||||||
/* The pixel shader has to know the luminance offset. Do a constants update if it
|
|
||||||
* isn't scheduled anyway
|
|
||||||
*/
|
|
||||||
if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT))
|
|
||||||
context_apply_state(context, state, STATE_PIXELSHADERCONSTANT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(device->shader_backend == &arb_program_shader_backend) {
|
if(device->shader_backend == &arb_program_shader_backend) {
|
||||||
/* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants */
|
/* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants */
|
||||||
|
@ -6391,7 +6383,6 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi
|
||||||
const struct wined3d_device *device = context->swapchain->device;
|
const struct wined3d_device *device = context->swapchain->device;
|
||||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||||
struct shader_arb_priv *priv = device->fragment_priv;
|
struct shader_arb_priv *priv = device->fragment_priv;
|
||||||
BOOL use_vshader = use_vs(state);
|
|
||||||
BOOL use_pshader = use_ps(state);
|
BOOL use_pshader = use_ps(state);
|
||||||
struct ffp_frag_settings settings;
|
struct ffp_frag_settings settings;
|
||||||
const struct arbfp_ffp_desc *desc;
|
const struct arbfp_ffp_desc *desc;
|
||||||
|
@ -6412,9 +6403,9 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi
|
||||||
state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR));
|
state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR));
|
||||||
state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
|
state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE));
|
||||||
}
|
}
|
||||||
else if (use_pshader && !isStateDirty(context, context->state_table[STATE_VSHADER].representative))
|
else if (use_pshader)
|
||||||
{
|
{
|
||||||
device->shader_backend->shader_select(context, use_pshader, use_vshader);
|
context->select_shader = 1;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -6464,24 +6455,8 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi
|
||||||
context->last_was_pshader = TRUE;
|
context->last_was_pshader = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, select the shader. If a pixel shader is used, it will be set and enabled by the shader backend.
|
context->select_shader = 1;
|
||||||
* If this shader backend is arbfp(most likely), then it will simply overwrite the last fixed function
|
context->load_constants = 1;
|
||||||
* replacement shader. If the shader backend is not ARB, it currently is important that the opengl implementation
|
|
||||||
* type overwrites GL_ARB_fragment_program. This is currently the case with GLSL. If we really want to use
|
|
||||||
* atifs or nvrc pixel shaders with arb fragment programs we'd have to disable GL_FRAGMENT_PROGRAM_ARB here
|
|
||||||
*
|
|
||||||
* Don't call shader_select if the vertex shader is dirty, because it will be called later on by the vertex
|
|
||||||
* shader handler.
|
|
||||||
*/
|
|
||||||
if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
|
|
||||||
{
|
|
||||||
device->shader_backend->shader_select(context, use_pshader, use_vshader);
|
|
||||||
|
|
||||||
if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader))
|
|
||||||
context_apply_state(context, state, STATE_VERTEXSHADERCONSTANT);
|
|
||||||
}
|
|
||||||
if (use_pshader)
|
|
||||||
context_apply_state(context, state, STATE_PIXELSHADERCONSTANT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We can't link the fog states to the fragment state directly since the
|
/* We can't link the fog states to the fragment state directly since the
|
||||||
|
|
|
@ -926,9 +926,6 @@ static void textransform(struct wined3d_context *context, const struct wined3d_s
|
||||||
|
|
||||||
static void atifs_apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
static void atifs_apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||||
{
|
{
|
||||||
const struct wined3d_device *device = context->swapchain->device;
|
|
||||||
BOOL use_vshader = use_vs(state);
|
|
||||||
|
|
||||||
context->last_was_pshader = use_ps(state);
|
context->last_was_pshader = use_ps(state);
|
||||||
/* The ATIFS code does not support pixel shaders currently, but we have to
|
/* The ATIFS code does not support pixel shaders currently, but we have to
|
||||||
* provide a state handler to call shader_select to select a vertex shader
|
* provide a state handler to call shader_select to select a vertex shader
|
||||||
|
@ -943,13 +940,8 @@ static void atifs_apply_pixelshader(struct wined3d_context *context, const struc
|
||||||
* startup, and blitting disables all shaders and dirtifies all shader
|
* startup, and blitting disables all shaders and dirtifies all shader
|
||||||
* states. If atifs can deal with this it keeps the rest of the code
|
* states. If atifs can deal with this it keeps the rest of the code
|
||||||
* simpler. */
|
* simpler. */
|
||||||
if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
|
context->select_shader = 1;
|
||||||
{
|
context->load_constants = 1;
|
||||||
device->shader_backend->shader_select(context, FALSE, use_vshader);
|
|
||||||
|
|
||||||
if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && use_vshader)
|
|
||||||
context_apply_state(context, state, STATE_VERTEXSHADERCONSTANT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void atifs_srgbwriteenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
static void atifs_srgbwriteenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||||
|
|
|
@ -1711,11 +1711,10 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
|
||||||
/* Disable shaders */
|
/* Disable shaders */
|
||||||
ENTER_GL();
|
ENTER_GL();
|
||||||
device->shader_backend->shader_select(context, FALSE, FALSE);
|
device->shader_backend->shader_select(context, FALSE, FALSE);
|
||||||
|
context->select_shader = 1;
|
||||||
|
context->load_constants = 1;
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
|
||||||
context_invalidate_state(context, STATE_VSHADER);
|
|
||||||
context_invalidate_state(context, STATE_PIXELSHADER);
|
|
||||||
|
|
||||||
/* Call ENTER_GL() once for all gl calls below. In theory we should not call
|
/* Call ENTER_GL() once for all gl calls below. In theory we should not call
|
||||||
* helper functions in between gl calls. This function is full of context_invalidate_state
|
* helper functions in between gl calls. This function is full of context_invalidate_state
|
||||||
* which can safely be called from here, we only lock once instead locking/unlocking
|
* which can safely be called from here, we only lock once instead locking/unlocking
|
||||||
|
@ -2365,6 +2364,18 @@ BOOL context_apply_draw_state(struct wined3d_context *context, struct wined3d_de
|
||||||
state_table[rep].apply(context, state, rep);
|
state_table[rep].apply(context, state, rep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context->select_shader)
|
||||||
|
{
|
||||||
|
device->shader_backend->shader_select(context, use_ps(state), use_vs(state));
|
||||||
|
context->select_shader = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->load_constants)
|
||||||
|
{
|
||||||
|
device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
|
||||||
|
context->load_constants = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
|
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
|
||||||
{
|
{
|
||||||
context_check_fbo_status(context, GL_FRAMEBUFFER);
|
context_check_fbo_status(context, GL_FRAMEBUFFER);
|
||||||
|
|
|
@ -599,15 +599,7 @@ static void state_alpha(struct wined3d_context *context, const struct wined3d_st
|
||||||
|
|
||||||
static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||||
{
|
{
|
||||||
const struct wined3d_device *device = context->swapchain->device;
|
context->load_constants = 1;
|
||||||
|
|
||||||
/* Vertex and pixel shader states will call a shader upload, don't do
|
|
||||||
* anything as long one of them has an update pending. */
|
|
||||||
if (isStateDirty(context, STATE_VDECL)
|
|
||||||
|| isStateDirty(context, STATE_PIXELSHADER))
|
|
||||||
return;
|
|
||||||
|
|
||||||
device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||||
|
@ -640,12 +632,8 @@ static void state_clipping(struct wined3d_context *context, const struct wined3d
|
||||||
|
|
||||||
/* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
|
/* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
|
||||||
* hardcoded into the shader. Update the shader to update the enabled clipplanes */
|
* hardcoded into the shader. Update the shader to update the enabled clipplanes */
|
||||||
if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
|
context->select_shader = 1;
|
||||||
{
|
context->load_constants = 1;
|
||||||
device->shader_backend->shader_select(context, use_ps(state), TRUE);
|
|
||||||
if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
|
|
||||||
shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
|
/* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
|
||||||
|
@ -3618,14 +3606,9 @@ static void tex_bumpenvlscale(struct wined3d_context *context, const struct wine
|
||||||
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
|
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
|
||||||
const struct wined3d_shader *ps = state->pixel_shader;
|
const struct wined3d_shader *ps = state->pixel_shader;
|
||||||
|
|
||||||
|
/* The pixel shader has to know the luminance scale. Do a constants update. */
|
||||||
if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
|
if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
|
||||||
{
|
context->load_constants = 1;
|
||||||
/* The pixel shader has to know the luminance scale. Do a constants
|
|
||||||
* update if it isn't scheduled anyway. */
|
|
||||||
if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
|
|
||||||
&& !isStateDirty(context, STATE_PIXELSHADER))
|
|
||||||
shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||||
|
@ -3738,12 +3721,9 @@ static void sampler(struct wined3d_context *context, const struct wined3d_state
|
||||||
|
|
||||||
void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||||
{
|
{
|
||||||
const struct wined3d_device *device = context->swapchain->device;
|
|
||||||
BOOL use_vshader = use_vs(state);
|
|
||||||
BOOL use_pshader = use_ps(state);
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (use_pshader)
|
if (use_ps(state))
|
||||||
{
|
{
|
||||||
if (!context->last_was_pshader)
|
if (!context->last_was_pshader)
|
||||||
{
|
{
|
||||||
|
@ -3776,13 +3756,8 @@ void apply_pixelshader(struct wined3d_context *context, const struct wined3d_sta
|
||||||
context->last_was_pshader = FALSE;
|
context->last_was_pshader = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
|
context->select_shader = 1;
|
||||||
{
|
context->load_constants = 1;
|
||||||
device->shader_backend->shader_select(context, use_pshader, use_vshader);
|
|
||||||
|
|
||||||
if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader))
|
|
||||||
shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||||
|
@ -3790,14 +3765,9 @@ static void shader_bumpenvmat(struct wined3d_context *context, const struct wine
|
||||||
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
|
DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
|
||||||
const struct wined3d_shader *ps = state->pixel_shader;
|
const struct wined3d_shader *ps = state->pixel_shader;
|
||||||
|
|
||||||
|
/* The pixel shader has to know the bump env matrix. Do a constants update. */
|
||||||
if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
|
if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
|
||||||
{
|
context->load_constants = 1;
|
||||||
/* The pixel shader has to know the bump env matrix. Do a constants
|
|
||||||
* update if it isn't scheduled anyway. */
|
|
||||||
if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
|
|
||||||
&& !isStateDirty(context, STATE_PIXELSHADER))
|
|
||||||
shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||||
|
@ -4580,7 +4550,6 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine
|
||||||
const struct wined3d_device *device = context->swapchain->device;
|
const struct wined3d_device *device = context->swapchain->device;
|
||||||
const struct wined3d_gl_info *gl_info = context->gl_info;
|
const struct wined3d_gl_info *gl_info = context->gl_info;
|
||||||
BOOL useVertexShaderFunction = use_vs(state);
|
BOOL useVertexShaderFunction = use_vs(state);
|
||||||
BOOL usePixelShaderFunction = use_ps(state);
|
|
||||||
BOOL updateFog = FALSE;
|
BOOL updateFog = FALSE;
|
||||||
BOOL transformed;
|
BOOL transformed;
|
||||||
BOOL wasrhw = context->last_was_rhw;
|
BOOL wasrhw = context->last_was_rhw;
|
||||||
|
@ -4684,18 +4653,9 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vertex and pixel shaders are applied together, so let the last dirty
|
|
||||||
* state do the application. */
|
|
||||||
if (!isStateDirty(context, STATE_PIXELSHADER))
|
|
||||||
{
|
|
||||||
device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
|
|
||||||
|
|
||||||
if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)
|
|
||||||
&& (useVertexShaderFunction || usePixelShaderFunction))
|
|
||||||
shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
|
|
||||||
}
|
|
||||||
|
|
||||||
context->last_was_vshader = useVertexShaderFunction;
|
context->last_was_vshader = useVertexShaderFunction;
|
||||||
|
context->select_shader = 1;
|
||||||
|
context->load_constants = 1;
|
||||||
|
|
||||||
if (updateFog)
|
if (updateFog)
|
||||||
context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
|
context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
|
||||||
|
@ -4753,8 +4713,7 @@ static void viewport_vertexpart(struct wined3d_context *context, const struct wi
|
||||||
if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
|
if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
|
||||||
state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
|
state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
|
||||||
/* Update the position fixup. */
|
/* Update the position fixup. */
|
||||||
if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
|
context->load_constants = 1;
|
||||||
shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
|
||||||
|
|
|
@ -1084,21 +1084,23 @@ struct wined3d_context
|
||||||
DWORD tid; /* Thread ID which owns this context at the moment */
|
DWORD tid; /* Thread ID which owns this context at the moment */
|
||||||
|
|
||||||
/* Stores some information about the context state for optimization */
|
/* Stores some information about the context state for optimization */
|
||||||
WORD render_offscreen : 1;
|
DWORD render_offscreen : 1;
|
||||||
WORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */
|
DWORD last_was_rhw : 1; /* true iff last draw_primitive was in xyzrhw mode */
|
||||||
WORD last_was_pshader : 1;
|
DWORD last_was_pshader : 1;
|
||||||
WORD last_was_vshader : 1;
|
DWORD last_was_vshader : 1;
|
||||||
WORD namedArraysLoaded : 1;
|
DWORD namedArraysLoaded : 1;
|
||||||
WORD numberedArraysLoaded : 1;
|
DWORD numberedArraysLoaded : 1;
|
||||||
WORD last_was_blit : 1;
|
DWORD last_was_blit : 1;
|
||||||
WORD last_was_ckey : 1;
|
DWORD last_was_ckey : 1;
|
||||||
WORD fog_coord : 1;
|
DWORD fog_coord : 1;
|
||||||
WORD fog_enabled : 1;
|
DWORD fog_enabled : 1;
|
||||||
WORD num_untracked_materials : 2; /* Max value 2 */
|
DWORD num_untracked_materials : 2; /* Max value 2 */
|
||||||
WORD current : 1;
|
DWORD current : 1;
|
||||||
WORD destroyed : 1;
|
DWORD destroyed : 1;
|
||||||
WORD valid : 1;
|
DWORD valid : 1;
|
||||||
WORD padding : 1;
|
DWORD select_shader : 1;
|
||||||
|
DWORD load_constants : 1;
|
||||||
|
DWORD padding : 15;
|
||||||
BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */
|
BYTE texShaderBumpMap; /* MAX_TEXTURES, 8 */
|
||||||
BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */
|
BYTE lastWasPow2Texture; /* MAX_TEXTURES, 8 */
|
||||||
DWORD numbered_array_mask;
|
DWORD numbered_array_mask;
|
||||||
|
|
Loading…
Reference in New Issue