wined3d: Record the data type of shader resources.

This commit is contained in:
Henri Verbeet 2014-12-03 10:28:11 +01:00 committed by Alexandre Julliard
parent f7e485dcf4
commit 3aa9fe6bef
7 changed files with 115 additions and 39 deletions

View File

@ -1390,7 +1390,7 @@ static const char *shader_arb_get_modifier(const struct wined3d_shader_instructi
static void shader_hw_sample(const struct wined3d_shader_instruction *ins, DWORD sampler_idx,
const char *dst_str, const char *coord_reg, WORD flags, const char *dsx, const char *dsy)
{
enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_type[sampler_idx];
enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[sampler_idx].type;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
const char *tex_type;
BOOL np2_fixup = FALSE;

View File

@ -2585,14 +2585,14 @@ static void context_map_fixed_function_samplers(struct wined3d_context *context,
static void context_map_psamplers(struct wined3d_context *context, const struct wined3d_state *state)
{
const enum wined3d_shader_resource_type *resource_type =
state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_type;
const struct wined3d_shader_resource_info *resource_info =
state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info;
unsigned int i;
const struct wined3d_d3d_info *d3d_info = context->d3d_info;
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
if (resource_type[i] && context->tex_unit_map[i] != i)
if (resource_info[i].type && context->tex_unit_map[i] != i)
{
context_map_stage(context, i, i);
context_invalidate_state(context, STATE_SAMPLER(i));
@ -2603,8 +2603,8 @@ static void context_map_psamplers(struct wined3d_context *context, const struct
}
static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
const enum wined3d_shader_resource_type *ps_resource_types,
const enum wined3d_shader_resource_type *vs_resource_types, DWORD unit)
const struct wined3d_shader_resource_info *ps_resource_info,
const struct wined3d_shader_resource_info *vs_resource_info, DWORD unit)
{
DWORD current_mapping = context->rev_tex_unit_map[unit];
@ -2616,25 +2616,25 @@ static BOOL context_unit_free_for_vs(const struct wined3d_context *context,
{
/* Used by a fragment sampler */
if (!ps_resource_types)
if (!ps_resource_info)
{
/* No pixel shader, check fixed function */
return current_mapping >= MAX_TEXTURES || !(context->fixed_function_usage_map & (1 << current_mapping));
}
/* Pixel shader, check the shader's sampler map */
return !ps_resource_types[current_mapping];
return !ps_resource_info[current_mapping].type;
}
/* Used by a vertex sampler */
return !vs_resource_types[current_mapping - MAX_FRAGMENT_SAMPLERS];
return !vs_resource_info[current_mapping - MAX_FRAGMENT_SAMPLERS].type;
}
static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, const struct wined3d_state *state)
{
const enum wined3d_shader_resource_type *vs_resource_type =
state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_type;
const enum wined3d_shader_resource_type *ps_resource_type = NULL;
const struct wined3d_shader_resource_info *vs_resource_info =
state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info;
const struct wined3d_shader_resource_info *ps_resource_info = NULL;
const struct wined3d_gl_info *gl_info = context->gl_info;
int start = min(MAX_COMBINED_SAMPLERS, gl_info->limits.combined_samplers) - 1;
int i;
@ -2643,12 +2643,12 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons
* resource's specific type. Otherwise we'd need to call
* shader_update_samplers() here for 1.x pixelshaders. */
if (ps)
ps_resource_type = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_type;
ps_resource_info = state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info;
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
{
DWORD vsampler_idx = i + MAX_FRAGMENT_SAMPLERS;
if (vs_resource_type[i])
if (vs_resource_info[i].type)
{
if (context->tex_unit_map[vsampler_idx] != WINED3D_UNMAPPED_STAGE)
{
@ -2658,7 +2658,7 @@ static void context_map_vsamplers(struct wined3d_context *context, BOOL ps, cons
while (start >= 0)
{
if (context_unit_free_for_vs(context, ps_resource_type, vs_resource_type, start))
if (context_unit_free_for_vs(context, ps_resource_info, vs_resource_info, start))
{
context_map_stage(context, vsampler_idx, start);
context_invalidate_state(context, STATE_SAMPLER(vsampler_idx));
@ -2930,7 +2930,7 @@ static void context_preload_textures(struct wined3d_context *context, const stru
{
for (i = 0; i < MAX_VERTEX_SAMPLERS; ++i)
{
if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_type[i])
if (state->shader[WINED3D_SHADER_TYPE_VERTEX]->reg_maps.resource_info[i].type)
context_preload_texture(context, state, MAX_FRAGMENT_SAMPLERS + i);
}
}
@ -2939,7 +2939,7 @@ static void context_preload_textures(struct wined3d_context *context, const stru
{
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_type[i])
if (state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.resource_info[i].type)
context_preload_texture(context, state, i);
}
}

View File

@ -1066,11 +1066,11 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
{
BOOL shadow_sampler, tex_rect;
if (!reg_maps->resource_type[i])
if (!reg_maps->resource_info[i].type)
continue;
shadow_sampler = version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1 << i));
switch (reg_maps->resource_type[i])
switch (reg_maps->resource_info[i].type)
{
case WINED3D_SHADER_RESOURCE_TEXTURE_1D:
if (shadow_sampler)
@ -1112,7 +1112,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
default:
shader_addline(buffer, "uniform unsupported_sampler %s_sampler%u;\n", prefix, i);
FIXME("Unhandled resource type %#x.\n", reg_maps->resource_type[i]);
FIXME("Unhandled resource type %#x.\n", reg_maps->resource_info[i].type);
break;
}
}
@ -1134,10 +1134,10 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
for (i = 0; i < shader->limits->sampler; ++i)
{
if (!reg_maps->resource_type[i] || !(ps_args->np2_fixup & (1 << i)))
if (!reg_maps->resource_info[i].type || !(ps_args->np2_fixup & (1 << i)))
continue;
if (reg_maps->resource_type[i] != WINED3D_SHADER_RESOURCE_TEXTURE_2D)
if (reg_maps->resource_info[i].type != WINED3D_SHADER_RESOURCE_TEXTURE_2D)
{
FIXME("Non-2D texture is flagged for NP2 texcoord fixup.\n");
continue;
@ -1890,7 +1890,7 @@ static const char *shader_glsl_get_rel_op(enum wined3d_shader_rel_op op)
static void shader_glsl_get_sample_function(const struct wined3d_shader_context *ctx,
DWORD resource_idx, DWORD flags, struct glsl_sample_function *sample_function)
{
enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_type[resource_idx];
enum wined3d_shader_resource_type resource_type = ctx->reg_maps->resource_info[resource_idx].type;
const struct wined3d_gl_info *gl_info = ctx->gl_info;
BOOL shadow = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
&& (((const struct shader_glsl_ctx_priv *)ctx->backend_data)->cur_ps_args->shadow & (1 << resource_idx));
@ -3468,7 +3468,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
{
DWORD flags = (priv->cur_ps_args->tex_transform >> resource_idx * WINED3D_PSARGS_TEXTRANSFORM_SHIFT)
& WINED3D_PSARGS_TEXTRANSFORM_MASK;
enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_type[resource_idx];
enum wined3d_shader_resource_type resource_type = ins->ctx->reg_maps->resource_info[resource_idx].type;
/* Projected cube textures don't make a lot of sense, the resulting coordinates stay the same. */
if (flags & WINED3D_PSARGS_PROJECTED && resource_type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
@ -3507,7 +3507,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
else
{
if ((ins->flags & WINED3DSI_TEXLD_PROJECT)
&& ins->ctx->reg_maps->resource_type[resource_idx] != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
&& ins->ctx->reg_maps->resource_info[resource_idx].type != WINED3D_SHADER_RESOURCE_TEXTURE_CUBE)
{
/* ps 2.0 texldp instruction always divides by the fourth component. */
sample_flags |= WINED3D_GLSL_SAMPLE_PROJECTED;

View File

@ -664,12 +664,13 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
case WINED3DSPR_SAMPLER:
case WINED3DSPR_RESOURCE:
if (reg_idx >= ARRAY_SIZE(reg_maps->resource_type))
if (reg_idx >= ARRAY_SIZE(reg_maps->resource_info))
{
ERR("Invalid resource index %u.\n", reg_idx);
break;
}
reg_maps->resource_type[reg_idx] = semantic->resource_type;
reg_maps->resource_info[reg_idx].type = semantic->resource_type;
reg_maps->resource_info[reg_idx].data_type = semantic->resource_data_type;
break;
default:
@ -897,17 +898,20 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
|| ins.handler_idx == WINED3DSIH_TEXREG2GB
|| ins.handler_idx == WINED3DSIH_TEXREG2RGB))
{
unsigned int reg_idx = ins.dst[i].reg.idx[0].offset;
TRACE("Setting fake 2D resource for 1.x pixelshader.\n");
reg_maps->resource_type[ins.dst[i].reg.idx[0].offset] = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_FLOAT;
/* texbem is only valid with < 1.4 pixel shaders */
if (ins.handler_idx == WINED3DSIH_TEXBEM
|| ins.handler_idx == WINED3DSIH_TEXBEML)
{
reg_maps->bumpmat |= 1 << ins.dst[i].reg.idx[0].offset;
reg_maps->bumpmat |= 1 << reg_idx;
if (ins.handler_idx == WINED3DSIH_TEXBEML)
{
reg_maps->luminanceparams |= 1 << ins.dst[i].reg.idx[0].offset;
reg_maps->luminanceparams |= 1 << reg_idx;
}
}
}
@ -1063,6 +1067,32 @@ static void shader_dump_decl_usage(const struct wined3d_shader_semantic *semanti
TRACE("unknown");
break;
}
switch (semantic->resource_data_type)
{
case WINED3D_DATA_FLOAT:
TRACE(" (float)");
break;
case WINED3D_DATA_INT:
TRACE(" (int)");
break;
case WINED3D_DATA_UINT:
TRACE(" (uint)");
break;
case WINED3D_DATA_UNORM:
TRACE(" (unorm)");
break;
case WINED3D_DATA_SNORM:
TRACE(" (snorm)");
break;
default:
TRACE(" (unknown)");
break;
}
}
else
{
@ -2179,7 +2209,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
if (!state->shader[WINED3D_SHADER_TYPE_VERTEX])
{
enum wined3d_shader_resource_type resource_type = shader->reg_maps.resource_type[i];
enum wined3d_shader_resource_type resource_type = shader->reg_maps.resource_info[i].type;
unsigned int j;
unsigned int index = state->texture_states[i][WINED3D_TSS_TEXCOORD_INDEX];
DWORD max_valid = WINED3D_TTFF_COUNT4;
@ -2229,7 +2259,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
{
const struct wined3d_texture *texture = state->textures[i];
if (!shader->reg_maps.resource_type[i])
if (!shader->reg_maps.resource_info[i].type)
continue;
/* Treat unbound textures as 2D. The dummy texture will provide
@ -2258,7 +2288,7 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
{
if (!shader->reg_maps.resource_type[i])
if (!shader->reg_maps.resource_info[i].type)
continue;
texture = state->textures[i];
@ -2429,7 +2459,7 @@ static HRESULT pixelshader_init(struct wined3d_shader *shader, struct wined3d_de
void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_types)
{
struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
enum wined3d_shader_resource_type *resource_type = reg_maps->resource_type;
struct wined3d_shader_resource_info *resource_info = reg_maps->resource_info;
unsigned int i;
if (reg_maps->shader_version.major != 1) return;
@ -2437,21 +2467,21 @@ void pixelshader_update_resource_types(struct wined3d_shader *shader, WORD tex_t
for (i = 0; i < shader->limits->sampler; ++i)
{
/* We don't sample from this sampler. */
if (!resource_type[i])
if (!resource_info[i].type)
continue;
switch ((tex_types >> i * WINED3D_PSARGS_TEXTYPE_SHIFT) & WINED3D_PSARGS_TEXTYPE_MASK)
{
case WINED3D_SHADER_TEX_2D:
resource_type[i] = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
break;
case WINED3D_SHADER_TEX_3D:
resource_type[i] = WINED3D_SHADER_RESOURCE_TEXTURE_3D;
resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_3D;
break;
case WINED3D_SHADER_TEX_CUBE:
resource_type[i] = WINED3D_SHADER_RESOURCE_TEXTURE_CUBE;
resource_info[i].type = WINED3D_SHADER_RESOURCE_TEXTURE_CUBE;
break;
}
}

View File

@ -646,6 +646,7 @@ static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_se
{
semantic->resource_type = resource_type_table[resource_type];
}
semantic->resource_data_type = WINED3D_DATA_FLOAT;
shader_parse_dst_param(dst_token, NULL, &semantic->reg);
}

View File

@ -185,6 +185,15 @@ enum wined3d_sm4_resource_type
WINED3D_SM4_RESOURCE_TEXTURE_2DMSARRAY = 0x9,
};
enum wined3d_sm4_data_type
{
WINED3D_SM4_DATA_UNORM = 0x1,
WINED3D_SM4_DATA_SNORM = 0x2,
WINED3D_SM4_DATA_INT = 0x3,
WINED3D_SM4_DATA_UINT = 0x4,
WINED3D_SM4_DATA_FLOAT = 0x5,
};
struct wined3d_shader_src_param_entry
{
struct list entry;
@ -356,6 +365,16 @@ static const enum wined3d_shader_resource_type resource_type_table[] =
/* WINED3D_SM4_RESOURCE_TEXTURE_2DMSARRAY */ WINED3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY,
};
static const enum wined3d_data_type data_type_table[] =
{
/* 0 */ WINED3D_DATA_FLOAT,
/* WINED3D_SM4_DATA_UNORM */ WINED3D_DATA_UNORM,
/* WINED3D_SM4_DATA_SNORM */ WINED3D_DATA_SNORM,
/* WINED3D_SM4_DATA_INT */ WINED3D_DATA_INT,
/* WINED3D_SM4_DATA_UINT */ WINED3D_DATA_UINT,
/* WINED3D_SM4_DATA_FLOAT */ WINED3D_DATA_FLOAT,
};
static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr,
enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param);
@ -779,6 +798,8 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi
if (opcode == WINED3D_SM4_OP_DCL_RESOURCE)
{
enum wined3d_sm4_resource_type resource_type;
enum wined3d_sm4_data_type data_type;
DWORD components;
resource_type = (opcode_token & WINED3D_SM4_RESOURCE_TYPE_MASK) >> WINED3D_SM4_RESOURCE_TYPE_SHIFT;
if (!resource_type || (resource_type >= ARRAY_SIZE(resource_type_table)))
@ -791,6 +812,21 @@ static void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct wi
ins->declaration.semantic.resource_type = resource_type_table[resource_type];
}
shader_sm4_read_dst_param(priv, &p, WINED3D_DATA_RESOURCE, &ins->declaration.semantic.reg);
components = *p++;
if ((components & 0xfff0) != (components & 0xf) * 0x1110)
FIXME("Components (%#x) have different data types.\n", components);
data_type = components & 0xf;
if (!data_type || (data_type >= ARRAY_SIZE(data_type_table)))
{
FIXME("Unhandled data type %#x.\n", data_type);
ins->declaration.semantic.resource_data_type = WINED3D_DATA_FLOAT;
}
else
{
ins->declaration.semantic.resource_data_type = data_type_table[data_type];
}
}
else if (opcode == WINED3D_SM4_OP_DCL_CONSTANT_BUFFER)
{

View File

@ -347,6 +347,8 @@ enum wined3d_data_type
WINED3D_DATA_RESOURCE,
WINED3D_DATA_SAMPLER,
WINED3D_DATA_UINT,
WINED3D_DATA_UNORM,
WINED3D_DATA_SNORM,
};
enum wined3d_immconst_type
@ -574,6 +576,12 @@ struct wined3d_shader_version
BYTE minor;
};
struct wined3d_shader_resource_info
{
enum wined3d_shader_resource_type type;
enum wined3d_data_type data_type;
};
#define WINED3D_SHADER_VERSION(major, minor) (((major) << 8) | (minor))
struct wined3d_shader_reg_maps
@ -593,7 +601,7 @@ struct wined3d_shader_reg_maps
WORD local_bool_consts; /* MAX_CONST_B, 16 */
UINT cb_sizes[WINED3D_MAX_CBS];
enum wined3d_shader_resource_type resource_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
struct wined3d_shader_resource_info resource_info[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
BYTE bumpmat; /* MAX_TEXTURES, 8 */
BYTE luminanceparams; /* MAX_TEXTURES, 8 */
@ -679,6 +687,7 @@ struct wined3d_shader_semantic
enum wined3d_decl_usage usage;
UINT usage_idx;
enum wined3d_shader_resource_type resource_type;
enum wined3d_data_type resource_data_type;
struct wined3d_shader_dst_param reg;
};