[PATCH 11/11] wined3d: Implement SM4 indexable temporary registers in GLSL backend.
Józef Kucia
jkucia at codeweavers.com
Mon Jul 4 05:26:30 CDT 2016
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
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;
--
2.7.3
More information about the wine-patches
mailing list