Commit b18f2f5d authored by Józef Kucia's avatar Józef Kucia Committed by Alexandre Julliard

wined3d: Implement SM4 indexable temporary registers in GLSL backend.

parent 2460d6f3
......@@ -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, &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,
......
......@@ -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(&reg_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(&reg_maps->indexable_temps, &reg->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, &reg_maps->indexable_temps, struct wined3d_shader_indexable_temp, entry)
HeapFree(GetProcessHeap(), 0, reg);
list_init(&reg_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(&reg_maps->indexable_temps);
fe = shader_select_frontend(*byte_code);
if (!fe)
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment