wined3d: Get rid of IWineD3DBaseShaderClass.

This commit is contained in:
Henri Verbeet 2011-03-30 20:49:24 +02:00 committed by Alexandre Julliard
parent 45fd0d4e7a
commit 5555d904be
6 changed files with 387 additions and 381 deletions

View File

@ -362,7 +362,7 @@ static unsigned int reserved_vs_const(const struct arb_vshader_private *shader_d
* or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
*/
/* GL locking is done by the caller */
static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info,
GLuint target_type, unsigned int max_constants, const float *constants, char *dirty_consts)
{
local_constant* lconst;
@ -382,7 +382,7 @@ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl *This, con
i = 0;
/* In 1.X pixel shaders constants are implicitly clamped in the range [-1;1] */
if (target_type == GL_FRAGMENT_PROGRAM_ARB && This->baseShader.reg_maps.shader_version.major == 1)
if (target_type == GL_FRAGMENT_PROGRAM_ARB && shader->reg_maps.shader_version.major == 1)
{
float lcl_const[4];
/* ps 1.x supports only 8 constants, clamp only those. When switching between 1.x and higher
@ -451,9 +451,12 @@ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl *This, con
checkGLcall("glProgramEnvParameter4fvARB()");
/* Load immediate constants */
if(This->baseShader.load_local_constsF) {
if (TRACE_ON(d3d_shader)) {
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
if (shader->load_local_constsF)
{
if (TRACE_ON(d3d_shader))
{
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, local_constant, entry)
{
GLfloat* values = (GLfloat*)lconst->value;
TRACE_(d3d_constants)("Loading local constants %i: %f, %f, %f, %f\n", lconst->idx,
values[0], values[1], values[2], values[3]);
@ -461,7 +464,8 @@ static unsigned int shader_arb_load_constantsF(IWineD3DBaseShaderImpl *This, con
}
/* Immediate constants are clamped for 1.X shaders at loading times */
ret = 0;
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, local_constant, entry)
{
dirty_consts[lconst->idx] = 1; /* Dirtify so the non-immediate constant overwrites it next time */
ret = max(ret, lconst->idx + 1);
GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, lconst->idx, (GLfloat*)lconst->value));
@ -678,21 +682,24 @@ static void shader_arb_update_float_pixel_constants(IWineD3DDeviceImpl *device,
device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, start + count);
}
static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *This)
static DWORD *local_const_mapping(IWineD3DBaseShaderImpl *shader)
{
DWORD *ret;
DWORD idx = 0;
const local_constant *lconst;
if(This->baseShader.load_local_constsF || list_empty(&This->baseShader.constantsF)) return NULL;
if (shader->load_local_constsF || list_empty(&shader->constantsF))
return NULL;
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * This->baseShader.limits.constant_float);
if(!ret) {
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * shader->limits.constant_float);
if (!ret)
{
ERR("Out of memory\n");
return NULL;
}
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, local_constant, entry)
{
ret[lconst->idx] = idx++;
}
return ret;
@ -729,7 +736,7 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShaderImpl *shader,
}
else
{
const struct arb_vshader_private *shader_data = shader->baseShader.backend_data;
const struct arb_vshader_private *shader_data = shader->backend_data;
max_constantsF = gl_info->limits.arb_vs_native_constants;
/* 96 is the minimum MAX_PROGRAM_ENV_PARAMETERS_ARB value.
* Also prevents max_constantsF from becoming less than 0 and
@ -744,7 +751,7 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShaderImpl *shader,
max_constantsF -= reserved_vs_const(shader_data, reg_maps, gl_info);
max_constantsF -= count_bits(reg_maps->integer_constants);
for (i = 0; i < shader->baseShader.limits.constant_float; ++i)
for (i = 0; i < shader->limits.constant_float; ++i)
{
DWORD idx = i >> 5;
DWORD shift = i & 0x1f;
@ -800,7 +807,7 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShaderImpl *shader,
*/
if (lconst_map)
{
LIST_FOR_EACH_ENTRY(lconst, &shader->baseShader.constantsF, local_constant, entry)
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, local_constant, entry)
{
shader_addline(buffer, "PARAM C%u = program.local[%u];\n", lconst->idx,
lconst_map[lconst->idx]);
@ -821,7 +828,7 @@ static DWORD shader_generate_arb_declarations(IWineD3DBaseShaderImpl *shader,
}
/* Avoid declaring more constants than needed */
max_constantsF = min(max_constantsF, shader->baseShader.limits.constant_float);
max_constantsF = min(max_constantsF, shader->limits.constant_float);
/* we use the array-based constants array if the local constants are marked for loading,
* because then we use indirect addressing, or when the local constant list is empty,
@ -1039,7 +1046,7 @@ static void shader_arb_get_register_name(const struct wined3d_shader_instruction
case WINED3DSPR_CONST:
if (!pshader && reg->rel_addr)
{
const struct arb_vshader_private *shader_data = shader->baseShader.backend_data;
const struct arb_vshader_private *shader_data = shader->backend_data;
UINT rel_offset = shader_data->rel_offset;
BOOL aL = FALSE;
char rel_reg[50];
@ -1334,7 +1341,7 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD
const char *tex_type;
BOOL np2_fixup = FALSE;
struct IWineD3DBaseShaderImpl *shader = ins->ctx->shader;
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
const char *mod;
BOOL pshader = shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type);
@ -1762,7 +1769,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
if (ins->handler_idx == WINED3DSIH_MOVA)
{
const struct arb_vshader_private *shader_data = shader->baseShader.backend_data;
const struct arb_vshader_private *shader_data = shader->backend_data;
char write_mask[6];
const char *offset = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_VS_REL_OFFSET);
@ -1801,7 +1808,7 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
&& !shader_is_pshader_version(reg_maps->shader_version.type)
&& ins->dst[0].reg.type == WINED3DSPR_ADDR)
{
const struct arb_vshader_private *shader_data = shader->baseShader.backend_data;
const struct arb_vshader_private *shader_data = shader->backend_data;
src0_param[0] = '\0';
if (shader_data->rel_offset)
@ -3206,7 +3213,7 @@ static void shader_hw_ret(const struct wined3d_shader_instruction *ins)
if(vshader)
{
if (priv->in_main_func) vshader_add_footer(priv, shader->baseShader.backend_data,
if (priv->in_main_func) vshader_add_footer(priv, shader->backend_data,
priv->cur_vs_args, ins->ctx->reg_maps, ins->ctx->gl_info, buffer);
}
@ -3406,11 +3413,11 @@ static void arbfp_add_sRGB_correction(struct wined3d_shader_buffer *buffer, cons
/* [0.0;1.0] clamping. Not needed, this is done implicitly */
}
static const DWORD *find_loop_control_values(IWineD3DBaseShaderImpl *This, DWORD idx)
static const DWORD *find_loop_control_values(IWineD3DBaseShaderImpl *shader, DWORD idx)
{
const local_constant *constant;
LIST_FOR_EACH_ENTRY(constant, &This->baseShader.constantsI, local_constant, entry)
LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, local_constant, entry)
{
if (constant->idx == idx)
{
@ -3429,7 +3436,7 @@ static void init_ps_input(const IWineD3DBaseShaderImpl *shader,
"fragment.texcoord[4]", "fragment.texcoord[5]", "fragment.texcoord[6]", "fragment.texcoord[7]"
};
unsigned int i;
const struct wined3d_shader_signature_element *sig = shader->baseShader.input_signature;
const struct wined3d_shader_signature_element *sig = shader->input_signature;
const char *semantic_name;
DWORD semantic_idx;
@ -3499,8 +3506,8 @@ 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 = &shader->baseShader.reg_maps;
const DWORD *function = shader->baseShader.function;
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
const DWORD *function = shader->function;
const local_constant *lconst;
GLuint retval;
char fragcolor[16];
@ -3508,7 +3515,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DBaseShaderImpl *shader,
struct shader_arb_ctx_priv priv_ctx;
BOOL dcl_td = FALSE;
BOOL want_nv_prog = FALSE;
struct arb_pshader_private *shader_priv = shader->baseShader.backend_data;
struct arb_pshader_private *shader_priv = shader->backend_data;
GLint errPos;
DWORD map;
@ -3827,7 +3834,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DBaseShaderImpl *shader,
/* Load immediate constants */
if (lconst_map)
{
LIST_FOR_EACH_ENTRY(lconst, &shader->baseShader.constantsF, local_constant, entry)
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, local_constant, entry)
{
const float *value = (const float *)lconst->value;
GL_EXTCALL(glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, lconst_map[lconst->idx], value));
@ -3914,8 +3921,7 @@ static void init_output_registers(IWineD3DBaseShaderImpl *shader, DWORD sig_num,
"result.texcoord[0]", "result.texcoord[1]", "result.texcoord[2]", "result.texcoord[3]",
"result.texcoord[4]", "result.texcoord[5]", "result.texcoord[6]", "result.texcoord[7]"
};
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DBaseShaderClass *baseshader = &shader->baseShader;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_shader_signature_element *sig;
const char *semantic_name;
DWORD semantic_idx, reg_idx;
@ -3943,42 +3949,42 @@ static void init_output_registers(IWineD3DBaseShaderImpl *shader, DWORD sig_num,
priv_ctx->fog_output = "result.fogcoord";
/* Map declared regs to builtins. Use "TA" to /dev/null unread output */
for (i = 0; i < (sizeof(baseshader->output_signature) / sizeof(*baseshader->output_signature)); ++i)
for (i = 0; i < (sizeof(shader->output_signature) / sizeof(*shader->output_signature)); ++i)
{
semantic_name = baseshader->output_signature[i].semantic_name;
semantic_name = shader->output_signature[i].semantic_name;
if (!semantic_name) continue;
if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION))
{
TRACE("o%u is TMP_OUT\n", i);
if (!baseshader->output_signature[i].semantic_idx) priv_ctx->vs_output[i] = "TMP_OUT";
if (!shader->output_signature[i].semantic_idx) priv_ctx->vs_output[i] = "TMP_OUT";
else priv_ctx->vs_output[i] = "TA";
}
else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE))
{
TRACE("o%u is result.pointsize\n", i);
if (!baseshader->output_signature[i].semantic_idx) priv_ctx->vs_output[i] = "result.pointsize";
if (!shader->output_signature[i].semantic_idx) priv_ctx->vs_output[i] = "result.pointsize";
else priv_ctx->vs_output[i] = "TA";
}
else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_COLOR))
{
TRACE("o%u is result.color.?, idx %u\n", i, baseshader->output_signature[i].semantic_idx);
if (!baseshader->output_signature[i].semantic_idx)
TRACE("o%u is result.color.?, idx %u\n", i, shader->output_signature[i].semantic_idx);
if (!shader->output_signature[i].semantic_idx)
priv_ctx->vs_output[i] = "result.color.primary";
else if (baseshader->output_signature[i].semantic_idx == 1)
else if (shader->output_signature[i].semantic_idx == 1)
priv_ctx->vs_output[i] = "result.color.secondary";
else priv_ctx->vs_output[i] = "TA";
}
else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_TEXCOORD))
{
TRACE("o%u is %s\n", i, texcoords[baseshader->output_signature[i].semantic_idx]);
if (baseshader->output_signature[i].semantic_idx >= 8) priv_ctx->vs_output[i] = "TA";
else priv_ctx->vs_output[i] = texcoords[baseshader->output_signature[i].semantic_idx];
TRACE("o%u is %s\n", i, texcoords[shader->output_signature[i].semantic_idx]);
if (shader->output_signature[i].semantic_idx >= 8) priv_ctx->vs_output[i] = "TA";
else priv_ctx->vs_output[i] = texcoords[shader->output_signature[i].semantic_idx];
}
else if(shader_match_semantic(semantic_name, WINED3DDECLUSAGE_FOG))
{
TRACE("o%u is result.fogcoord\n", i);
if (baseshader->output_signature[i].semantic_idx > 0) priv_ctx->vs_output[i] = "TA";
if (shader->output_signature[i].semantic_idx > 0) priv_ctx->vs_output[i] = "TA";
else priv_ctx->vs_output[i] = "result.fogcoord";
}
else
@ -3992,7 +3998,7 @@ static void init_output_registers(IWineD3DBaseShaderImpl *shader, DWORD sig_num,
/* Instead of searching for the signature in the signature list, read the one from the current pixel shader.
* Its maybe not the shader where the signature came from, but it is the same signature and faster to find
*/
sig = device->stateBlock->state.pixel_shader->baseShader.input_signature;
sig = device->stateBlock->state.pixel_shader->input_signature;
TRACE("Pixel shader uses declared varyings\n");
/* Map builtin to declared. /dev/null the results by default to the TA temp reg */
@ -4042,21 +4048,21 @@ static void init_output_registers(IWineD3DBaseShaderImpl *shader, DWORD sig_num,
}
/* Map declared to declared */
for (i = 0; i < (sizeof(baseshader->output_signature) / sizeof(*baseshader->output_signature)); ++i)
for (i = 0; i < (sizeof(shader->output_signature) / sizeof(*shader->output_signature)); ++i)
{
/* Write unread output to TA to throw them away */
priv_ctx->vs_output[i] = "TA";
semantic_name = baseshader->output_signature[i].semantic_name;
semantic_name = shader->output_signature[i].semantic_name;
if (!semantic_name) continue;
if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_POSITION)
&& !baseshader->output_signature[i].semantic_idx)
&& !shader->output_signature[i].semantic_idx)
{
priv_ctx->vs_output[i] = "TMP_OUT";
continue;
}
else if (shader_match_semantic(semantic_name, WINED3DDECLUSAGE_PSIZE)
&& !baseshader->output_signature[i].semantic_idx)
&& !shader->output_signature[i].semantic_idx)
{
priv_ctx->vs_output[i] = "result.pointsize";
continue;
@ -4067,7 +4073,7 @@ static void init_output_registers(IWineD3DBaseShaderImpl *shader, DWORD sig_num,
if (!sig[j].semantic_name) continue;
if (!strcmp(sig[j].semantic_name, semantic_name)
&& sig[j].semantic_idx == baseshader->output_signature[i].semantic_idx)
&& sig[j].semantic_idx == shader->output_signature[i].semantic_idx)
{
priv_ctx->vs_output[i] = decl_idx_to_string[sig[j].register_idx];
@ -4086,9 +4092,9 @@ static GLuint shader_arb_generate_vshader(IWineD3DBaseShaderImpl *shader,
const struct wined3d_gl_info *gl_info, struct wined3d_shader_buffer *buffer,
const struct arb_vs_compile_args *args, struct arb_vs_compiled_shader *compiled)
{
const struct arb_vshader_private *shader_data = shader->baseShader.backend_data;
const struct wined3d_shader_reg_maps *reg_maps = &shader->baseShader.reg_maps;
const DWORD *function = shader->baseShader.function;
const struct arb_vshader_private *shader_data = shader->backend_data;
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
const DWORD *function = shader->function;
const local_constant *lconst;
GLuint ret;
DWORD next_local, *lconst_map = local_const_mapping(shader);
@ -4177,7 +4183,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DBaseShaderImpl *shader,
*/
if (!gl_info->supported[NV_VERTEX_PROGRAM])
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
const char *color_init = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_0001);
shader_addline(buffer, "MOV result.color.secondary, %s;\n", color_init);
@ -4234,7 +4240,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DBaseShaderImpl *shader,
/* Load immediate constants */
if (lconst_map)
{
LIST_FOR_EACH_ENTRY(lconst, &shader->baseShader.constantsF, local_constant, entry)
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, local_constant, entry)
{
const float *value = (const float *)lconst->value;
GL_EXTCALL(glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, lconst_map[lconst->idx], value));
@ -4250,7 +4256,7 @@ static GLuint shader_arb_generate_vshader(IWineD3DBaseShaderImpl *shader,
static struct arb_ps_compiled_shader *find_arb_pshader(IWineD3DBaseShaderImpl *shader,
const struct arb_ps_compile_args *args)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
UINT i;
DWORD new_size;
@ -4259,27 +4265,29 @@ static struct arb_ps_compiled_shader *find_arb_pshader(IWineD3DBaseShaderImpl *s
struct arb_pshader_private *shader_data;
GLuint ret;
if (!shader->baseShader.backend_data)
if (!shader->backend_data)
{
struct shader_arb_priv *priv = device->shader_priv;
shader->baseShader.backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
shader_data = shader->baseShader.backend_data;
shader_data->clamp_consts = shader->baseShader.reg_maps.shader_version.major == 1;
shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
shader_data = shader->backend_data;
shader_data->clamp_consts = shader->reg_maps.shader_version.major == 1;
if(shader->baseShader.reg_maps.shader_version.major < 3) shader_data->input_signature_idx = ~0;
else shader_data->input_signature_idx = find_input_signature(priv, shader->baseShader.input_signature);
if (shader->reg_maps.shader_version.major < 3)
shader_data->input_signature_idx = ~0;
else
shader_data->input_signature_idx = find_input_signature(priv, shader->input_signature);
shader_data->has_signature_idx = TRUE;
TRACE("Shader got assigned input signature index %u\n", shader_data->input_signature_idx);
if (!device->vs_clipping)
shader_data->clipplane_emulation = shader_find_free_input_register(&shader->baseShader.reg_maps,
shader_data->clipplane_emulation = shader_find_free_input_register(&shader->reg_maps,
gl_info->limits.texture_stages - 1);
else
shader_data->clipplane_emulation = ~0U;
}
shader_data = shader->baseShader.backend_data;
shader_data = shader->backend_data;
/* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
* so a linear search is more performant than a hashmap or a binary search
@ -4313,7 +4321,7 @@ static struct arb_ps_compiled_shader *find_arb_pshader(IWineD3DBaseShaderImpl *s
shader_data->gl_shaders[shader_data->num_gl_shaders].args = *args;
pixelshader_update_samplers(&shader->baseShader.reg_maps, device->stateBlock->state.textures);
pixelshader_update_samplers(&shader->reg_maps, device->stateBlock->state.textures);
if (!shader_buffer_init(&buffer))
{
@ -4345,7 +4353,7 @@ static inline BOOL vs_args_equal(const struct arb_vs_compile_args *stored, const
static struct arb_vs_compiled_shader *find_arb_vshader(IWineD3DBaseShaderImpl *shader,
const struct arb_vs_compile_args *args)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
DWORD use_map = device->strided_streams.use_map;
UINT i;
@ -4355,12 +4363,12 @@ static struct arb_vs_compiled_shader *find_arb_vshader(IWineD3DBaseShaderImpl *s
struct arb_vshader_private *shader_data;
GLuint ret;
if (!shader->baseShader.backend_data)
if (!shader->backend_data)
{
const struct wined3d_shader_reg_maps *reg_maps = &shader->baseShader.reg_maps;
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
shader->baseShader.backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
shader_data = shader->baseShader.backend_data;
shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
shader_data = shader->backend_data;
if ((gl_info->quirks & WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT)
&& reg_maps->min_rel_offset <= reg_maps->max_rel_offset)
@ -4377,7 +4385,7 @@ static struct arb_vs_compiled_shader *find_arb_vshader(IWineD3DBaseShaderImpl *s
shader_data->rel_offset = reg_maps->min_rel_offset;
}
}
shader_data = shader->baseShader.backend_data;
shader_data = shader->backend_data;
/* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
* so a linear search is more performant than a hashmap or a binary search
@ -4431,7 +4439,7 @@ static struct arb_vs_compiled_shader *find_arb_vshader(IWineD3DBaseShaderImpl *s
static void find_arb_ps_compile_args(const struct wined3d_state *state,
IWineD3DBaseShaderImpl *shader, struct arb_ps_compile_args *args)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
int i;
WORD int_skip;
@ -4439,7 +4447,7 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state,
find_ps_compile_args(state, shader, &args->super);
/* This forces all local boolean constants to 1 to make them stateblock independent */
args->bools = shader->baseShader.reg_maps.local_bool_consts;
args->bools = shader->reg_maps.local_bool_consts;
for(i = 0; i < MAX_CONST_B; i++)
{
@ -4459,7 +4467,7 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state,
args->clip = 0;
/* Skip if unused or local, or supported natively */
int_skip = ~shader->baseShader.reg_maps.integer_constants | shader->baseShader.reg_maps.local_int_consts;
int_skip = ~shader->reg_maps.integer_constants | shader->reg_maps.local_int_consts;
if (int_skip == 0xffff || gl_info->supported[NV_FRAGMENT_PROGRAM_OPTION])
{
memset(&args->loop_ctrl, 0, sizeof(args->loop_ctrl));
@ -4486,7 +4494,7 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state,
static void find_arb_vs_compile_args(const struct wined3d_state *state,
IWineD3DBaseShaderImpl *shader, struct arb_vs_compile_args *args)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
int i;
WORD int_skip;
@ -4497,7 +4505,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
if (use_ps(state))
{
IWineD3DBaseShaderImpl *ps = state->pixel_shader;
struct arb_pshader_private *shader_priv = ps->baseShader.backend_data;
struct arb_pshader_private *shader_priv = ps->backend_data;
args->ps_signature = shader_priv->input_signature_idx;
args->clip.boolclip.clip_texcoord = shader_priv->clipplane_emulation + 1;
@ -4520,7 +4528,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
}
/* This forces all local boolean constants to 1 to make them stateblock independent */
args->clip.boolclip.bools = shader->baseShader.reg_maps.local_bool_consts;
args->clip.boolclip.bools = shader->reg_maps.local_bool_consts;
/* TODO: Figure out if it would be better to store bool constants as bitmasks in the stateblock */
for(i = 0; i < MAX_CONST_B; i++)
{
@ -4534,7 +4542,7 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
args->vertex.samplers[3] = 0;
/* Skip if unused or local */
int_skip = ~shader->baseShader.reg_maps.integer_constants | shader->baseShader.reg_maps.local_int_consts;
int_skip = ~shader->reg_maps.integer_constants | shader->reg_maps.local_int_consts;
/* This is about flow control, not clipping. */
if (int_skip == 0xffff || gl_info->supported[NV_VERTEX_PROGRAM2_OPTION])
{
@ -4595,9 +4603,9 @@ static void shader_arb_select(const struct wined3d_context *context, BOOL usePS,
/* Pixel Shader 1.x constants are clamped to [-1;1], Pixel Shader 2.0 constants are not. If switching between
* a 1.x and newer shader, reload the first 8 constants
*/
if(priv->last_ps_const_clamped != ((struct arb_pshader_private *)ps->baseShader.backend_data)->clamp_consts)
if (priv->last_ps_const_clamped != ((struct arb_pshader_private *)ps->backend_data)->clamp_consts)
{
priv->last_ps_const_clamped = ((struct arb_pshader_private *)ps->baseShader.backend_data)->clamp_consts;
priv->last_ps_const_clamped = ((struct arb_pshader_private *)ps->backend_data)->clamp_consts;
This->highest_dirty_ps_const = max(This->highest_dirty_ps_const, 8);
for(i = 0; i < 8; i++)
{
@ -4721,12 +4729,12 @@ static void shader_arb_deselect_depth_blt(void *shader_priv, const struct wined3
static void shader_arb_destroy(IWineD3DBaseShaderImpl *shader)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
if (shader_is_pshader_version(shader->baseShader.reg_maps.shader_version.type))
if (shader_is_pshader_version(shader->reg_maps.shader_version.type))
{
struct arb_pshader_private *shader_data = shader->baseShader.backend_data;
struct arb_pshader_private *shader_data = shader->backend_data;
UINT i;
if(!shader_data) return; /* This can happen if a shader was never compiled */
@ -4748,11 +4756,11 @@ static void shader_arb_destroy(IWineD3DBaseShaderImpl *shader)
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
HeapFree(GetProcessHeap(), 0, shader_data);
shader->baseShader.backend_data = NULL;
shader->backend_data = NULL;
}
else
{
struct arb_vshader_private *shader_data = shader->baseShader.backend_data;
struct arb_vshader_private *shader_data = shader->backend_data;
UINT i;
if(!shader_data) return; /* This can happen if a shader was never compiled */
@ -4774,7 +4782,7 @@ static void shader_arb_destroy(IWineD3DBaseShaderImpl *shader)
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
HeapFree(GetProcessHeap(), 0, shader_data);
shader->baseShader.backend_data = NULL;
shader->backend_data = NULL;
}
}
@ -5077,7 +5085,8 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
/* WINED3DSIH_UTOF */ NULL,
};
static inline BOOL get_bool_const(const struct wined3d_shader_instruction *ins, IWineD3DBaseShaderImpl *This, DWORD idx)
static BOOL get_bool_const(const struct wined3d_shader_instruction *ins,
IWineD3DBaseShaderImpl *shader, DWORD idx)
{
const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
BOOL vshader = shader_is_vshader_version(reg_maps->shader_version.type);
@ -5089,7 +5098,7 @@ static inline BOOL get_bool_const(const struct wined3d_shader_instruction *ins,
if (reg_maps->local_bool_consts & flag)
{
/* What good is a if(bool) with a hardcoded local constant? I don't know, but handle it */
LIST_FOR_EACH_ENTRY(constant, &This->baseShader.constantsB, local_constant, entry)
LIST_FOR_EACH_ENTRY(constant, &shader->constantsB, local_constant, entry)
{
if (constant->idx == idx)
{
@ -5108,7 +5117,7 @@ static inline BOOL get_bool_const(const struct wined3d_shader_instruction *ins,
}
static void get_loop_control_const(const struct wined3d_shader_instruction *ins,
IWineD3DBaseShaderImpl *This, UINT idx, struct wined3d_shader_loop_control *loop_control)
IWineD3DBaseShaderImpl *shader, UINT idx, struct wined3d_shader_loop_control *loop_control)
{
const struct wined3d_shader_reg_maps *reg_maps = ins->ctx->reg_maps;
struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
@ -5119,7 +5128,7 @@ static void get_loop_control_const(const struct wined3d_shader_instruction *ins,
{
const local_constant *constant;
LIST_FOR_EACH_ENTRY(constant, &This->baseShader.constantsI, local_constant, entry)
LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, local_constant, entry)
{
if (constant->idx == idx)
{
@ -5665,7 +5674,7 @@ static void set_bumpmat_arbfp(DWORD state_id, struct wined3d_stateblock *statebl
if (use_ps(state))
{
IWineD3DBaseShaderImpl *ps = state->pixel_shader;
if (stage && (ps->baseShader.reg_maps.bumpmat & (1 << stage)))
if (stage && (ps->reg_maps.bumpmat & (1 << stage)))
{
/* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
* anyway
@ -5704,7 +5713,7 @@ static void tex_bumpenvlum_arbfp(DWORD state_id,
if (use_ps(state))
{
IWineD3DBaseShaderImpl *ps = state->pixel_shader;
if (stage && (ps->baseShader.reg_maps.luminanceparams & (1 << stage)))
if (stage && (ps->reg_maps.luminanceparams & (1 << stage)))
{
/* The pixel shader has to know the luminance offset. Do a constants update if it
* isn't scheduled anyway

View File

@ -472,7 +472,7 @@ void device_preload_textures(IWineD3DDeviceImpl *device)
{
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
{
if (state->vertex_shader->baseShader.reg_maps.sampler_type[i])
if (state->vertex_shader->reg_maps.sampler_type[i])
device_preload_texture(state, MAX_FRAGMENT_SAMPLERS + i);
}
}
@ -481,7 +481,7 @@ void device_preload_textures(IWineD3DDeviceImpl *device)
{
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
if (state->pixel_shader->baseShader.reg_maps.sampler_type[i])
if (state->pixel_shader->reg_maps.sampler_type[i])
device_preload_texture(state, i);
}
}
@ -3641,7 +3641,7 @@ static void device_map_fixed_function_samplers(IWineD3DDeviceImpl *This, const s
static void device_map_psamplers(IWineD3DDeviceImpl *This, const struct wined3d_gl_info *gl_info)
{
const WINED3DSAMPLER_TEXTURE_TYPE *sampler_type =
This->stateBlock->state.pixel_shader->baseShader.reg_maps.sampler_type;
This->stateBlock->state.pixel_shader->reg_maps.sampler_type;
unsigned int i;
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i) {
@ -3684,7 +3684,7 @@ static BOOL device_unit_free_for_vs(IWineD3DDeviceImpl *This, const WINED3DSAMPL
static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps, const struct wined3d_gl_info *gl_info)
{
const WINED3DSAMPLER_TEXTURE_TYPE *vshader_sampler_type =
This->stateBlock->state.vertex_shader->baseShader.reg_maps.sampler_type;
This->stateBlock->state.vertex_shader->reg_maps.sampler_type;
const WINED3DSAMPLER_TEXTURE_TYPE *pshader_sampler_type = NULL;
int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
int i;
@ -3695,7 +3695,7 @@ static void device_map_vsamplers(IWineD3DDeviceImpl *This, BOOL ps, const struct
/* 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. */
pshader_sampler_type = pshader->baseShader.reg_maps.sampler_type;
pshader_sampler_type = pshader->reg_maps.sampler_type;
}
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i) {
@ -6258,7 +6258,7 @@ static void delete_opengl_contexts(IWineD3DDeviceImpl *device, IWineD3DSwapChain
gl_info = context->gl_info;
IWineD3DDevice_EnumResources((IWineD3DDevice *)device, device_unload_resource, NULL);
LIST_FOR_EACH_ENTRY(shader, &device->shaders, IWineD3DBaseShaderImpl, baseShader.shader_list_entry)
LIST_FOR_EACH_ENTRY(shader, &device->shaders, IWineD3DBaseShaderImpl, shader_list_entry)
{
device->shader_backend->shader_destroy(shader);
}

View File

@ -4,7 +4,7 @@
* Copyright 2006 Jason Green
* Copyright 2006-2007 Henri Verbeet
* Copyright 2007-2008 Stefan Dösinger for CodeWeavers
* Copyright 2009-2010 Henri Verbeet for CodeWeavers
* Copyright 2009-2011 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -534,27 +534,27 @@ static inline void walk_constant_heap_clamped(const struct wined3d_gl_info *gl_i
/* Loads floating point constants (aka uniforms) into the currently set GLSL program. */
/* GL locking is done by the caller */
static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info,
const float *constants, const GLint *constant_locations, const struct constant_heap *heap,
unsigned char *stack, UINT version)
{
const local_constant *lconst;
/* 1.X pshaders have the constants clamped to [-1;1] implicitly. */
if (This->baseShader.reg_maps.shader_version.major == 1
&& shader_is_pshader_version(This->baseShader.reg_maps.shader_version.type))
if (shader->reg_maps.shader_version.major == 1
&& shader_is_pshader_version(shader->reg_maps.shader_version.type))
walk_constant_heap_clamped(gl_info, constants, constant_locations, heap, stack, version);
else
walk_constant_heap(gl_info, constants, constant_locations, heap, stack, version);
if (!This->baseShader.load_local_constsF)
if (!shader->load_local_constsF)
{
TRACE("No need to load local float constants for this shader\n");
return;
}
/* Immediate constants are clamped to [-1;1] at shader creation time if needed */
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry)
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, local_constant, entry)
{
GLint location = constant_locations[lconst->idx];
/* We found this uniform name in the program - go ahead and send the data */
@ -565,7 +565,7 @@ static void shader_glsl_load_constantsF(IWineD3DBaseShaderImpl *This, const stru
/* Loads integer constants (aka uniforms) into the currently set GLSL program. */
/* GL locking is done by the caller */
static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info,
const GLint locations[MAX_CONST_I], const int *constants, WORD constants_set)
{
unsigned int i;
@ -584,8 +584,9 @@ static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const stru
}
/* Load immediate constants */
ptr = list_head(&This->baseShader.constantsI);
while (ptr) {
ptr = list_head(&shader->constantsI);
while (ptr)
{
const struct local_constant *lconst = LIST_ENTRY(ptr, const struct local_constant, entry);
unsigned int idx = lconst->idx;
const GLint *values = (const GLint *)lconst->value;
@ -596,13 +597,13 @@ static void shader_glsl_load_constantsI(IWineD3DBaseShaderImpl *This, const stru
/* We found this uniform name in the program - go ahead and send the data */
GL_EXTCALL(glUniform4ivARB(locations[idx], 1, values));
checkGLcall("glUniform4ivARB");
ptr = list_next(&This->baseShader.constantsI, ptr);
ptr = list_next(&shader->constantsI, ptr);
}
}
/* Loads boolean constants (aka uniforms) into the currently set GLSL program. */
/* GL locking is done by the caller */
static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const struct wined3d_gl_info *gl_info,
static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *shader, const struct wined3d_gl_info *gl_info,
GLhandleARB programId, const BOOL *constants, WORD constants_set)
{
GLint tmp_loc;
@ -611,7 +612,7 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const stru
const char *prefix;
struct list* ptr;
switch (This->baseShader.reg_maps.shader_version.type)
switch (shader->reg_maps.shader_version.type)
{
case WINED3D_SHADER_TYPE_VERTEX:
prefix = "VB";
@ -627,7 +628,7 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const stru
default:
FIXME("Unknown shader type %#x.\n",
This->baseShader.reg_maps.shader_version.type);
shader->reg_maps.shader_version.type);
prefix = "UB";
break;
}
@ -653,8 +654,9 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const stru
}
/* Load immediate constants */
ptr = list_head(&This->baseShader.constantsB);
while (ptr) {
ptr = list_head(&shader->constantsB);
while (ptr)
{
const struct local_constant *lconst = LIST_ENTRY(ptr, const struct local_constant, entry);
unsigned int idx = lconst->idx;
const GLint *values = (const GLint *)lconst->value;
@ -668,7 +670,7 @@ static void shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const stru
GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, values));
checkGLcall("glUniform1ivARB");
}
ptr = list_next(&This->baseShader.constantsB, ptr);
ptr = list_next(&shader->constantsB, ptr);
}
}
@ -762,11 +764,11 @@ static void shader_glsl_load_constants(const struct wined3d_context *context,
/* Load DirectX 9 integer constants/uniforms for vertex shader */
shader_glsl_load_constantsI(vshader, gl_info, prog->vuniformI_locations, stateBlock->state.vs_consts_i,
stateBlock->changed.vertexShaderConstantsI & vshader->baseShader.reg_maps.integer_constants);
stateBlock->changed.vertexShaderConstantsI & vshader->reg_maps.integer_constants);
/* Load DirectX 9 boolean constants/uniforms for vertex shader */
shader_glsl_load_constantsB(vshader, gl_info, programId, stateBlock->state.vs_consts_b,
stateBlock->changed.vertexShaderConstantsB & vshader->baseShader.reg_maps.boolean_constants);
stateBlock->changed.vertexShaderConstantsB & vshader->reg_maps.boolean_constants);
/* Upload the position fixup params */
shader_get_position_fixup(context, &stateBlock->state, position_fixup);
@ -784,11 +786,11 @@ static void shader_glsl_load_constants(const struct wined3d_context *context,
/* Load DirectX 9 integer constants/uniforms for pixel shader */
shader_glsl_load_constantsI(pshader, gl_info, prog->puniformI_locations, stateBlock->state.ps_consts_i,
stateBlock->changed.pixelShaderConstantsI & pshader->baseShader.reg_maps.integer_constants);
stateBlock->changed.pixelShaderConstantsI & pshader->reg_maps.integer_constants);
/* Load DirectX 9 boolean constants/uniforms for pixel shader */
shader_glsl_load_constantsB(pshader, gl_info, programId, stateBlock->state.ps_consts_b,
stateBlock->changed.pixelShaderConstantsB & pshader->baseShader.reg_maps.boolean_constants);
stateBlock->changed.pixelShaderConstantsB & pshader->reg_maps.boolean_constants);
/* Upload the environment bump map matrix if needed. The needsbumpmat member specifies the texture stage to load the matrix from.
* It can't be 0 for a valid texbem instruction.
@ -915,7 +917,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
struct wined3d_shader_buffer *buffer, IWineD3DBaseShaderImpl *shader,
const struct wined3d_shader_reg_maps *reg_maps, struct shader_glsl_ctx_priv *ctx_priv)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_state *state = &device->stateBlock->state;
const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args;
const struct wined3d_gl_info *gl_info = context->gl_info;
@ -934,7 +936,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
}
/* Declare the constants (aka uniforms) */
if (shader->baseShader.limits.constant_float > 0)
if (shader->limits.constant_float > 0)
{
unsigned max_constantsF;
/* Unless the shader uses indirect addressing, always declare the maximum array size and ignore that we need some
@ -988,18 +990,18 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
max_constantsF = gl_info->limits.glsl_vs_float_constants;
}
}
max_constantsF = min(shader->baseShader.limits.constant_float, max_constantsF);
max_constantsF = min(shader->limits.constant_float, max_constantsF);
shader_addline(buffer, "uniform vec4 %cC[%u];\n", prefix, max_constantsF);
}
/* Always declare the full set of constants, the compiler can remove the
* unused ones because d3d doesn't (yet) support indirect int and bool
* constant addressing. This avoids problems if the app uses e.g. i0 and i9. */
if (shader->baseShader.limits.constant_int > 0 && reg_maps->integer_constants)
shader_addline(buffer, "uniform ivec4 %cI[%u];\n", prefix, shader->baseShader.limits.constant_int);
if (shader->limits.constant_int > 0 && reg_maps->integer_constants)
shader_addline(buffer, "uniform ivec4 %cI[%u];\n", prefix, shader->limits.constant_int);
if (shader->baseShader.limits.constant_bool > 0 && reg_maps->boolean_constants)
shader_addline(buffer, "uniform bool %cB[%u];\n", prefix, shader->baseShader.limits.constant_bool);
if (shader->limits.constant_bool > 0 && reg_maps->boolean_constants)
shader_addline(buffer, "uniform bool %cB[%u];\n", prefix, shader->limits.constant_bool);
if (!pshader)
{
@ -1033,7 +1035,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
}
if (reg_maps->vpos || reg_maps->usesdsy)
{
if (shader->baseShader.limits.constant_float + extra_constants_needed
if (shader->limits.constant_float + extra_constants_needed
+ 1 < gl_info->limits.glsl_ps_float_constants)
{
shader_addline(buffer, "uniform vec4 ycorrection;\n");
@ -1055,7 +1057,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
}
/* Declare texture samplers */
for (i = 0; i < shader->baseShader.limits.sampler; ++i)
for (i = 0; i < shader->limits.sampler; ++i)
{
if (reg_maps->sampler_type[i])
{
@ -1116,7 +1118,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
* samplerNP2Fixup stores texture dimensions and is updated through
* shader_glsl_load_np2fixup_constants when the sampler changes. */
for (i = 0; i < shader->baseShader.limits.sampler; ++i)
for (i = 0; i < shader->limits.sampler; ++i)
{
if (reg_maps->sampler_type[i])
{
@ -1165,8 +1167,8 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
}
/* Declare output register temporaries */
if (shader->baseShader.limits.packed_output)
shader_addline(buffer, "vec4 OUT[%u];\n", shader->baseShader.limits.packed_output);
if (shader->limits.packed_output)
shader_addline(buffer, "vec4 OUT[%u];\n", shader->limits.packed_output);
/* Declare temporary variables */
for (i = 0, map = reg_maps->temporary; map; map >>= 1, ++i)
@ -1197,9 +1199,9 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
* They can't be hardcoded into the shader text via LC = {x, y, z, w}; because the
* float -> string conversion can cause precision loss.
*/
if (!shader->baseShader.load_local_constsF)
if (!shader->load_local_constsF)
{
LIST_FOR_EACH_ENTRY(lconst, &shader->baseShader.constantsF, local_constant, entry)
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, local_constant, entry)
{
shader_addline(buffer, "uniform vec4 %cLC%u;\n", prefix, lconst->idx);
}
@ -2853,7 +2855,8 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
*/
if (ins->src[1].reg.type == WINED3DSPR_CONSTINT)
{
LIST_FOR_EACH_ENTRY(constant, &shader->baseShader.constantsI, local_constant, entry) {
LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, local_constant, entry)
{
if (constant->idx == ins->src[1].reg.idx)
{
control_values = constant->value;
@ -2931,7 +2934,7 @@ static void shader_glsl_rep(const struct wined3d_shader_instruction *ins)
/* Try to hardcode local values to help the GLSL compiler to unroll and optimize the loop */
if (ins->src[0].reg.type == WINED3DSPR_CONSTINT)
{
LIST_FOR_EACH_ENTRY(constant, &shader->baseShader.constantsI, local_constant, entry)
LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, local_constant, entry)
{
if (constant->idx == ins->src[0].reg.idx)
{
@ -3033,7 +3036,7 @@ static void shader_glsl_ret(const struct wined3d_shader_instruction *ins)
static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
{
struct IWineD3DBaseShaderImpl *shader = ins->ctx->shader;
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
ins->ctx->reg_maps->shader_version.minor);
glsl_sample_function_t sample_function;
@ -3123,7 +3126,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
{
struct IWineD3DBaseShaderImpl *shader = ins->ctx->shader;
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param, dx_param, dy_param;
@ -3156,7 +3159,7 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
{
struct IWineD3DBaseShaderImpl *shader = ins->ctx->shader;
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
glsl_sample_function_t sample_function;
glsl_src_param_t coord_param, lod_param;
@ -3844,13 +3847,13 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
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;
DWORD ps_major = ps ? ps->reg_maps.shader_version.major : 0;
unsigned int i;
const char *semantic_name;
UINT semantic_idx;
char reg_mask[6];
const struct wined3d_shader_signature_element *output_signature = vs->baseShader.output_signature;
WORD map = vs->baseShader.reg_maps.output_registers;
const struct wined3d_shader_signature_element *output_signature = vs->output_signature;
WORD map = vs->reg_maps.output_registers;
shader_buffer_clear(buffer);
@ -3936,8 +3939,8 @@ static GLhandleARB generate_param_reorder_function(struct wined3d_shader_buffer
}
/* Then, fix the pixel shader input */
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);
handle_ps3_input(buffer, gl_info, ps->u.ps.input_reg_map, ps->input_signature,
&ps->reg_maps, output_signature, &vs->reg_maps);
shader_addline(buffer, "}\n");
}
@ -3958,7 +3961,8 @@ static void hardcode_local_constants(IWineD3DBaseShaderImpl *shader, const struc
const float *value;
char glsl_name[8];
LIST_FOR_EACH_ENTRY(lconst, &shader->baseShader.constantsF, local_constant, entry) {
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, local_constant, entry)
{
value = (const float *)lconst->value;
snprintf(glsl_name, sizeof(glsl_name), "%cLC%u", prefix, lconst->idx);
tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, glsl_name));
@ -3972,9 +3976,9 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
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 = &shader->baseShader.reg_maps;
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
const struct wined3d_gl_info *gl_info = context->gl_info;
const DWORD *function = shader->baseShader.function;
const DWORD *function = shader->function;
struct shader_glsl_ctx_priv priv_ctx;
/* Create the hw GLSL shader object and assign it as the shader->prgId */
@ -4007,7 +4011,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
/* Pack 3.0 inputs */
if (reg_maps->shader_version.major >= 3 && args->vp_mode != vertexshader)
shader_glsl_input_pack(shader, buffer, shader->baseShader.input_signature, reg_maps, args->vp_mode);
shader_glsl_input_pack(shader, buffer, shader->input_signature, reg_maps, args->vp_mode);
/* Base Shader Body */
shader_generate_main(shader, buffer, reg_maps, function, &priv_ctx);
@ -4073,9 +4077,9 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
struct wined3d_shader_buffer *buffer, IWineD3DBaseShaderImpl *shader,
const struct vs_compile_args *args)
{
const struct wined3d_shader_reg_maps *reg_maps = &shader->baseShader.reg_maps;
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
const struct wined3d_gl_info *gl_info = context->gl_info;
const DWORD *function = shader->baseShader.function;
const DWORD *function = shader->function;
struct shader_glsl_ctx_priv priv_ctx;
/* Create the hw GLSL shader program and assign it as the shader->prgId */
@ -4142,7 +4146,7 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
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;
struct wined3d_state *state = &shader->device->stateBlock->state;
UINT i;
DWORD new_size;
struct glsl_ps_compiled_shader *new_array;
@ -4150,16 +4154,16 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
struct ps_np2fixup_info *np2fixup = NULL;
GLhandleARB ret;
if (!shader->baseShader.backend_data)
if (!shader->backend_data)
{
shader->baseShader.backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
if (!shader->baseShader.backend_data)
shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
if (!shader->backend_data)
{
ERR("Failed to allocate backend data.\n");
return 0;
}
}
shader_data = shader->baseShader.backend_data;
shader_data = shader->backend_data;
/* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
* so a linear search is more performant than a hashmap or a binary search
@ -4199,7 +4203,7 @@ static GLhandleARB find_glsl_pshader(const struct wined3d_context *context,
memset(&shader_data->gl_shaders[shader_data->num_gl_shaders].np2fixup, 0, sizeof(struct ps_np2fixup_info));
if (args->np2_fixup) np2fixup = &shader_data->gl_shaders[shader_data->num_gl_shaders].np2fixup;
pixelshader_update_samplers(&shader->baseShader.reg_maps, state->textures);
pixelshader_update_samplers(&shader->reg_maps, state->textures);
shader_buffer_clear(buffer);
ret = shader_glsl_generate_pshader(context, buffer, shader, args, np2fixup);
@ -4223,20 +4227,20 @@ static GLhandleARB find_glsl_vshader(const struct wined3d_context *context,
UINT i;
DWORD new_size;
struct glsl_vs_compiled_shader *new_array;
DWORD use_map = shader->baseShader.device->strided_streams.use_map;
DWORD use_map = shader->device->strided_streams.use_map;
struct glsl_vshader_private *shader_data;
GLhandleARB ret;
if (!shader->baseShader.backend_data)
if (!shader->backend_data)
{
shader->baseShader.backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
if (!shader->baseShader.backend_data)
shader->backend_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*shader_data));
if (!shader->backend_data)
{
ERR("Failed to allocate backend data.\n");
return 0;
}
}
shader_data = shader->baseShader.backend_data;
shader_data = shader->backend_data;
/* Usually we have very few GL shaders for each d3d shader(just 1 or maybe 2),
* so a linear search is more performant than a hashmap or a binary search
@ -4337,7 +4341,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
if (vshader)
{
GLhandleARB vshader_id = find_glsl_vshader(context, &priv->shader_buffer, vshader, &vs_compile_args);
WORD map = vshader->baseShader.reg_maps.input_registers;
WORD map = vshader->reg_maps.input_registers;
char tmp_name[10];
reorder_shader_id = generate_param_reorder_function(&priv->shader_buffer, vshader, pshader, gl_info);
@ -4371,7 +4375,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
}
checkGLcall("glBindAttribLocationARB");
list_add_head(&vshader->baseShader.linked_programs, &entry->vshader_entry);
list_add_head(&vshader->linked_programs, &entry->vshader_entry);
}
/* Attach GLSL pshader */
@ -4383,7 +4387,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
GL_EXTCALL(glAttachObjectARB(programId, pshader_id));
checkGLcall("glAttachObjectARB");
list_add_head(&pshader->baseShader.linked_programs, &entry->pshader_entry);
list_add_head(&pshader->linked_programs, &entry->pshader_entry);
}
/* Link the program */
@ -4441,8 +4445,7 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
entry->ycorrection_location = GL_EXTCALL(glGetUniformLocationARB(programId, "ycorrection"));
checkGLcall("Find glsl program uniform locations");
if (pshader
&& pshader->baseShader.reg_maps.shader_version.major >= 3
if (pshader && pshader->reg_maps.shader_version.major >= 3
&& pshader->u.ps.declared_in_count > vec4_varyings(3, gl_info))
{
TRACE("Shader %d needs vertex color clamping disabled\n", programId);
@ -4470,14 +4473,10 @@ static void set_glsl_shader_program(const struct wined3d_context *context,
* load them now to have them hardcoded in the GLSL program. This saves some CPU cycles
* later
*/
if (pshader && !pshader->baseShader.load_local_constsF)
{
hardcode_local_constants((IWineD3DBaseShaderImpl *) pshader, gl_info, programId, 'P');
}
if (vshader && !vshader->baseShader.load_local_constsF)
{
hardcode_local_constants((IWineD3DBaseShaderImpl *) vshader, gl_info, programId, 'V');
}
if (pshader && !pshader->load_local_constsF)
hardcode_local_constants(pshader, gl_info, programId, 'P');
if (vshader && !vshader->load_local_constsF)
hardcode_local_constants(vshader, gl_info, programId, 'V');
}
/* GL locking is done by the caller */
@ -4678,7 +4677,7 @@ static void shader_glsl_deselect_depth_blt(void *shader_priv, const struct wined
static void shader_glsl_destroy(IWineD3DBaseShaderImpl *shader)
{
const struct list *linked_programs;
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
struct shader_glsl_priv *priv = device->shader_priv;
const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
@ -4686,16 +4685,16 @@ static void shader_glsl_destroy(IWineD3DBaseShaderImpl *shader)
/* Note: Do not use QueryInterface here to find out which shader type this is because this code
* can be called from IWineD3DBaseShader::Release
*/
char pshader = shader_is_pshader_version(shader->baseShader.reg_maps.shader_version.type);
char pshader = shader_is_pshader_version(shader->reg_maps.shader_version.type);
if (pshader)
{
struct glsl_pshader_private *shader_data = shader->baseShader.backend_data;
struct glsl_pshader_private *shader_data = shader->backend_data;
if (!shader_data || !shader_data->num_gl_shaders)
{
HeapFree(GetProcessHeap(), 0, shader_data);
shader->baseShader.backend_data = NULL;
shader->backend_data = NULL;
return;
}
@ -4711,12 +4710,12 @@ static void shader_glsl_destroy(IWineD3DBaseShaderImpl *shader)
}
else
{
struct glsl_vshader_private *shader_data = shader->baseShader.backend_data;
struct glsl_vshader_private *shader_data = shader->backend_data;
if (!shader_data || !shader_data->num_gl_shaders)
{
HeapFree(GetProcessHeap(), 0, shader_data);
shader->baseShader.backend_data = NULL;
shader->backend_data = NULL;
return;
}
@ -4731,7 +4730,7 @@ static void shader_glsl_destroy(IWineD3DBaseShaderImpl *shader)
}
}
linked_programs = &shader->baseShader.linked_programs;
linked_programs = &shader->linked_programs;
TRACE("Deleting linked programs\n");
if (linked_programs->next) {
@ -4752,7 +4751,7 @@ static void shader_glsl_destroy(IWineD3DBaseShaderImpl *shader)
if (pshader)
{
struct glsl_pshader_private *shader_data = shader->baseShader.backend_data;
struct glsl_pshader_private *shader_data = shader->backend_data;
UINT i;
ENTER_GL();
@ -4766,7 +4765,7 @@ static void shader_glsl_destroy(IWineD3DBaseShaderImpl *shader)
}
else
{
struct glsl_vshader_private *shader_data = shader->baseShader.backend_data;
struct glsl_vshader_private *shader_data = shader->backend_data;
UINT i;
ENTER_GL();
@ -4779,8 +4778,8 @@ static void shader_glsl_destroy(IWineD3DBaseShaderImpl *shader)
HeapFree(GetProcessHeap(), 0, shader_data->gl_shaders);
}
HeapFree(GetProcessHeap(), 0, shader->baseShader.backend_data);
shader->baseShader.backend_data = NULL;
HeapFree(GetProcessHeap(), 0, shader->backend_data);
shader->backend_data = NULL;
context_release(context);
}

View File

@ -5,7 +5,7 @@
* Copyright 2005 Oliver Stieber
* Copyright 2006 Ivan Gyurdiev
* Copyright 2007-2008 Stefan Dösinger for CodeWeavers
* Copyright 2009-2010 Henri Verbeet for CodeWeavers
* Copyright 2009-2011 Henri Verbeet for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -298,7 +298,7 @@ int shader_addline(struct wined3d_shader_buffer *buffer, const char *format, ...
return ret;
}
static void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDeviceImpl *device,
static void shader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *device,
void *parent, const struct wined3d_parent_ops *parent_ops)
{
shader->ref = 1;
@ -453,7 +453,7 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShaderImpl *shader, const s
struct wined3d_shader_signature_element *output_signature, const DWORD *byte_code, DWORD constf_size)
{
unsigned int cur_loop_depth = 0, max_loop_depth = 0;
void *fe_data = shader->baseShader.frontend_data;
void *fe_data = shader->frontend_data;
struct wined3d_shader_version shader_version;
const DWORD *ptr = byte_code;
@ -553,7 +553,7 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShaderImpl *shader, const s
else if (value[3] > 1.0f) value[3] = 1.0f;
}
list_add_head(&shader->baseShader.constantsF, &lconst->entry);
list_add_head(&shader->constantsF, &lconst->entry);
}
else if (ins.handler_idx == WINED3DSIH_DEFI)
{
@ -569,7 +569,7 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShaderImpl *shader, const s
memcpy(lconst->value, ptr, 4 * sizeof(DWORD));
ptr += 4;
list_add_head(&shader->baseShader.constantsI, &lconst->entry);
list_add_head(&shader->constantsI, &lconst->entry);
reg_maps->local_int_consts |= (1 << dst.reg.idx);
}
else if (ins.handler_idx == WINED3DSIH_DEFB)
@ -586,7 +586,7 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShaderImpl *shader, const s
memcpy(lconst->value, ptr, sizeof(DWORD));
++ptr;
list_add_head(&shader->baseShader.constantsB, &lconst->entry);
list_add_head(&shader->constantsB, &lconst->entry);
reg_maps->local_bool_consts |= (1 << dst.reg.idx);
}
/* If there's a loop in the shader. */
@ -821,7 +821,7 @@ static HRESULT shader_get_registers_used(IWineD3DBaseShaderImpl *shader, const s
}
reg_maps->loop_depth = max_loop_depth;
shader->baseShader.functionLength = ((const char *)ptr - (const char *)byte_code);
shader->functionLength = ((const char *)ptr - (const char *)byte_code);
return WINED3D_OK;
}
@ -1162,9 +1162,9 @@ void shader_dump_src_param(const struct wined3d_shader_src_param *param,
void shader_generate_main(IWineD3DBaseShaderImpl *shader, struct wined3d_shader_buffer *buffer,
const struct wined3d_shader_reg_maps *reg_maps, const DWORD *byte_code, void *backend_ctx)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
const struct wined3d_shader_frontend *fe = shader->baseShader.frontend;
void *fe_data = shader->baseShader.frontend_data;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_shader_frontend *fe = shader->frontend;
void *fe_data = shader->frontend_data;
struct wined3d_shader_src_param dst_rel_addr[2];
struct wined3d_shader_src_param src_rel_addr[4];
struct wined3d_shader_dst_param dst_param[2];
@ -1472,18 +1472,16 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
static void shader_cleanup(IWineD3DBaseShaderImpl *shader)
{
shader->baseShader.device->shader_backend->shader_destroy(shader);
HeapFree(GetProcessHeap(), 0, shader->baseShader.reg_maps.constf);
HeapFree(GetProcessHeap(), 0, shader->baseShader.function);
shader_delete_constant_list(&shader->baseShader.constantsF);
shader_delete_constant_list(&shader->baseShader.constantsB);
shader_delete_constant_list(&shader->baseShader.constantsI);
list_remove(&shader->baseShader.shader_list_entry);
shader->device->shader_backend->shader_destroy(shader);
HeapFree(GetProcessHeap(), 0, shader->reg_maps.constf);
HeapFree(GetProcessHeap(), 0, shader->function);
shader_delete_constant_list(&shader->constantsF);
shader_delete_constant_list(&shader->constantsB);
shader_delete_constant_list(&shader->constantsI);
list_remove(&shader->shader_list_entry);
if (shader->baseShader.frontend && shader->baseShader.frontend_data)
{
shader->baseShader.frontend->shader_free(shader->baseShader.frontend_data);
}
if (shader->frontend && shader->frontend_data)
shader->frontend->shader_free(shader->frontend_data);
}
static void shader_none_handle_instruction(const struct wined3d_shader_instruction *ins) {}
@ -1552,11 +1550,11 @@ static HRESULT shader_get_function(IWineD3DBaseShaderImpl *shader, void *data, U
{
if (!data)
{
*data_size = shader->baseShader.functionLength;
*data_size = shader->functionLength;
return WINED3D_OK;
}
if (*data_size < shader->baseShader.functionLength)
if (*data_size < shader->functionLength)
{
/* MSDN claims (for d3d8 at least) that if *pSizeOfData is smaller
* than the required size we should write the required size and
@ -1564,7 +1562,7 @@ static HRESULT shader_get_function(IWineD3DBaseShaderImpl *shader, void *data, U
return WINED3DERR_INVALIDCALL;
}
memcpy(data, shader->baseShader.function, shader->baseShader.functionLength);
memcpy(data, shader->function, shader->functionLength);
return WINED3D_OK;
}
@ -1576,11 +1574,11 @@ static HRESULT shader_set_local_constants_float(IWineD3DBaseShaderImpl *shader,
UINT end_idx = start_idx + count;
UINT i;
if (end_idx > shader->baseShader.limits.constant_float)
if (end_idx > shader->limits.constant_float)
{
WARN("end_idx %u > float constants limit %u.\n",
end_idx, shader->baseShader.limits.constant_float);
end_idx = shader->baseShader.limits.constant_float;
end_idx, shader->limits.constant_float);
end_idx = shader->limits.constant_float;
}
for (i = start_idx; i < end_idx; ++i)
@ -1590,7 +1588,7 @@ static HRESULT shader_set_local_constants_float(IWineD3DBaseShaderImpl *shader,
lconst->idx = i;
memcpy(lconst->value, src_data + (i - start_idx) * 4 /* 4 components */, 4 * sizeof(float));
list_add_head(&shader->baseShader.constantsF, &lconst->entry);
list_add_head(&shader->constantsF, &lconst->entry);
}
return WINED3D_OK;
@ -1599,7 +1597,7 @@ static HRESULT shader_set_local_constants_float(IWineD3DBaseShaderImpl *shader,
static HRESULT shader_set_function(IWineD3DBaseShaderImpl *shader, const DWORD *byte_code,
const struct wined3d_shader_signature *output_signature, DWORD float_const_count)
{
struct wined3d_shader_reg_maps *reg_maps = &shader->baseShader.reg_maps;
struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
const struct wined3d_shader_frontend *fe;
HRESULT hr;
@ -1612,31 +1610,33 @@ static HRESULT shader_set_function(IWineD3DBaseShaderImpl *shader, const DWORD *
FIXME("Unable to find frontend for shader.\n");
return WINED3DERR_INVALIDCALL;
}
shader->baseShader.frontend = fe;
shader->baseShader.frontend_data = fe->shader_init(byte_code, output_signature);
if (!shader->baseShader.frontend_data)
shader->frontend = fe;
shader->frontend_data = fe->shader_init(byte_code, output_signature);
if (!shader->frontend_data)
{
FIXME("Failed to initialize frontend.\n");
return WINED3DERR_INVALIDCALL;
}
/* First pass: trace shader. */
if (TRACE_ON(d3d_shader)) shader_trace_init(fe, shader->baseShader.frontend_data, byte_code);
if (TRACE_ON(d3d_shader))
shader_trace_init(fe, shader->frontend_data, byte_code);
/* Initialize immediate constant lists. */
list_init(&shader->baseShader.constantsF);
list_init(&shader->baseShader.constantsB);
list_init(&shader->baseShader.constantsI);
list_init(&shader->constantsF);
list_init(&shader->constantsB);
list_init(&shader->constantsI);
/* Second pass: figure out which registers are used, what the semantics are, etc. */
hr = shader_get_registers_used(shader, fe,
reg_maps, shader->baseShader.input_signature, shader->baseShader.output_signature,
reg_maps, shader->input_signature, shader->output_signature,
byte_code, float_const_count);
if (FAILED(hr)) return hr;
shader->baseShader.function = HeapAlloc(GetProcessHeap(), 0, shader->baseShader.functionLength);
if (!shader->baseShader.function) return E_OUTOFMEMORY;
memcpy(shader->baseShader.function, byte_code, shader->baseShader.functionLength);
shader->function = HeapAlloc(GetProcessHeap(), 0, shader->functionLength);
if (!shader->function)
return E_OUTOFMEMORY;
memcpy(shader->function, byte_code, shader->functionLength);
return WINED3D_OK;
}
@ -1664,7 +1664,7 @@ static HRESULT STDMETHODCALLTYPE wined3d_shader_QueryInterface(IWineD3DBaseShade
static ULONG STDMETHODCALLTYPE wined3d_shader_AddRef(IWineD3DBaseShader *iface)
{
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)iface;
ULONG refcount = InterlockedIncrement(&shader->baseShader.ref);
ULONG refcount = InterlockedIncrement(&shader->ref);
TRACE("%p increasing refcount to %u.\n", shader, refcount);
@ -1675,14 +1675,14 @@ static ULONG STDMETHODCALLTYPE wined3d_shader_AddRef(IWineD3DBaseShader *iface)
static ULONG STDMETHODCALLTYPE wined3d_shader_Release(IWineD3DBaseShader *iface)
{
IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)iface;
ULONG refcount = InterlockedDecrement(&shader->baseShader.ref);
ULONG refcount = InterlockedDecrement(&shader->ref);
TRACE("%p decreasing refcount to %u.\n", shader, refcount);
if (!refcount)
{
shader_cleanup(shader);
shader->baseShader.parent_ops->wined3d_object_destroyed(shader->baseShader.parent);
shader->parent_ops->wined3d_object_destroyed(shader->parent);
HeapFree(GetProcessHeap(), 0, shader);
}
@ -1693,7 +1693,7 @@ static void * STDMETHODCALLTYPE wined3d_shader_GetParent(IWineD3DBaseShader *ifa
{
TRACE("iface %p.\n", iface);
return ((IWineD3DBaseShaderImpl *)iface)->baseShader.parent;
return ((IWineD3DBaseShaderImpl *)iface)->parent;
}
static HRESULT STDMETHODCALLTYPE wined3d_shader_GetFunction(IWineD3DBaseShader *iface, void *data, UINT *data_size)
@ -1729,7 +1729,7 @@ void find_vs_compile_args(const struct wined3d_state *state,
== WINED3DFOG_NONE ? VS_FOG_COORD : VS_FOG_Z;
args->clip_enabled = state->render_states[WINED3DRS_CLIPPING]
&& state->render_states[WINED3DRS_CLIPPLANEENABLE];
args->swizzle_map = shader->baseShader.device->strided_streams.swizzle_map;
args->swizzle_map = shader->device->strided_streams.swizzle_map;
}
static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_idx2)
@ -1745,7 +1745,7 @@ static BOOL match_usage(BYTE usage1, BYTE usage_idx1, BYTE usage2, BYTE usage_id
BOOL vshader_get_input(struct IWineD3DBaseShaderImpl *shader,
BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum)
{
WORD map = shader->baseShader.reg_maps.input_registers;
WORD map = shader->reg_maps.input_registers;
unsigned int i;
for (i = 0; map; map >>= 1, ++i)
@ -1764,41 +1764,41 @@ BOOL vshader_get_input(struct IWineD3DBaseShaderImpl *shader,
static void vertexshader_set_limits(IWineD3DBaseShaderImpl *shader)
{
DWORD shader_version = WINED3D_SHADER_VERSION(shader->baseShader.reg_maps.shader_version.major,
shader->baseShader.reg_maps.shader_version.minor);
IWineD3DDeviceImpl *device = shader->baseShader.device;
DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
IWineD3DDeviceImpl *device = shader->device;
shader->baseShader.limits.texcoord = 0;
shader->baseShader.limits.attributes = 16;
shader->baseShader.limits.packed_input = 0;
shader->limits.texcoord = 0;
shader->limits.attributes = 16;
shader->limits.packed_input = 0;
switch (shader_version)
{
case WINED3D_SHADER_VERSION(1, 0):
case WINED3D_SHADER_VERSION(1, 1):
shader->baseShader.limits.temporary = 12;
shader->baseShader.limits.constant_bool = 0;
shader->baseShader.limits.constant_int = 0;
shader->baseShader.limits.address = 1;
shader->baseShader.limits.packed_output = 12;
shader->baseShader.limits.sampler = 0;
shader->baseShader.limits.label = 0;
shader->limits.temporary = 12;
shader->limits.constant_bool = 0;
shader->limits.constant_int = 0;
shader->limits.address = 1;
shader->limits.packed_output = 12;
shader->limits.sampler = 0;
shader->limits.label = 0;
/* TODO: vs_1_1 has a minimum of 96 constants. What happens when
* a vs_1_1 shader is used on a vs_3_0 capable card that has 256
* constants? */
shader->baseShader.limits.constant_float = min(256, device->d3d_vshader_constantF);
shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
break;
case WINED3D_SHADER_VERSION(2, 0):
case WINED3D_SHADER_VERSION(2, 1):
shader->baseShader.limits.temporary = 12;
shader->baseShader.limits.constant_bool = 16;
shader->baseShader.limits.constant_int = 16;
shader->baseShader.limits.address = 1;
shader->baseShader.limits.packed_output = 12;
shader->baseShader.limits.sampler = 0;
shader->baseShader.limits.label = 16;
shader->baseShader.limits.constant_float = min(256, device->d3d_vshader_constantF);
shader->limits.temporary = 12;
shader->limits.constant_bool = 16;
shader->limits.constant_int = 16;
shader->limits.address = 1;
shader->limits.packed_output = 12;
shader->limits.sampler = 0;
shader->limits.label = 16;
shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
break;
case WINED3D_SHADER_VERSION(4, 0):
@ -1806,33 +1806,33 @@ static void vertexshader_set_limits(IWineD3DBaseShaderImpl *shader)
/* Fall through. */
case WINED3D_SHADER_VERSION(3, 0):
shader->baseShader.limits.temporary = 32;
shader->baseShader.limits.constant_bool = 32;
shader->baseShader.limits.constant_int = 32;
shader->baseShader.limits.address = 1;
shader->baseShader.limits.packed_output = 12;
shader->baseShader.limits.sampler = 4;
shader->baseShader.limits.label = 16; /* FIXME: 2048 */
shader->limits.temporary = 32;
shader->limits.constant_bool = 32;
shader->limits.constant_int = 32;
shader->limits.address = 1;
shader->limits.packed_output = 12;
shader->limits.sampler = 4;
shader->limits.label = 16; /* FIXME: 2048 */
/* DX10 cards on Windows advertise a d3d9 constant limit of 256
* even though they are capable of supporting much more (GL
* drivers advertise 1024). d3d9.dll and d3d8.dll clamp the
* wined3d-advertised maximum. Clamp the constant limit for <= 3.0
* shaders to 256. */
shader->baseShader.limits.constant_float = min(256, device->d3d_vshader_constantF);
shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
break;
default:
shader->baseShader.limits.temporary = 12;
shader->baseShader.limits.constant_bool = 16;
shader->baseShader.limits.constant_int = 16;
shader->baseShader.limits.address = 1;
shader->baseShader.limits.packed_output = 12;
shader->baseShader.limits.sampler = 0;
shader->baseShader.limits.label = 16;
shader->baseShader.limits.constant_float = min(256, device->d3d_vshader_constantF);
shader->limits.temporary = 12;
shader->limits.constant_bool = 16;
shader->limits.constant_int = 16;
shader->limits.address = 1;
shader->limits.packed_output = 12;
shader->limits.sampler = 0;
shader->limits.label = 16;
shader->limits.constant_float = min(256, device->d3d_vshader_constantF);
FIXME("Unrecognized vertex shader version \"%u.%u\".\n",
shader->baseShader.reg_maps.shader_version.major,
shader->baseShader.reg_maps.shader_version.minor);
shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
}
}
@ -1840,7 +1840,7 @@ HRESULT vertexshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *de
const DWORD *byte_code, const struct wined3d_shader_signature *output_signature,
void *parent, const struct wined3d_parent_ops *parent_ops)
{
struct wined3d_shader_reg_maps *reg_maps = &shader->baseShader.reg_maps;
struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
unsigned int i;
HRESULT hr;
WORD map;
@ -1848,7 +1848,7 @@ HRESULT vertexshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *de
if (!byte_code) return WINED3DERR_INVALIDCALL;
shader->lpVtbl = &wined3d_shader_vtbl;
shader_init(&shader->baseShader, device, parent, parent_ops);
shader_init(shader, device, parent, parent_ops);
hr = shader_set_function(shader, byte_code, output_signature, device->d3d_vshader_constantF);
if (FAILED(hr))
@ -1861,11 +1861,12 @@ HRESULT vertexshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *de
map = reg_maps->input_registers;
for (i = 0; map; map >>= 1, ++i)
{
if (!(map & 1) || !shader->baseShader.input_signature[i].semantic_name) continue;
if (!(map & 1) || !shader->input_signature[i].semantic_name)
continue;
shader->u.vs.attributes[i].usage =
shader_usage_from_semantic_name(shader->baseShader.input_signature[i].semantic_name);
shader->u.vs.attributes[i].usage_idx = shader->baseShader.input_signature[i].semantic_idx;
shader_usage_from_semantic_name(shader->input_signature[i].semantic_name);
shader->u.vs.attributes[i].usage_idx = shader->input_signature[i].semantic_idx;
}
if (output_signature)
@ -1874,14 +1875,14 @@ HRESULT vertexshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *de
{
struct wined3d_shader_signature_element *e = &output_signature->elements[i];
reg_maps->output_registers |= 1 << e->register_idx;
shader->baseShader.output_signature[e->register_idx] = *e;
shader->output_signature[e->register_idx] = *e;
}
}
vertexshader_set_limits(shader);
shader->baseShader.load_local_constsF = reg_maps->usesrelconstF
&& !list_empty(&shader->baseShader.constantsF);
shader->load_local_constsF = reg_maps->usesrelconstF
&& !list_empty(&shader->constantsF);
return WINED3D_OK;
}
@ -1893,7 +1894,7 @@ HRESULT geometryshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *
HRESULT hr;
shader->lpVtbl = &wined3d_shader_vtbl;
shader_init(&shader->baseShader, device, parent, parent_ops);
shader_init(shader, device, parent, parent_ops);
hr = shader_set_function(shader, byte_code, output_signature, 0);
if (FAILED(hr))
@ -1903,7 +1904,7 @@ HRESULT geometryshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *
return hr;
}
shader->baseShader.load_local_constsF = FALSE;
shader->load_local_constsF = FALSE;
return WINED3D_OK;
}
@ -1911,7 +1912,7 @@ HRESULT geometryshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *
void find_ps_compile_args(const struct wined3d_state *state,
IWineD3DBaseShaderImpl *shader, struct ps_compile_args *args)
{
IWineD3DDeviceImpl *device = shader->baseShader.device;
IWineD3DDeviceImpl *device = shader->device;
const struct wined3d_texture *texture;
UINT i;
@ -1922,8 +1923,8 @@ void find_ps_compile_args(const struct wined3d_state *state,
if (rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE) args->srgb_correction = 1;
}
if (shader->baseShader.reg_maps.shader_version.major == 1
&& shader->baseShader.reg_maps.shader_version.minor <= 3)
if (shader->reg_maps.shader_version.major == 1
&& shader->reg_maps.shader_version.minor <= 3)
{
for (i = 0; i < 4; ++i)
{
@ -1937,7 +1938,9 @@ void find_ps_compile_args(const struct wined3d_state *state,
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
if (!shader->baseShader.reg_maps.sampler_type[i]) continue;
if (!shader->reg_maps.sampler_type[i])
continue;
texture = state->textures[i];
if (!texture)
{
@ -1953,7 +1956,7 @@ void find_ps_compile_args(const struct wined3d_state *state,
if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
args->np2_fixup |= (1 << i);
}
if (shader->baseShader.reg_maps.shader_version.major >= 3)
if (shader->reg_maps.shader_version.major >= 3)
{
if (device->strided_streams.position_transformed)
{
@ -2006,12 +2009,12 @@ void find_ps_compile_args(const struct wined3d_state *state,
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);
DWORD shader_version = WINED3D_SHADER_VERSION(shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
shader->baseShader.limits.attributes = 0;
shader->baseShader.limits.address = 0;
shader->baseShader.limits.packed_output = 0;
shader->limits.attributes = 0;
shader->limits.address = 0;
shader->limits.packed_output = 0;
switch (shader_version)
{
@ -2019,47 +2022,47 @@ static void pixelshader_set_limits(IWineD3DBaseShaderImpl *shader)
case WINED3D_SHADER_VERSION(1, 1):
case WINED3D_SHADER_VERSION(1, 2):
case WINED3D_SHADER_VERSION(1, 3):
shader->baseShader.limits.temporary = 2;
shader->baseShader.limits.constant_float = 8;
shader->baseShader.limits.constant_int = 0;
shader->baseShader.limits.constant_bool = 0;
shader->baseShader.limits.texcoord = 4;
shader->baseShader.limits.sampler = 4;
shader->baseShader.limits.packed_input = 0;
shader->baseShader.limits.label = 0;
shader->limits.temporary = 2;
shader->limits.constant_float = 8;
shader->limits.constant_int = 0;
shader->limits.constant_bool = 0;
shader->limits.texcoord = 4;
shader->limits.sampler = 4;
shader->limits.packed_input = 0;
shader->limits.label = 0;
break;
case WINED3D_SHADER_VERSION(1, 4):
shader->baseShader.limits.temporary = 6;
shader->baseShader.limits.constant_float = 8;
shader->baseShader.limits.constant_int = 0;
shader->baseShader.limits.constant_bool = 0;
shader->baseShader.limits.texcoord = 6;
shader->baseShader.limits.sampler = 6;
shader->baseShader.limits.packed_input = 0;
shader->baseShader.limits.label = 0;
shader->limits.temporary = 6;
shader->limits.constant_float = 8;
shader->limits.constant_int = 0;
shader->limits.constant_bool = 0;
shader->limits.texcoord = 6;
shader->limits.sampler = 6;
shader->limits.packed_input = 0;
shader->limits.label = 0;
break;
/* FIXME: Temporaries must match D3DPSHADERCAPS2_0.NumTemps. */
case WINED3D_SHADER_VERSION(2, 0):
shader->baseShader.limits.temporary = 32;
shader->baseShader.limits.constant_float = 32;
shader->baseShader.limits.constant_int = 16;
shader->baseShader.limits.constant_bool = 16;
shader->baseShader.limits.texcoord = 8;
shader->baseShader.limits.sampler = 16;
shader->baseShader.limits.packed_input = 0;
shader->limits.temporary = 32;
shader->limits.constant_float = 32;
shader->limits.constant_int = 16;
shader->limits.constant_bool = 16;
shader->limits.texcoord = 8;
shader->limits.sampler = 16;
shader->limits.packed_input = 0;
break;
case WINED3D_SHADER_VERSION(2, 1):
shader->baseShader.limits.temporary = 32;
shader->baseShader.limits.constant_float = 32;
shader->baseShader.limits.constant_int = 16;
shader->baseShader.limits.constant_bool = 16;
shader->baseShader.limits.texcoord = 8;
shader->baseShader.limits.sampler = 16;
shader->baseShader.limits.packed_input = 0;
shader->baseShader.limits.label = 16;
shader->limits.temporary = 32;
shader->limits.constant_float = 32;
shader->limits.constant_int = 16;
shader->limits.constant_bool = 16;
shader->limits.texcoord = 8;
shader->limits.sampler = 16;
shader->limits.packed_input = 0;
shader->limits.label = 16;
break;
case WINED3D_SHADER_VERSION(4, 0):
@ -2067,28 +2070,28 @@ static void pixelshader_set_limits(IWineD3DBaseShaderImpl *shader)
/* Fall through. */
case WINED3D_SHADER_VERSION(3, 0):
shader->baseShader.limits.temporary = 32;
shader->baseShader.limits.constant_float = 224;
shader->baseShader.limits.constant_int = 16;
shader->baseShader.limits.constant_bool = 16;
shader->baseShader.limits.texcoord = 0;
shader->baseShader.limits.sampler = 16;
shader->baseShader.limits.packed_input = 12;
shader->baseShader.limits.label = 16; /* FIXME: 2048 */
shader->limits.temporary = 32;
shader->limits.constant_float = 224;
shader->limits.constant_int = 16;
shader->limits.constant_bool = 16;
shader->limits.texcoord = 0;
shader->limits.sampler = 16;
shader->limits.packed_input = 12;
shader->limits.label = 16; /* FIXME: 2048 */
break;
default:
shader->baseShader.limits.temporary = 32;
shader->baseShader.limits.constant_float = 32;
shader->baseShader.limits.constant_int = 16;
shader->baseShader.limits.constant_bool = 16;
shader->baseShader.limits.texcoord = 8;
shader->baseShader.limits.sampler = 16;
shader->baseShader.limits.packed_input = 0;
shader->baseShader.limits.label = 0;
shader->limits.temporary = 32;
shader->limits.constant_float = 32;
shader->limits.constant_int = 16;
shader->limits.constant_bool = 16;
shader->limits.texcoord = 8;
shader->limits.sampler = 16;
shader->limits.packed_input = 0;
shader->limits.label = 0;
FIXME("Unrecognized pixel shader version %u.%u\n",
shader->baseShader.reg_maps.shader_version.major,
shader->baseShader.reg_maps.shader_version.minor);
shader->reg_maps.shader_version.major,
shader->reg_maps.shader_version.minor);
}
}
@ -2103,7 +2106,7 @@ HRESULT pixelshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *dev
if (!byte_code) return WINED3DERR_INVALIDCALL;
shader->lpVtbl = &wined3d_shader_vtbl;
shader_init(&shader->baseShader, device, parent, parent_ops);
shader_init(shader, device, parent, parent_ops);
hr = shader_set_function(shader, byte_code, output_signature, device->d3d_pshader_constantF);
if (FAILED(hr))
@ -2155,7 +2158,7 @@ HRESULT pixelshader_init(IWineD3DBaseShaderImpl *shader, IWineD3DDeviceImpl *dev
}
}
shader->baseShader.load_local_constsF = FALSE;
shader->load_local_constsF = FALSE;
return WINED3D_OK;
}

View File

@ -3571,7 +3571,7 @@ static void tex_bumpenvlscale(DWORD state, struct wined3d_stateblock *stateblock
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
IWineD3DBaseShaderImpl *ps = stateblock->state.pixel_shader;
if (ps && stage && (ps->baseShader.reg_maps.luminanceparams & (1 << stage)))
if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
{
/* The pixel shader has to know the luminance scale. Do a constants update if it
* isn't scheduled anyway
@ -3742,7 +3742,7 @@ static void shader_bumpenvmat(DWORD state, struct wined3d_stateblock *stateblock
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
IWineD3DBaseShaderImpl *ps = stateblock->state.pixel_shader;
if (ps && stage && (ps->baseShader.reg_maps.bumpmat & (1 << stage)))
if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
{
/* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
* anyway

View File

@ -2685,41 +2685,6 @@ int shader_vaddline(struct wined3d_shader_buffer *buffer, const char *fmt, va_li
extern BOOL vshader_get_input(struct IWineD3DBaseShaderImpl *shader,
BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum) DECLSPEC_HIDDEN;
/*****************************************************************************
* IDirect3DBaseShader implementation structure
*/
typedef struct IWineD3DBaseShaderClass
{
LONG ref;
SHADER_LIMITS limits;
DWORD *function;
UINT functionLength;
BOOL load_local_constsF;
const struct wined3d_shader_frontend *frontend;
void *frontend_data;
void *backend_data;
void *parent;
const struct wined3d_parent_ops *parent_ops;
/* Programs this shader is linked with */
struct list linked_programs;
/* Immediate constants (override global ones) */
struct list constantsB;
struct list constantsF;
struct list constantsI;
struct wined3d_shader_reg_maps reg_maps;
struct wined3d_shader_signature_element input_signature[max(MAX_ATTRIBS, MAX_REG_INPUT)];
struct wined3d_shader_signature_element output_signature[MAX_REG_OUTPUT];
/* Pointer to the parent device */
struct IWineD3DDeviceImpl *device;
struct list shader_list_entry;
} IWineD3DBaseShaderClass;
struct wined3d_vertex_shader
{
struct wined3d_shader_attribute attributes[MAX_ATTRIBS];
@ -2742,8 +2707,33 @@ typedef struct IWineD3DBaseShaderImpl {
/* IUnknown */
const IWineD3DBaseShaderVtbl *lpVtbl;
/* IWineD3DBaseShader */
IWineD3DBaseShaderClass baseShader;
LONG ref;
SHADER_LIMITS limits;
DWORD *function;
UINT functionLength;
BOOL load_local_constsF;
const struct wined3d_shader_frontend *frontend;
void *frontend_data;
void *backend_data;
void *parent;
const struct wined3d_parent_ops *parent_ops;
/* Programs this shader is linked with */
struct list linked_programs;
/* Immediate constants (override global ones) */
struct list constantsB;
struct list constantsF;
struct list constantsI;
struct wined3d_shader_reg_maps reg_maps;
struct wined3d_shader_signature_element input_signature[max(MAX_ATTRIBS, MAX_REG_INPUT)];
struct wined3d_shader_signature_element output_signature[MAX_REG_OUTPUT];
/* Pointer to the parent device */
struct IWineD3DDeviceImpl *device;
struct list shader_list_entry;
union
{
@ -2843,15 +2833,20 @@ static inline void shader_get_position_fixup(const struct wined3d_context *conte
}
}
static inline BOOL shader_constant_is_local(IWineD3DBaseShaderImpl* This, DWORD reg) {
local_constant* lconst;
static inline BOOL shader_constant_is_local(IWineD3DBaseShaderImpl *shader, DWORD reg)
{
struct local_constant *lconst;
if(This->baseShader.load_local_constsF) return FALSE;
LIST_FOR_EACH_ENTRY(lconst, &This->baseShader.constantsF, local_constant, entry) {
if(lconst->idx == reg) return TRUE;
if (shader->load_local_constsF)
return FALSE;
LIST_FOR_EACH_ENTRY(lconst, &shader->constantsF, local_constant, entry)
{
if (lconst->idx == reg)
return TRUE;
}
return FALSE;
return FALSE;
}
/* Using additional shader constants (uniforms in GLSL / program environment