Module: wine Branch: master Commit: b18f2f5debba73005ea4c39160715c29f0c360ad URL: http://source.winehq.org/git/wine.git/?a=commit;h=b18f2f5debba73005ea4c39160... Author: Józef Kucia <jkucia(a)codeweavers.com> Date: Mon Jul 4 12:26:30 2016 +0200 wined3d: Implement SM4 indexable temporary registers in GLSL backend. Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/wined3d/glsl_shader.c | 18 +++++++++++++++++- dlls/wined3d/shader.c | 27 +++++++++++++++++++++++++-- dlls/wined3d/wined3d_private.h | 16 +++++++++------- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 63442b3..5c33106 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1796,6 +1796,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont const struct vs_compile_args *vs_args = ctx_priv->cur_vs_args; const struct ps_compile_args *ps_args = ctx_priv->cur_ps_args; const struct wined3d_gl_info *gl_info = context->gl_info; + const struct wined3d_shader_indexable_temp *idx_temp_reg; unsigned int i, extra_constants_needed = 0; const struct wined3d_shader_lconst *lconst; const char *prefix; @@ -2172,6 +2173,14 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont if (map & 1) shader_addline(buffer, "vec4 R%u;\n", i); } + /* Declare indexable temporary variables */ + LIST_FOR_EACH_ENTRY(idx_temp_reg, ®_maps->indexable_temps, struct wined3d_shader_indexable_temp, entry) + { + if (idx_temp_reg->component_count != 4) + FIXME("Ignoring component count %u.\n", idx_temp_reg->component_count); + shader_addline(buffer, "vec4 X%u[%u];\n", idx_temp_reg->register_idx, idx_temp_reg->register_size); + } + /* Declare loop registers aLx */ if (version->major < 4) { @@ -2575,6 +2584,13 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * sprintf(register_name, "uint(gl_PrimitiveIDIn)"); break; + case WINED3DSPR_IDXTEMP: + if (reg->idx[1].rel_addr) + sprintf(register_name, "X%u[%s + %u]", reg->idx[0].offset, rel_param1.param_str, reg->idx[1].offset); + else + sprintf(register_name, "X%u[%u]", reg->idx[0].offset, reg->idx[1].offset); + break; + default: FIXME("Unhandled register type %#x.\n", reg->type); sprintf(register_name, "unrecognized_register"); @@ -8568,7 +8584,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT */ NULL, /* WINED3DSIH_DCL_HS_MAX_TESSFACTOR */ NULL, /* WINED3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER */ NULL, - /* WINED3DSIH_DCL_INDEXABLE_TEMP */ NULL, + /* WINED3DSIH_DCL_INDEXABLE_TEMP */ shader_glsl_nop, /* WINED3DSIH_DCL_INPUT */ shader_glsl_nop, /* WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT */ NULL, /* WINED3DSIH_DCL_INPUT_PRIMITIVE */ shader_glsl_nop, diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index d11eeb0..2a3b9a9 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -852,6 +852,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st memset(input_signature_elements, 0, sizeof(input_signature_elements)); memset(output_signature_elements, 0, sizeof(output_signature_elements)); reg_maps->min_rel_offset = ~0U; + list_init(®_maps->indexable_temps); fe->shader_read_header(fe_data, &ptr, &shader_version); reg_maps->shader_version = shader_version; @@ -947,6 +948,16 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st FIXME("Multiple immediate constant buffers.\n"); reg_maps->icb = ins.declaration.icb; } + else if (ins.handler_idx == WINED3DSIH_DCL_INDEXABLE_TEMP) + { + struct wined3d_shader_indexable_temp *reg; + + if (!(reg = HeapAlloc(GetProcessHeap(), 0, sizeof(*reg)))) + return E_OUTOFMEMORY; + + *reg = ins.declaration.indexable_temp; + list_add_tail(®_maps->indexable_temps, ®->entry); + } else if (ins.handler_idx == WINED3DSIH_DCL_INPUT_PRIMITIVE) { if (shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY) @@ -1331,6 +1342,18 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st return WINED3D_OK; } +static void shader_cleanup_reg_maps(struct wined3d_shader_reg_maps *reg_maps) +{ + struct wined3d_shader_indexable_temp *reg, *reg_next; + + HeapFree(GetProcessHeap(), 0, reg_maps->constf); + HeapFree(GetProcessHeap(), 0, reg_maps->sampler_map.entries); + + LIST_FOR_EACH_ENTRY_SAFE(reg, reg_next, ®_maps->indexable_temps, struct wined3d_shader_indexable_temp, entry) + HeapFree(GetProcessHeap(), 0, reg); + list_init(®_maps->indexable_temps); +} + unsigned int shader_find_free_input_register(const struct wined3d_shader_reg_maps *reg_maps, unsigned int max) { DWORD map = 1u << max; @@ -2432,8 +2455,7 @@ static void shader_cleanup(struct wined3d_shader *shader) HeapFree(GetProcessHeap(), 0, shader->input_signature.elements); HeapFree(GetProcessHeap(), 0, shader->signature_strings); shader->device->shader_backend->shader_destroy(shader); - HeapFree(GetProcessHeap(), 0, shader->reg_maps.constf); - HeapFree(GetProcessHeap(), 0, shader->reg_maps.sampler_map.entries); + shader_cleanup_reg_maps(&shader->reg_maps); HeapFree(GetProcessHeap(), 0, shader->function); shader_delete_constant_list(&shader->constantsF); shader_delete_constant_list(&shader->constantsB); @@ -2609,6 +2631,7 @@ static HRESULT shader_set_function(struct wined3d_shader *shader, const DWORD *b list_init(&shader->constantsB); list_init(&shader->constantsI); shader->lconst_inf_or_nan = FALSE; + list_init(®_maps->indexable_temps); fe = shader_select_frontend(*byte_code); if (!fe) diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c3d5ae8..f592664 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -791,6 +791,14 @@ struct wined3d_shader_immediate_constant_buffer DWORD data[MAX_IMMEDIATE_CONSTANT_BUFFER_SIZE]; }; +struct wined3d_shader_indexable_temp +{ + struct list entry; + unsigned int register_idx; + unsigned int register_size; + unsigned int component_count; +}; + #define WINED3D_SHADER_VERSION(major, minor) (((major) << 8) | (minor)) struct wined3d_shader_reg_maps @@ -801,6 +809,7 @@ struct wined3d_shader_reg_maps WORD labels; /* MAX_LABELS, 16 */ DWORD temporary; /* MAX_REG_TEMP, 32 */ DWORD *constf; /* pixel, vertex */ + struct list indexable_temps; const struct wined3d_shader_immediate_constant_buffer *icb; union { @@ -899,13 +908,6 @@ struct wined3d_shader_src_param enum wined3d_shader_src_modifier modifiers; }; -struct wined3d_shader_indexable_temp -{ - unsigned int register_idx; - unsigned int register_size; - unsigned int component_count; -}; - struct wined3d_shader_semantic { enum wined3d_decl_usage usage;