wined3d: Get rid of IWineD3DPixelShaderImpl.

This commit is contained in:
Henri Verbeet 2011-03-29 19:21:52 +02:00 committed by Alexandre Julliard
parent 4674b94d23
commit 99bed5d41d
6 changed files with 129 additions and 132 deletions

View File

@ -1824,8 +1824,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
}
else if (ins->dst[0].reg.type == WINED3DSPR_COLOROUT && !ins->dst[0].reg.idx && pshader)
{
IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *) shader;
if(ctx->cur_ps_args->super.srgb_correction && ps->color0_mov)
if (ctx->cur_ps_args->super.srgb_correction && shader->u.ps.color0_mov)
{
shader_addline(buffer, "#mov handled in srgb write code\n");
return;
@ -3421,8 +3420,8 @@ static const DWORD *find_loop_control_values(IWineD3DBaseShaderImpl *This, DWORD
return NULL;
}
static void init_ps_input(const IWineD3DPixelShaderImpl *This, const struct arb_ps_compile_args *args,
struct shader_arb_ctx_priv *priv)
static void init_ps_input(const IWineD3DBaseShaderImpl *shader,
const struct arb_ps_compile_args *args, struct shader_arb_ctx_priv *priv)
{
static const char * const texcoords[8] =
{
@ -3430,7 +3429,7 @@ static void init_ps_input(const IWineD3DPixelShaderImpl *This, const struct arb_
"fragment.texcoord[4]", "fragment.texcoord[5]", "fragment.texcoord[6]", "fragment.texcoord[7]"
};
unsigned int i;
const struct wined3d_shader_signature_element *sig = This->baseShader.input_signature;
const struct wined3d_shader_signature_element *sig = shader->baseShader.input_signature;
const char *semantic_name;
DWORD semantic_idx;
@ -3496,20 +3495,20 @@ static void init_ps_input(const IWineD3DPixelShaderImpl *This, const struct arb_
}
/* GL locking is done by the caller */
static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This,
static GLuint shader_arb_generate_pshader(IWineD3DBaseShaderImpl *shader,
const struct wined3d_gl_info *gl_info, struct wined3d_shader_buffer *buffer,
const struct arb_ps_compile_args *args, struct arb_ps_compiled_shader *compiled)
{
const struct wined3d_shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
CONST DWORD *function = This->baseShader.function;
const struct wined3d_shader_reg_maps *reg_maps = &shader->baseShader.reg_maps;
const DWORD *function = shader->baseShader.function;
const local_constant *lconst;
GLuint retval;
char fragcolor[16];
DWORD *lconst_map = local_const_mapping((IWineD3DBaseShaderImpl *) This), next_local, cur;
DWORD *lconst_map = local_const_mapping(shader), next_local, cur;
struct shader_arb_ctx_priv priv_ctx;
BOOL dcl_td = FALSE;
BOOL want_nv_prog = FALSE;
struct arb_pshader_private *shader_priv = This->baseShader.backend_data;
struct arb_pshader_private *shader_priv = shader->baseShader.backend_data;
GLint errPos;
DWORD map;
@ -3519,7 +3518,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This,
for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
{
if (!(map & 1)
|| (This->color0_mov && i == This->color0_reg)
|| (shader->u.ps.color0_mov && i == shader->u.ps.color0_reg)
|| (reg_maps->shader_version.major < 2 && !i))
continue;
@ -3557,7 +3556,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This,
priv_ctx.cur_ps_args = args;
priv_ctx.compiled_fprog = compiled;
priv_ctx.cur_np2fixup_info = &compiled->np2fixup_info;
init_ps_input(This, args, &priv_ctx);
init_ps_input(shader, args, &priv_ctx);
list_init(&priv_ctx.control_frames);
/* Avoid enabling NV_fragment_program* if we do not need it.
@ -3636,11 +3635,17 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This,
if (reg_maps->shader_version.major < 2)
{
strcpy(fragcolor, "R0");
} else {
if(args->super.srgb_correction) {
if(This->color0_mov) {
sprintf(fragcolor, "R%u", This->color0_reg);
} else {
}
else
{
if (args->super.srgb_correction)
{
if (shader->u.ps.color0_mov)
{
sprintf(fragcolor, "R%u", shader->u.ps.color0_reg);
}
else
{
shader_addline(buffer, "TEMP TMP_COLOR;\n");
strcpy(fragcolor, "TMP_COLOR");
}
@ -3657,8 +3662,8 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This,
}
/* Base Declarations */
next_local = shader_generate_arb_declarations((IWineD3DBaseShaderImpl *)This,
reg_maps, buffer, gl_info, lconst_map, NULL, &priv_ctx);
next_local = shader_generate_arb_declarations(shader, reg_maps,
buffer, gl_info, lconst_map, NULL, &priv_ctx);
for (i = 0, map = reg_maps->bumpmat; map; map >>= 1, ++i)
{
@ -3696,7 +3701,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This,
compiled->int_consts[i] = WINED3D_CONST_NUM_UNUSED;
if (reg_maps->integer_constants & (1 << i) && priv_ctx.target_version >= NV2)
{
const DWORD *control_values = find_loop_control_values((IWineD3DBaseShaderImpl *) This, i);
const DWORD *control_values = find_loop_control_values(shader, i);
if(control_values)
{
@ -3778,7 +3783,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This,
}
/* Base Shader Body */
shader_generate_main((IWineD3DBaseShaderImpl *)This, buffer, reg_maps, function, &priv_ctx);
shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
if(args->super.srgb_correction) {
arbfp_add_sRGB_correction(buffer, fragcolor, srgbtmp[0], srgbtmp[1], srgbtmp[2], srgbtmp[3],
@ -3820,8 +3825,10 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This,
}
/* Load immediate constants */
if(lconst_map) {
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
if (lconst_map)
{
LIST_FOR_EACH_ENTRY(lconst, &shader->baseShader.constantsF, local_constant, entry)
{
const float *value = (const float *)lconst->value;
GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst_map[lconst->idx], value));
checkGLcall("glProgramLocalParameter4fvARB");
@ -4240,7 +4247,8 @@ static GLuint shader_arb_generate_vshader(IWineD3DBaseShaderImpl *shader,
}
/* GL locking is done by the caller */
static struct arb_ps_compiled_shader *find_arb_pshader(IWineD3DPixelShaderImpl *shader, const struct arb_ps_compile_args *args)
static struct arb_ps_compiled_shader *find_arb_pshader(IWineD3DBaseShaderImpl *shader,
const struct arb_ps_compile_args *args)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
@ -4421,7 +4429,7 @@ static struct arb_vs_compiled_shader *find_arb_vshader(IWineD3DBaseShaderImpl *s
}
static void find_arb_ps_compile_args(const struct wined3d_state *state,
IWineD3DPixelShaderImpl *shader, struct arb_ps_compile_args *args)
IWineD3DBaseShaderImpl *shader, struct arb_ps_compile_args *args)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
@ -4488,7 +4496,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
args->clip.boolclip_compare = 0;
if (use_ps(state))
{
IWineD3DPixelShaderImpl *ps = state->pixel_shader;
IWineD3DBaseShaderImpl *ps = state->pixel_shader;
struct arb_pshader_private *shader_priv = ps->baseShader.backend_data;
args->ps_signature = shader_priv->input_signature_idx;
@ -4563,7 +4571,7 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS,
/* Deal with pixel shaders first so the vertex shader arg function has the input signature ready */
if (usePS)
{
IWineD3DPixelShaderImpl *ps = state->pixel_shader;
IWineD3DBaseShaderImpl *ps = state->pixel_shader;
struct arb_ps_compile_args compile_args;
struct arb_ps_compiled_shader *compiled;
@ -5656,7 +5664,7 @@ static void set_bumpmat_arbfp(DWORD state_id, struct wined3d_stateblock *statebl
if (use_ps(state))
{
IWineD3DPixelShaderImpl *ps = state->pixel_shader;
IWineD3DBaseShaderImpl *ps = state->pixel_shader;
if (stage && (ps->baseShader.reg_maps.bumpmat & (1 << stage)))
{
/* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
@ -5695,7 +5703,7 @@ static void tex_bumpenvlum_arbfp(DWORD state_id,
if (use_ps(state))
{
IWineD3DPixelShaderImpl *ps = state->pixel_shader;
IWineD3DBaseShaderImpl *ps = state->pixel_shader;
if (stage && (ps->baseShader.reg_maps.luminanceparams & (1 << stage)))
{
/* The pixel shader has to know the luminance offset. Do a constants update if it

View File

@ -1579,7 +1579,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreatePixelShader(IWineD3DDevice *iface
IWineD3DBaseShader **shader)
{
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DPixelShaderImpl *object;
IWineD3DBaseShaderImpl *object;
HRESULT hr;
if (This->ps_selected_mode == SHADER_NONE)
@ -3691,7 +3691,7 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps, const struct
if (ps)
{
IWineD3DPixelShaderImpl *pshader = This->stateBlock->state.pixel_shader;
IWineD3DBaseShaderImpl *pshader = This->stateBlock->state.pixel_shader;
/* Note that we only care if a sampler is sampled or not, not the sampler's specific type.
* Otherwise we'd need to call shader_update_samplers() here for 1.x pixelshaders. */
@ -3748,7 +3748,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetPixelShader(IWineD3DDevice *iface, I
IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)iface;
IWineD3DBaseShader *prev = (IWineD3DBaseShader *)device->updateStateBlock->state.pixel_shader;
device->updateStateBlock->state.pixel_shader = (IWineD3DPixelShaderImpl *)shader;
device->updateStateBlock->state.pixel_shader = (IWineD3DBaseShaderImpl *)shader;
device->updateStateBlock->changed.pixelShader = TRUE;
/* Handle recording of state blocks */

View File

@ -110,7 +110,7 @@ struct glsl_shader_prog_link {
GLint ycorrection_location;
GLenum vertex_color_clamp;
IWineD3DBaseShaderImpl *vshader;
IWineD3DPixelShaderImpl *pshader;
IWineD3DBaseShaderImpl *pshader;
struct vs_compile_args vs_args;
struct ps_compile_args ps_args;
UINT constant_version;
@ -119,7 +119,7 @@ struct glsl_shader_prog_link {
typedef struct {
IWineD3DBaseShaderImpl *vshader;
IWineD3DPixelShaderImpl *pshader;
IWineD3DBaseShaderImpl *pshader;
struct ps_compile_args ps_args;
struct vs_compile_args vs_args;
} glsl_program_key_t;
@ -776,7 +776,7 @@ static void shader_glsl_load_constants(const struct wined3d_context *context,
if (usePixelShader)
{
IWineD3DBaseShaderImpl *pshader = (IWineD3DBaseShaderImpl *)stateBlock->state.pixel_shader;
IWineD3DBaseShaderImpl *pshader = stateBlock->state.pixel_shader;
/* Load DirectX 9 float constants/uniforms for pixel shader */
shader_glsl_load_constantsF(pshader, gl_info, stateBlock->state.ps_consts_f,
@ -817,7 +817,8 @@ static void shader_glsl_load_constants(const struct wined3d_context *context,
}
}
if(((IWineD3DPixelShaderImpl *) pshader)->vpos_uniform) {
if (pshader->u.ps.vpos_uniform)
{
float correction_params[4];
if (context->render_offscreen)
@ -1036,9 +1037,11 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
+ 1 < gl_info->limits.glsl_ps_float_constants)
{
shader_addline(buffer, "uniform vec4 ycorrection;\n");
((IWineD3DPixelShaderImpl *)shader)->vpos_uniform = 1;
shader->u.ps.vpos_uniform = 1;
extra_constants_needed++;
} else {
}
else
{
/* This happens because we do not have proper tracking of the constant registers that are
* actually used, only the max limit of the shader version
*/
@ -1338,7 +1341,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
/* pixel shaders >= 3.0 */
if (reg_maps->shader_version.major >= 3)
{
DWORD idx = ((IWineD3DPixelShaderImpl *)shader)->input_reg_map[reg->idx];
DWORD idx = shader->u.ps.input_reg_map[reg->idx];
unsigned int in_count = vec4_varyings(reg_maps->shader_version.major, gl_info);
if (reg->rel_addr)
@ -1351,7 +1354,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
* operation there */
if (idx)
{
if (((IWineD3DPixelShaderImpl *)shader)->declared_in_count > in_count)
if (shader->u.ps.declared_in_count > in_count)
{
sprintf(register_name,
"((%s + %u) > %d ? (%s + %u) > %d ? gl_SecondaryColor : gl_Color : IN[%s + %u])",
@ -1365,7 +1368,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
}
else
{
if (((IWineD3DPixelShaderImpl *)shader)->declared_in_count > in_count)
if (shader->u.ps.declared_in_count > in_count)
{
sprintf(register_name, "((%s) > %d ? (%s) > %d ? gl_SecondaryColor : gl_Color : IN[%s])",
rel_param.param_str, in_count - 1, rel_param.param_str, in_count,
@ -3641,13 +3644,13 @@ static void shader_glsl_dp2add(const struct wined3d_shader_instruction *ins)
}
}
static void shader_glsl_input_pack(IWineD3DBaseShader *iface, struct wined3d_shader_buffer *buffer,
const struct wined3d_shader_signature_element *input_signature, const struct wined3d_shader_reg_maps *reg_maps,
static void shader_glsl_input_pack(IWineD3DBaseShaderImpl *shader, struct wined3d_shader_buffer *buffer,
const struct wined3d_shader_signature_element *input_signature,
const struct wined3d_shader_reg_maps *reg_maps,
enum vertexprocessing_mode vertexprocessing)
{
unsigned int i;
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
WORD map = reg_maps->input_registers;
unsigned int i;
for (i = 0; map; map >>= 1, ++i)
{
@ -3666,27 +3669,27 @@ static void shader_glsl_input_pack(IWineD3DBaseShader *iface, struct wined3d_sha
{
if (semantic_idx < 8 && vertexprocessing == pretransformed)
shader_addline(buffer, "IN[%u]%s = gl_TexCoord[%u]%s;\n",
This->input_reg_map[i], reg_mask, semantic_idx, reg_mask);
shader->u.ps.input_reg_map[i], reg_mask, semantic_idx, reg_mask);
else
shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
This->input_reg_map[i], reg_mask, reg_mask);
shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
}
else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR))
{
if (!semantic_idx)
shader_addline(buffer, "IN[%u]%s = vec4(gl_Color)%s;\n",
This->input_reg_map[i], reg_mask, reg_mask);
shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
else if (semantic_idx == 1)
shader_addline(buffer, "IN[%u]%s = vec4(gl_SecondaryColor)%s;\n",
This->input_reg_map[i], reg_mask, reg_mask);
shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
else
shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
This->input_reg_map[i], reg_mask, reg_mask);
shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
}
else
{
shader_addline(buffer, "IN[%u]%s = vec4(0.0, 0.0, 0.0, 0.0)%s;\n",
This->input_reg_map[i], reg_mask, reg_mask);
shader->u.ps.input_reg_map[i], reg_mask, reg_mask);
}
}
}
@ -3710,7 +3713,7 @@ static void add_glsl_program_entry(struct shader_glsl_priv *priv, struct glsl_sh
}
static struct glsl_shader_prog_link *get_glsl_program_entry(struct shader_glsl_priv *priv,
IWineD3DBaseShaderImpl *vshader, IWineD3DPixelShaderImpl *pshader,
IWineD3DBaseShaderImpl *vshader, IWineD3DBaseShaderImpl *pshader,
struct vs_compile_args *vs_args, struct ps_compile_args *ps_args)
{
struct wine_rb_entry *entry;
@ -3838,7 +3841,7 @@ static void handle_ps3_input(struct wined3d_shader_buffer *buffer,
/* GL locking is done by the caller */
static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer *buffer,
IWineD3DBaseShaderImpl *vs, IWineD3DPixelShaderImpl *ps, const struct wined3d_gl_info *gl_info)
IWineD3DBaseShaderImpl *vs, IWineD3DBaseShaderImpl *ps, const struct wined3d_gl_info *gl_info)
{
GLhandleARB ret = 0;
DWORD ps_major = ps ? ps->baseShader.reg_maps.shader_version.major : 0;
@ -3933,7 +3936,7 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
}
/* Then, fix the pixel shader input */
handle_ps3_input(buffer, gl_info, ps->input_reg_map, ps->baseShader.input_signature,
handle_ps3_input(buffer, gl_info, ps->u.ps.input_reg_map, ps->baseShader.input_signature,
&ps->baseShader.reg_maps, output_signature, &vs->baseShader.reg_maps);
shader_addline(buffer, "}\n");
@ -3966,12 +3969,12 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const struc
/* GL locking is done by the caller */
static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context,
struct wined3d_shader_buffer *buffer, IWineD3DPixelShaderImpl *This,
struct wined3d_shader_buffer *buffer, IWineD3DBaseShaderImpl *shader,
const struct ps_compile_args *args, struct ps_np2fixup_info *np2fixup_info)
{
const struct wined3d_shader_reg_maps *reg_maps = &This->baseShader.reg_maps;
const struct wined3d_shader_reg_maps *reg_maps = &shader->baseShader.reg_maps;
const struct wined3d_gl_info *gl_info = context->gl_info;
CONST DWORD *function = This->baseShader.function;
const DWORD *function = shader->baseShader.function;
struct shader_glsl_ctx_priv priv_ctx;
/* Create the hw GLSL shader object and assign it as the shader->prgId */
@ -4000,17 +4003,14 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
}
/* Base Declarations */
shader_generate_glsl_declarations(context, buffer, (IWineD3DBaseShaderImpl *)This, reg_maps, &priv_ctx);
shader_generate_glsl_declarations(context, buffer, shader, reg_maps, &priv_ctx);
/* Pack 3.0 inputs */
if (reg_maps->shader_version.major >= 3 && args->vp_mode != vertexshader)
{
shader_glsl_input_pack((IWineD3DBaseShader *)This, buffer,
This->baseShader.input_signature, reg_maps, args->vp_mode);
}
shader_glsl_input_pack(shader, buffer, shader->baseShader.input_signature, reg_maps, args->vp_mode);
/* Base Shader Body */
shader_generate_main((IWineD3DBaseShaderImpl *)This, buffer, reg_maps, function, &priv_ctx);
shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
if (reg_maps->shader_version.major < 2)
@ -4139,7 +4139,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
}
static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
struct wined3d_shader_buffer *buffer, IWineD3DPixelShaderImpl *shader,
struct wined3d_shader_buffer *buffer, IWineD3DBaseShaderImpl *shader,
const struct ps_compile_args *args, const struct ps_np2fixup_info **np2fixup_info)
{
struct wined3d_state *state = &shader->baseShader.device->stateBlock->state;
@ -4293,7 +4293,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
{
const struct wined3d_state *state = &device->stateBlock->state;
IWineD3DBaseShaderImpl *vshader = use_vs ? state->vertex_shader : NULL;
IWineD3DPixelShaderImpl *pshader = use_ps ? state->pixel_shader : NULL;
IWineD3DBaseShaderImpl *pshader = use_ps ? state->pixel_shader : NULL;
const struct wined3d_gl_info *gl_info = context->gl_info;
struct shader_glsl_priv *priv = device->shader_priv;
struct glsl_shader_prog_link *entry = NULL;
@ -4443,7 +4443,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
if (pshader
&& pshader->baseShader.reg_maps.shader_version.major >= 3
&& pshader->declared_in_count > vec4_varyings(3, gl_info))
&& pshader->u.ps.declared_in_count > vec4_varyings(3, gl_info))
{
TRACE("Shader %d needs vertex color clamping disabled\n", programId);
entry->vertex_color_clamp = GL_FALSE;

View File

@ -373,12 +373,12 @@ static void shader_record_register_usage(IWineD3DBaseShaderImpl *shader, struct
unsigned int i;
for (i = 0; i < MAX_REG_INPUT; ++i)
{
((IWineD3DPixelShaderImpl *)shader)->input_reg_used[i] = TRUE;
shader->u.ps.input_reg_used[i] = TRUE;
}
}
else
{
((IWineD3DPixelShaderImpl *)shader)->input_reg_used[reg->idx] = TRUE;
shader->u.ps.input_reg_used[reg->idx] = TRUE;
}
}
else reg_maps->input_registers |= 1 << reg->idx;
@ -716,19 +716,16 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShaderImpl *shader, const s
if (shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
{
IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *)shader;
if (dst_param.reg.type == WINED3DSPR_COLOROUT && !dst_param.reg.idx)
{
/* Many 2.0 and 3.0 pixel shaders end with a MOV from a temp register to
* COLOROUT 0. If we know this in advance, the ARB shader backend can skip
* the mov and perform the sRGB write correction from the source register.
*
* However, if the mov is only partial, we can't do this, and if the write
* comes from an instruction other than MOV it is hard to do as well. If
* COLOROUT 0 is overwritten partially later, the marker is dropped again. */
ps->color0_mov = FALSE;
/* Many 2.0 and 3.0 pixel shaders end with a MOV from a temp register to
* COLOROUT 0. If we know this in advance, the ARB shader backend can skip
* the mov and perform the sRGB write correction from the source register.
*
* However, if the mov is only partial, we can't do this, and if the write
* comes from an instruction other than MOV it is hard to do as well. If
* COLOROUT 0 is overwritten partially later, the marker is dropped again. */
shader->u.ps.color0_mov = FALSE;
if (ins.handler_idx == WINED3DSIH_MOV
&& dst_param.write_mask == WINED3DSP_WRITEMASK_ALL)
{
@ -739,9 +736,10 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShaderImpl *shader, const s
/* Also drop the MOV marker if the source register is overwritten prior to the shader
* end
*/
else if (dst_param.reg.type == WINED3DSPR_TEMP && dst_param.reg.idx == ps->color0_reg)
else if (dst_param.reg.type == WINED3DSPR_TEMP
&& dst_param.reg.idx == shader->u.ps.color0_reg)
{
ps->color0_mov = FALSE;
shader->u.ps.color0_mov = FALSE;
}
}
@ -811,12 +809,11 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShaderImpl *shader, const s
if (color0_mov)
{
IWineD3DPixelShaderImpl *ps = (IWineD3DPixelShaderImpl *)shader;
if (src_param.reg.type == WINED3DSPR_TEMP
&& src_param.swizzle == WINED3DSP_NOSWIZZLE)
{
ps->color0_mov = TRUE;
ps->color0_reg = src_param.reg.idx;
shader->u.ps.color0_mov = TRUE;
shader->u.ps.color0_reg = src_param.reg.idx;
}
}
}
@ -2018,7 +2015,7 @@ static HRESULT STDMETHODCALLTYPE pixelshader_QueryInterface(IWineD3DBaseShader *
static ULONG STDMETHODCALLTYPE pixelshader_AddRef(IWineD3DBaseShader *iface)
{
IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)iface;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)iface;
ULONG refcount = InterlockedIncrement(&shader->baseShader.ref);
TRACE("%p increasing refcount to %u.\n", shader, refcount);
@ -2029,14 +2026,14 @@ static ULONG STDMETHODCALLTYPE pixelshader_AddRef(IWineD3DBaseShader *iface)
/* Do not call while under the GL lock. */
static ULONG STDMETHODCALLTYPE pixelshader_Release(IWineD3DBaseShader *iface)
{
IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)iface;
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)iface;
ULONG refcount = InterlockedDecrement(&shader->baseShader.ref);
TRACE("%p decreasing refcount to %u.\n", shader, refcount);
if (!refcount)
{
shader_cleanup((IWineD3DBaseShaderImpl *)shader);
shader_cleanup(shader);
shader->baseShader.parent_ops->wined3d_object_destroyed(shader->baseShader.parent);
HeapFree(GetProcessHeap(), 0, shader);
}
@ -2081,7 +2078,7 @@ static const IWineD3DBaseShaderVtbl IWineD3DPixelShader_Vtbl =
};
void find_ps_compile_args(const struct wined3d_state *state,
IWineD3DPixelShaderImpl *shader, struct ps_compile_args *args)
IWineD3DBaseShaderImpl *shader, struct ps_compile_args *args)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
const struct wined3d_texture *texture;
@ -2176,7 +2173,7 @@ void find_ps_compile_args(const struct wined3d_state *state,
}
}
static void pixelshader_set_limits(IWineD3DPixelShaderImpl *shader)
static void pixelshader_set_limits(IWineD3DBaseShaderImpl *shader)
{
DWORD shader_version = WINED3D_SHADER_VERSION(shader->baseShader.reg_maps.shader_version.major,
shader->baseShader.reg_maps.shader_version.minor);
@ -2264,7 +2261,7 @@ static void pixelshader_set_limits(IWineD3DPixelShaderImpl *shader)
}
}
HRESULT pixelshader_init(IWineD3DPixelShaderImpl *shader, IWineD3DDeviceImpl *device,
HRESULT pixelshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *device,
const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
void *parent, const struct wined3d_parent_ops *parent_ops)
{
@ -2277,12 +2274,11 @@ HRESULT pixelshader_init(IWineD3DPixelShaderImpl *shader, IWineD3DDeviceImpl *de
shader->lpVtbl = &IWineD3DPixelShader_Vtbl;
shader_init(&shader->baseShader, device, parent, parent_ops);
hr = shader_set_function((IWineD3DBaseShaderImpl *)shader, byte_code,
output_signature, device->d3d_pshader_constantF);
hr = shader_set_function(shader, byte_code, output_signature, device->d3d_pshader_constantF);
if (FAILED(hr))
{
WARN("Failed to set function, hr %#x.\n", hr);
shader_cleanup((IWineD3DBaseShaderImpl *)shader);
shader_cleanup(shader);
return hr;
}
@ -2290,7 +2286,7 @@ HRESULT pixelshader_init(IWineD3DPixelShaderImpl *shader, IWineD3DDeviceImpl *de
for (i = 0; i < MAX_REG_INPUT; ++i)
{
if (shader->input_reg_used[i])
if (shader->u.ps.input_reg_used[i])
{
++num_regs_used;
highest_reg_used = i;
@ -2312,18 +2308,19 @@ HRESULT pixelshader_init(IWineD3DPixelShaderImpl *shader, IWineD3DDeviceImpl *de
for (i = 0; i < MAX_REG_INPUT; ++i)
{
shader->input_reg_map[i] = i;
shader->u.ps.input_reg_map[i] = i;
}
shader->declared_in_count = highest_reg_used + 1;
shader->u.ps.declared_in_count = highest_reg_used + 1;
}
else
{
shader->declared_in_count = 0;
shader->u.ps.declared_in_count = 0;
for (i = 0; i < MAX_REG_INPUT; ++i)
{
if (shader->input_reg_used[i]) shader->input_reg_map[i] = shader->declared_in_count++;
else shader->input_reg_map[i] = ~0U;
if (shader->u.ps.input_reg_used[i])
shader->u.ps.input_reg_map[i] = shader->u.ps.declared_in_count++;
else shader->u.ps.input_reg_map[i] = ~0U;
}
}

View File

@ -3569,7 +3569,7 @@ static void shaderconstant(DWORD state_id, struct wined3d_stateblock *stateblock
static void tex_bumpenvlscale(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
{
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
IWineD3DPixelShaderImpl *ps = stateblock->state.pixel_shader;
IWineD3DBaseShaderImpl *ps = stateblock->state.pixel_shader;
if (ps && stage && (ps->baseShader.reg_maps.luminanceparams & (1 << stage)))
{
@ -3740,7 +3740,7 @@ void apply_pixelshader(DWORD state_id, struct wined3d_stateblock *stateblock, st
static void shader_bumpenvmat(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
{
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
IWineD3DPixelShaderImpl *ps = stateblock->state.pixel_shader;
IWineD3DBaseShaderImpl *ps = stateblock->state.pixel_shader;
if (ps && stage && (ps->baseShader.reg_maps.bumpmat & (1 << stage)))
{

View File

@ -2341,7 +2341,7 @@ struct wined3d_state
INT vs_consts_i[MAX_CONST_I * 4];
float *vs_consts_f;
struct IWineD3DPixelShaderImpl *pixel_shader;
struct IWineD3DBaseShaderImpl *pixel_shader;
BOOL ps_consts_b[MAX_CONST_B];
INT ps_consts_i[MAX_CONST_I * 4];
float *ps_consts_f;
@ -2725,6 +2725,19 @@ struct wined3d_vertex_shader
struct wined3d_shader_attribute attributes[MAX_ATTRIBS];
};
struct wined3d_pixel_shader
{
/* Pixel shader input semantics */
DWORD input_reg_map[MAX_REG_INPUT];
BOOL input_reg_used[MAX_REG_INPUT];
unsigned int declared_in_count;
/* Some information about the shader behavior */
char vpos_uniform;
BOOL color0_mov;
DWORD color0_reg;
};
typedef struct IWineD3DBaseShaderImpl {
/* IUnknown */
const IWineD3DBaseShaderVtbl *lpVtbl;
@ -2735,6 +2748,7 @@ typedef struct IWineD3DBaseShaderImpl {
union
{
struct wined3d_vertex_shader vs;
struct wined3d_pixel_shader ps;
} u;
} IWineD3DBaseShaderImpl;
@ -2742,6 +2756,14 @@ HRESULT geometryshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *
const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
HRESULT pixelshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *device,
const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
void pixelshader_update_samplers(struct wined3d_shader_reg_maps *reg_maps,
struct wined3d_texture * const *textures) DECLSPEC_HIDDEN;
void find_ps_compile_args(const struct wined3d_state *state,
IWineD3DBaseShaderImpl *shader, struct ps_compile_args *args) DECLSPEC_HIDDEN;
void find_vs_compile_args(const struct wined3d_state *state,
IWineD3DBaseShaderImpl *shader, struct vs_compile_args *args) DECLSPEC_HIDDEN;
HRESULT vertexshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *device,
@ -2832,10 +2854,6 @@ static inline BOOL shader_constant_is_local(IWineD3DBaseShaderImpl* This, DWORD
}
/*****************************************************************************
* IDirect3DPixelShader implementation structure
*/
/* Using additional shader constants (uniforms in GLSL / program environment
* or local parameters in ARB) is costly:
* ARB only knows float4 parameters and GLSL compiler are not really smart
@ -2853,32 +2871,6 @@ struct ps_np2fixup_info {
WORD num_consts;
};
typedef struct IWineD3DPixelShaderImpl
{
const IWineD3DBaseShaderVtbl *lpVtbl;
IWineD3DBaseShaderClass baseShader;
/* Pixel shader input semantics */
DWORD input_reg_map[MAX_REG_INPUT];
BOOL input_reg_used[MAX_REG_INPUT];
unsigned int declared_in_count;
/* Some information about the shader behavior */
char vpos_uniform;
BOOL color0_mov;
DWORD color0_reg;
} IWineD3DPixelShaderImpl;
HRESULT pixelshader_init(IWineD3DPixelShaderImpl *shader, IWineD3DDeviceImpl *device,
const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
void pixelshader_update_samplers(struct wined3d_shader_reg_maps *reg_maps,
struct wined3d_texture * const *textures) DECLSPEC_HIDDEN;
void find_ps_compile_args(const struct wined3d_state *state,
IWineD3DPixelShaderImpl *shader, struct ps_compile_args *args) DECLSPEC_HIDDEN;
/* sRGB correction constants */
static const float srgb_cmp = 0.0031308f;
static const float srgb_mul_low = 12.92f;