Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 63 ++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 00fe76b2f..bf93a03df 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1197,6 +1197,64 @@ static void allocate_buffers(struct hlsl_ctx *ctx) } }
+static const struct hlsl_ir_var *get_reserved_texture(struct hlsl_ctx *ctx, uint32_t index) +{ + const struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry) + { + if (var->has_resource_access && var->reg_reservation.type == 't' && var->reg_reservation.index == index) + return var; + } + return NULL; +} + +static void allocate_textures(struct hlsl_ctx *ctx) +{ + struct hlsl_ir_var *var; + uint32_t index = 0; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->has_resource_access || var->data_type->type != HLSL_CLASS_OBJECT + || var->data_type->base_type != HLSL_TYPE_TEXTURE) + continue; + + if (var->reg_reservation.type == 't') + { + const struct hlsl_ir_var *reserved_texture = get_reserved_texture(ctx, var->reg_reservation.index); + + if (reserved_texture && reserved_texture != var) + { + hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, + "Multiple textures bound to t%u.", var->reg_reservation.index); + hlsl_note(ctx, reserved_texture->loc, VKD3D_SHADER_LOG_ERROR, + "Texture '%s' is already bound to t%u.", reserved_texture->name, + var->reg_reservation.index); + } + + var->reg.id = var->reg_reservation.index; + var->reg.allocated = true; + TRACE("Allocated reserved %s to t%u.\n", var->name, index); + } + else if (!var->reg_reservation.type) + { + while (get_reserved_texture(ctx, index)) + ++index; + + var->reg.id = index; + var->reg.allocated = true; + TRACE("Allocated %s to t%u.\n", var->name, index); + ++index; + } + else + { + hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "Textures must be bound to register type 't'."); + } + } +} + static bool type_is_single_reg(const struct hlsl_type *type) { return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR; @@ -1315,9 +1373,14 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
allocate_temp_registers(ctx, entry_func); if (ctx->profile->major_version < 4) + { allocate_const_registers(ctx, entry_func); + } else + { allocate_buffers(ctx); + allocate_textures(ctx); + } allocate_semantic_registers(ctx);
if (ctx->result)
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index b4fb8f2f7..6efff09f0 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -378,6 +378,46 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } }
+static int sm4_compare_externs(const struct hlsl_ir_var *a, const struct hlsl_ir_var *b) +{ + if (a->data_type->base_type != b->data_type->base_type) + return a->data_type->base_type - b->data_type->base_type; + if (a->reg.allocated && b->reg.allocated) + return a->reg.id - b->reg.id; + return strcmp(a->name, b->name); +} + +static void sm4_sort_extern(struct list *sorted, struct hlsl_ir_var *to_sort) +{ + struct hlsl_ir_var *var; + + list_remove(&to_sort->extern_entry); + + LIST_FOR_EACH_ENTRY(var, sorted, struct hlsl_ir_var, extern_entry) + { + if (sm4_compare_externs(to_sort, var) < 0) + { + list_add_before(&var->extern_entry, &to_sort->extern_entry); + return; + } + } + + list_add_tail(sorted, &to_sort->extern_entry); +} + +static void sm4_sort_externs(struct hlsl_ctx *ctx) +{ + struct list sorted = LIST_INIT(sorted); + struct hlsl_ir_var *var, *next; + + LIST_FOR_EACH_ENTRY_SAFE(var, next, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->data_type->type == HLSL_CLASS_OBJECT) + sm4_sort_extern(&sorted, var); + } + list_move_tail(&ctx->extern_vars, &sorted); +} + static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) { size_t cbuffers_offset, resources_offset, creator_offset, string_offset; @@ -397,6 +437,8 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) 0x4353, /* COMPUTE */ };
+ sm4_sort_externs(ctx); + LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated)
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 12/10/21 04:58, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index b4fb8f2f7..6efff09f0 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -378,6 +378,46 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } }
+static int sm4_compare_externs(const struct hlsl_ir_var *a, const struct hlsl_ir_var *b) +{
- if (a->data_type->base_type != b->data_type->base_type)
return a->data_type->base_type - b->data_type->base_type;
- if (a->reg.allocated && b->reg.allocated)
return a->reg.id - b->reg.id;
- return strcmp(a->name, b->name);
+}
+static void sm4_sort_extern(struct list *sorted, struct hlsl_ir_var *to_sort) +{
- struct hlsl_ir_var *var;
- list_remove(&to_sort->extern_entry);
- LIST_FOR_EACH_ENTRY(var, sorted, struct hlsl_ir_var, extern_entry)
- {
if (sm4_compare_externs(to_sort, var) < 0)
{
list_add_before(&var->extern_entry, &to_sort->extern_entry);
return;
}
- }
- list_add_tail(sorted, &to_sort->extern_entry);
+}
+static void sm4_sort_externs(struct hlsl_ctx *ctx) +{
- struct list sorted = LIST_INIT(sorted);
- struct hlsl_ir_var *var, *next;
- LIST_FOR_EACH_ENTRY_SAFE(var, next, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
- {
if (var->data_type->type == HLSL_CLASS_OBJECT)
sm4_sort_extern(&sorted, var);
- }
- list_move_tail(&ctx->extern_vars, &sorted);
+}
- static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) { size_t cbuffers_offset, resources_offset, creator_offset, string_offset;
@@ -397,6 +437,8 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) 0x4353, /* COMPUTE */ };
- sm4_sort_externs(ctx);
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated)
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- include/vkd3d_d3dcommon.idl | 28 +++++++++ libs/vkd3d-shader/hlsl_sm4.c | 116 +++++++++++++++++++++++++++++++++-- 2 files changed, 140 insertions(+), 4 deletions(-)
diff --git a/include/vkd3d_d3dcommon.idl b/include/vkd3d_d3dcommon.idl index 4859d1450..0e0d4f7ba 100644 --- a/include/vkd3d_d3dcommon.idl +++ b/include/vkd3d_d3dcommon.idl @@ -125,6 +125,18 @@ typedef enum D3D_REGISTER_COMPONENT_TYPE D3D_REGISTER_COMPONENT_FLOAT32, } D3D_REGISTER_COMPONENT_TYPE;
+typedef enum D3D_RESOURCE_RETURN_TYPE +{ + D3D_RETURN_TYPE_UNORM = 1, + D3D_RETURN_TYPE_SNORM, + D3D_RETURN_TYPE_SINT, + D3D_RETURN_TYPE_UINT, + D3D_RETURN_TYPE_FLOAT, + D3D_RETURN_TYPE_MIXED, + D3D_RETURN_TYPE_DOUBLE, + D3D_RETURN_TYPE_CONTINUED, +} D3D_RESOURCE_RETURN_TYPE; + typedef enum _D3D_SHADER_INPUT_FLAGS { D3D_SIF_USERPACKED = 0x01, @@ -152,6 +164,22 @@ typedef enum _D3D_SHADER_INPUT_TYPE D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER, } D3D_SHADER_INPUT_TYPE;
+typedef enum D3D_SRV_DIMENSION +{ + D3D_SRV_DIMENSION_UNKNOWN, + D3D_SRV_DIMENSION_BUFFER, + D3D_SRV_DIMENSION_TEXTURE1D, + D3D_SRV_DIMENSION_TEXTURE1DARRAY, + D3D_SRV_DIMENSION_TEXTURE2D, + D3D_SRV_DIMENSION_TEXTURE2DARRAY, + D3D_SRV_DIMENSION_TEXTURE2DMS, + D3D_SRV_DIMENSION_TEXTURE2DMSARRAY, + D3D_SRV_DIMENSION_TEXTURE3D, + D3D_SRV_DIMENSION_TEXTURECUBE, + D3D_SRV_DIMENSION_TEXTURECUBEARRAY, + D3D_SRV_DIMENSION_BUFFEREX, +} D3D_SRV_DIMENSION; + typedef enum _D3D_SHADER_VARIABLE_CLASS { D3D_SVC_SCALAR, diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 6efff09f0..9b212227f 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -378,6 +378,63 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } }
+static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) +{ + switch (type->base_type) + { + case HLSL_TYPE_SAMPLER: + return D3D_SIT_SAMPLER; + case HLSL_TYPE_TEXTURE: + return D3D_SIT_TEXTURE; + default: + assert(0); + return 0; + } +} + +static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type) +{ + switch (type->e.resource_format->base_type) + { + case HLSL_TYPE_DOUBLE: + return D3D_RETURN_TYPE_DOUBLE; + + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + return D3D_RETURN_TYPE_FLOAT; + + case HLSL_TYPE_INT: + return D3D_RETURN_TYPE_SINT; + break; + + case HLSL_TYPE_BOOL: + case HLSL_TYPE_UINT: + return D3D_RETURN_TYPE_UINT; + + default: + assert(0); + return 0; + } +} + +static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *type) +{ + switch (type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + return D3D_SRV_DIMENSION_TEXTURE1D; + case HLSL_SAMPLER_DIM_2D: + return D3D_SRV_DIMENSION_TEXTURE2D; + case HLSL_SAMPLER_DIM_3D: + return D3D_SRV_DIMENSION_TEXTURE3D; + case HLSL_SAMPLER_DIM_CUBE: + return D3D_SRV_DIMENSION_TEXTURECUBE; + default: + assert(0); + return D3D_SRV_DIMENSION_UNKNOWN; + } +} + static int sm4_compare_externs(const struct hlsl_ir_var *a, const struct hlsl_ir_var *b) { if (a->data_type->base_type != b->data_type->base_type) @@ -422,10 +479,11 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) { size_t cbuffers_offset, resources_offset, creator_offset, string_offset; size_t cbuffer_position, resource_position, creator_position; + unsigned int cbuffer_count = 0, resource_count = 0, i, j; const struct hlsl_profile_info *profile = ctx->profile; struct vkd3d_bytecode_buffer buffer = {0}; - unsigned int cbuffer_count = 0, i, j; const struct hlsl_buffer *cbuffer; + const struct hlsl_ir_var *var;
static const uint16_t target_types[] = { @@ -439,15 +497,24 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
sm4_sort_externs(ctx);
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->reg.allocated && var->data_type->type == HLSL_CLASS_OBJECT) + ++resource_count; + } + LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated) + { ++cbuffer_count; + ++resource_count; + } }
put_u32(&buffer, cbuffer_count); cbuffer_position = put_u32(&buffer, 0); - put_u32(&buffer, cbuffer_count); /* bound resource count */ + put_u32(&buffer, resource_count); resource_position = put_u32(&buffer, 0); put_u32(&buffer, vkd3d_make_u32(vkd3d_make_u16(profile->minor_version, profile->major_version), target_types[profile->type])); @@ -470,6 +537,37 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
resources_offset = bytecode_get_size(&buffer); set_u32(&buffer, resource_position, resources_offset); + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + uint32_t flags = 0; + + if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT) + continue; + + if (var->reg_reservation.type) + flags |= D3D_SIF_USERPACKED; + + put_u32(&buffer, 0); /* name */ + put_u32(&buffer, sm4_resource_type(var->data_type)); + if (var->data_type->base_type == HLSL_TYPE_SAMPLER) + { + put_u32(&buffer, 0); + put_u32(&buffer, 0); + put_u32(&buffer, 0); + } + else + { + put_u32(&buffer, sm4_resource_format(var->data_type)); + put_u32(&buffer, sm4_rdef_resource_dimension(var->data_type)); + put_u32(&buffer, ~0u); /* FIXME: multisample count */ + flags |= (var->data_type->e.resource_format->dimx - 1) << 2; + } + put_u32(&buffer, var->reg.id); + put_u32(&buffer, 1); /* bind count */ + put_u32(&buffer, flags); + } + LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { uint32_t flags = 0; @@ -491,6 +589,16 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) }
i = 0; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT) + continue; + + string_offset = put_string(&buffer, var->name); + set_u32(&buffer, resources_offset + i++ * 8 * sizeof(uint32_t), string_offset); + } + LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (!cbuffer->reg.allocated) @@ -500,13 +608,14 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) set_u32(&buffer, resources_offset + i++ * 8 * sizeof(uint32_t), string_offset); }
+ assert(i == resource_count); + /* Buffers. */
cbuffers_offset = bytecode_get_size(&buffer); set_u32(&buffer, cbuffer_position, cbuffers_offset); LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { - const struct hlsl_ir_var *var; unsigned int var_count = 0;
if (!cbuffer->reg.allocated) @@ -540,7 +649,6 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { size_t vars_start = bytecode_get_size(&buffer); - const struct hlsl_ir_var *var;
if (!cbuffer->reg.allocated) continue;
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 12/10/21 04:58, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
include/vkd3d_d3dcommon.idl | 28 +++++++++ libs/vkd3d-shader/hlsl_sm4.c | 116 +++++++++++++++++++++++++++++++++-- 2 files changed, 140 insertions(+), 4 deletions(-)
diff --git a/include/vkd3d_d3dcommon.idl b/include/vkd3d_d3dcommon.idl index 4859d1450..0e0d4f7ba 100644 --- a/include/vkd3d_d3dcommon.idl +++ b/include/vkd3d_d3dcommon.idl @@ -125,6 +125,18 @@ typedef enum D3D_REGISTER_COMPONENT_TYPE D3D_REGISTER_COMPONENT_FLOAT32, } D3D_REGISTER_COMPONENT_TYPE;
+typedef enum D3D_RESOURCE_RETURN_TYPE +{
- D3D_RETURN_TYPE_UNORM = 1,
- D3D_RETURN_TYPE_SNORM,
- D3D_RETURN_TYPE_SINT,
- D3D_RETURN_TYPE_UINT,
- D3D_RETURN_TYPE_FLOAT,
- D3D_RETURN_TYPE_MIXED,
- D3D_RETURN_TYPE_DOUBLE,
- D3D_RETURN_TYPE_CONTINUED,
+} D3D_RESOURCE_RETURN_TYPE;
- typedef enum _D3D_SHADER_INPUT_FLAGS { D3D_SIF_USERPACKED = 0x01,
@@ -152,6 +164,22 @@ typedef enum _D3D_SHADER_INPUT_TYPE D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER, } D3D_SHADER_INPUT_TYPE;
+typedef enum D3D_SRV_DIMENSION +{
- D3D_SRV_DIMENSION_UNKNOWN,
- D3D_SRV_DIMENSION_BUFFER,
- D3D_SRV_DIMENSION_TEXTURE1D,
- D3D_SRV_DIMENSION_TEXTURE1DARRAY,
- D3D_SRV_DIMENSION_TEXTURE2D,
- D3D_SRV_DIMENSION_TEXTURE2DARRAY,
- D3D_SRV_DIMENSION_TEXTURE2DMS,
- D3D_SRV_DIMENSION_TEXTURE2DMSARRAY,
- D3D_SRV_DIMENSION_TEXTURE3D,
- D3D_SRV_DIMENSION_TEXTURECUBE,
- D3D_SRV_DIMENSION_TEXTURECUBEARRAY,
- D3D_SRV_DIMENSION_BUFFEREX,
+} D3D_SRV_DIMENSION;
- typedef enum _D3D_SHADER_VARIABLE_CLASS { D3D_SVC_SCALAR,
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 6efff09f0..9b212227f 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -378,6 +378,63 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } }
+static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) +{
- switch (type->base_type)
- {
case HLSL_TYPE_SAMPLER:
return D3D_SIT_SAMPLER;
case HLSL_TYPE_TEXTURE:
return D3D_SIT_TEXTURE;
default:
assert(0);
return 0;
- }
+}
+static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type) +{
- switch (type->e.resource_format->base_type)
- {
case HLSL_TYPE_DOUBLE:
return D3D_RETURN_TYPE_DOUBLE;
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
return D3D_RETURN_TYPE_FLOAT;
case HLSL_TYPE_INT:
return D3D_RETURN_TYPE_SINT;
break;
case HLSL_TYPE_BOOL:
case HLSL_TYPE_UINT:
return D3D_RETURN_TYPE_UINT;
default:
assert(0);
return 0;
- }
+}
+static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *type) +{
- switch (type->sampler_dim)
- {
case HLSL_SAMPLER_DIM_1D:
return D3D_SRV_DIMENSION_TEXTURE1D;
case HLSL_SAMPLER_DIM_2D:
return D3D_SRV_DIMENSION_TEXTURE2D;
case HLSL_SAMPLER_DIM_3D:
return D3D_SRV_DIMENSION_TEXTURE3D;
case HLSL_SAMPLER_DIM_CUBE:
return D3D_SRV_DIMENSION_TEXTURECUBE;
default:
assert(0);
return D3D_SRV_DIMENSION_UNKNOWN;
- }
+}
- static int sm4_compare_externs(const struct hlsl_ir_var *a, const struct hlsl_ir_var *b) { if (a->data_type->base_type != b->data_type->base_type)
@@ -422,10 +479,11 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) { size_t cbuffers_offset, resources_offset, creator_offset, string_offset; size_t cbuffer_position, resource_position, creator_position;
- unsigned int cbuffer_count = 0, resource_count = 0, i, j; const struct hlsl_profile_info *profile = ctx->profile; struct vkd3d_bytecode_buffer buffer = {0};
- unsigned int cbuffer_count = 0, i, j; const struct hlsl_buffer *cbuffer;
const struct hlsl_ir_var *var;
static const uint16_t target_types[] = {
@@ -439,15 +497,24 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
sm4_sort_externs(ctx);
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
if (var->reg.allocated && var->data_type->type == HLSL_CLASS_OBJECT)
++resource_count;
}
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated)
{ ++cbuffer_count;
++resource_count;
} } put_u32(&buffer, cbuffer_count); cbuffer_position = put_u32(&buffer, 0);
- put_u32(&buffer, cbuffer_count); /* bound resource count */
- put_u32(&buffer, resource_count); resource_position = put_u32(&buffer, 0); put_u32(&buffer, vkd3d_make_u32(vkd3d_make_u16(profile->minor_version, profile->major_version), target_types[profile->type]));
@@ -470,6 +537,37 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
resources_offset = bytecode_get_size(&buffer); set_u32(&buffer, resource_position, resources_offset);
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
- {
uint32_t flags = 0;
if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT)
continue;
if (var->reg_reservation.type)
flags |= D3D_SIF_USERPACKED;
put_u32(&buffer, 0); /* name */
put_u32(&buffer, sm4_resource_type(var->data_type));
if (var->data_type->base_type == HLSL_TYPE_SAMPLER)
{
put_u32(&buffer, 0);
put_u32(&buffer, 0);
put_u32(&buffer, 0);
}
else
{
put_u32(&buffer, sm4_resource_format(var->data_type));
put_u32(&buffer, sm4_rdef_resource_dimension(var->data_type));
put_u32(&buffer, ~0u); /* FIXME: multisample count */
flags |= (var->data_type->e.resource_format->dimx - 1) << 2;
}
put_u32(&buffer, var->reg.id);
put_u32(&buffer, 1); /* bind count */
put_u32(&buffer, flags);
- }
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { uint32_t flags = 0;
@@ -491,6 +589,16 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) }
i = 0;
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
- {
if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT)
continue;
string_offset = put_string(&buffer, var->name);
set_u32(&buffer, resources_offset + i++ * 8 * sizeof(uint32_t), string_offset);
- }
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (!cbuffer->reg.allocated)
@@ -500,13 +608,14 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) set_u32(&buffer, resources_offset + i++ * 8 * sizeof(uint32_t), string_offset); }
assert(i == resource_count);
/* Buffers. */ cbuffers_offset = bytecode_get_size(&buffer); set_u32(&buffer, cbuffer_position, cbuffers_offset); LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) {
const struct hlsl_ir_var *var; unsigned int var_count = 0; if (!cbuffer->reg.allocated)
@@ -540,7 +649,6 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { size_t vars_start = bytecode_get_size(&buffer);
const struct hlsl_ir_var *var; if (!cbuffer->reg.allocated) continue;
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
On Tue, Oct 12, 2021 at 4:59 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
include/vkd3d_d3dcommon.idl | 28 +++++++++ libs/vkd3d-shader/hlsl_sm4.c | 116 +++++++++++++++++++++++++++++++++-- 2 files changed, 140 insertions(+), 4 deletions(-)
I have just a tiny nit for this one.
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 6efff09f0..9b212227f 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c
@@ -470,6 +537,37 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
resources_offset = bytecode_get_size(&buffer); set_u32(&buffer, resource_position, resources_offset);
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
- {
uint32_t flags = 0;
if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT)
continue;
if (var->reg_reservation.type)
flags |= D3D_SIF_USERPACKED;
put_u32(&buffer, 0); /* name */
put_u32(&buffer, sm4_resource_type(var->data_type));
if (var->data_type->base_type == HLSL_TYPE_SAMPLER)
{
put_u32(&buffer, 0);
put_u32(&buffer, 0);
put_u32(&buffer, 0);
}
else
{
put_u32(&buffer, sm4_resource_format(var->data_type));
put_u32(&buffer, sm4_rdef_resource_dimension(var->data_type));
put_u32(&buffer, ~0u); /* FIXME: multisample count */
flags |= (var->data_type->e.resource_format->dimx - 1) << 2;
Ideally we would have a VKD3D_SM4_FLAGS_TEXTURE_DIM_SHIFT define or something instead of a plain 2 here.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 9b212227f..c979e14ac 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -704,6 +704,24 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) dxbc_writer_add_section(dxbc, TAG_RDEF, buffer.data, buffer.size); }
+static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_type *type) +{ + switch (type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + return VKD3D_SM4_RESOURCE_TEXTURE_1D; + case HLSL_SAMPLER_DIM_2D: + return VKD3D_SM4_RESOURCE_TEXTURE_2D; + case HLSL_SAMPLER_DIM_3D: + return VKD3D_SM4_RESOURCE_TEXTURE_3D; + case HLSL_SAMPLER_DIM_CUBE: + return VKD3D_SM4_RESOURCE_TEXTURE_CUBE; + default: + assert(0); + return 0; + } +} + struct sm4_register { enum vkd3d_sm4_register_type type; @@ -941,6 +959,24 @@ static void write_sm4_dcl_constant_buffer(struct vkd3d_bytecode_buffer *buffer, write_sm4_instruction(buffer, &instr); }
+static void write_sm4_dcl_texture(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var) +{ + const struct sm4_instruction instr = + { + .opcode = VKD3D_SM4_OP_DCL_RESOURCE + | (sm4_resource_dimension(var->data_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT), + + .dsts[0].reg.type = VKD3D_SM4_RT_RESOURCE, + .dsts[0].reg.idx = {var->reg.id}, + .dsts[0].reg.idx_count = 1, + .dst_count = 1, + + .idx[0] = sm4_resource_format(var->data_type) * 0x1111, + .idx_count = 1, + }; + write_sm4_instruction(buffer, &instr); +} + static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var) { const struct hlsl_profile_info *profile = ctx->profile; @@ -1418,6 +1454,15 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, write_sm4_dcl_constant_buffer(&buffer, cbuffer); }
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry) + { + if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT) + continue; + + if (var->data_type->base_type == HLSL_TYPE_TEXTURE) + write_sm4_dcl_texture(&buffer, var); + } + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { if ((var->is_input_semantic && var->last_read) || (var->is_output_semantic && var->first_write))
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 12/10/21 04:58, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 9b212227f..c979e14ac 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -704,6 +704,24 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) dxbc_writer_add_section(dxbc, TAG_RDEF, buffer.data, buffer.size); }
+static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_type *type) +{
- switch (type->sampler_dim)
- {
case HLSL_SAMPLER_DIM_1D:
return VKD3D_SM4_RESOURCE_TEXTURE_1D;
case HLSL_SAMPLER_DIM_2D:
return VKD3D_SM4_RESOURCE_TEXTURE_2D;
case HLSL_SAMPLER_DIM_3D:
return VKD3D_SM4_RESOURCE_TEXTURE_3D;
case HLSL_SAMPLER_DIM_CUBE:
return VKD3D_SM4_RESOURCE_TEXTURE_CUBE;
default:
assert(0);
return 0;
- }
+}
- struct sm4_register { enum vkd3d_sm4_register_type type;
@@ -941,6 +959,24 @@ static void write_sm4_dcl_constant_buffer(struct vkd3d_bytecode_buffer *buffer, write_sm4_instruction(buffer, &instr); }
+static void write_sm4_dcl_texture(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var) +{
- const struct sm4_instruction instr =
- {
.opcode = VKD3D_SM4_OP_DCL_RESOURCE
| (sm4_resource_dimension(var->data_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT),
.dsts[0].reg.type = VKD3D_SM4_RT_RESOURCE,
.dsts[0].reg.idx = {var->reg.id},
.dsts[0].reg.idx_count = 1,
.dst_count = 1,
.idx[0] = sm4_resource_format(var->data_type) * 0x1111,
.idx_count = 1,
- };
- write_sm4_instruction(buffer, &instr);
+}
- static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var) { const struct hlsl_profile_info *profile = ctx->profile;
@@ -1418,6 +1454,15 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, write_sm4_dcl_constant_buffer(&buffer, cbuffer); }
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry)
- {
if (!var->reg.allocated || var->data_type->type != HLSL_CLASS_OBJECT)
continue;
if (var->data_type->base_type == HLSL_TYPE_TEXTURE)
write_sm4_dcl_texture(&buffer, var);
- }
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { if ((var->is_input_semantic && var->last_read) || (var->is_output_semantic && var->first_write))
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
These can be assigned to when compatibility mode is used.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index bf93a03df..e041ccd7c 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1310,35 +1310,26 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) { - if (var->data_type->type == HLSL_CLASS_OBJECT) - list_add_tail(&ctx->extern_vars, &var->extern_entry); - else if (var->modifiers & HLSL_STORAGE_UNIFORM) + if (var->modifiers & HLSL_STORAGE_UNIFORM) prepend_uniform_copy(ctx, entry_func->body, var); }
LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry) { - if (var->data_type->type == HLSL_CLASS_OBJECT) + if (var->data_type->type == HLSL_CLASS_OBJECT || (var->modifiers & HLSL_STORAGE_UNIFORM)) { - list_add_tail(&ctx->extern_vars, &var->extern_entry); + prepend_uniform_copy(ctx, entry_func->body, var); } else { - if (var->modifiers & HLSL_STORAGE_UNIFORM) - { - prepend_uniform_copy(ctx, entry_func->body, var); - } - else - { - if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name) - hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, - "Parameter "%s" is missing a semantic.", var->name); - - if (var->modifiers & HLSL_STORAGE_IN) - prepend_input_var_copy(ctx, entry_func->body, var); - if (var->modifiers & HLSL_STORAGE_OUT) - append_output_var_copy(ctx, entry_func->body, var); - } + if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name) + hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + "Parameter "%s" is missing a semantic.", var->name); + + if (var->modifiers & HLSL_STORAGE_IN) + prepend_input_var_copy(ctx, entry_func->body, var); + if (var->modifiers & HLSL_STORAGE_OUT) + append_output_var_copy(ctx, entry_func->body, var); } } if (entry_func->return_var)
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 12/10/21 04:58, Zebediah Figura ha scritto:
These can be assigned to when compatibility mode is used.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_codegen.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index bf93a03df..e041ccd7c 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1310,35 +1310,26 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) {
if (var->data_type->type == HLSL_CLASS_OBJECT)
list_add_tail(&ctx->extern_vars, &var->extern_entry);
else if (var->modifiers & HLSL_STORAGE_UNIFORM)
if (var->modifiers & HLSL_STORAGE_UNIFORM) prepend_uniform_copy(ctx, entry_func->body, var); } LIST_FOR_EACH_ENTRY(var, entry_func->parameters, struct hlsl_ir_var, param_entry) {
if (var->data_type->type == HLSL_CLASS_OBJECT)
if (var->data_type->type == HLSL_CLASS_OBJECT || (var->modifiers & HLSL_STORAGE_UNIFORM)) {
list_add_tail(&ctx->extern_vars, &var->extern_entry);
prepend_uniform_copy(ctx, entry_func->body, var); } else {
if (var->modifiers & HLSL_STORAGE_UNIFORM)
{
prepend_uniform_copy(ctx, entry_func->body, var);
}
else
{
if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name)
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
"Parameter \"%s\" is missing a semantic.", var->name);
if (var->modifiers & HLSL_STORAGE_IN)
prepend_input_var_copy(ctx, entry_func->body, var);
if (var->modifiers & HLSL_STORAGE_OUT)
append_output_var_copy(ctx, entry_func->body, var);
}
if (var->data_type->type != HLSL_CLASS_STRUCT && !var->semantic.name)
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
"Parameter \"%s\" is missing a semantic.", var->name);
if (var->modifiers & HLSL_STORAGE_IN)
prepend_input_var_copy(ctx, entry_func->body, var);
if (var->modifiers & HLSL_STORAGE_OUT)
append_output_var_copy(ctx, entry_func->body, var); } } if (entry_func->return_var)
On Tue, Oct 12, 2021 at 4:59 AM Zebediah Figura zfigura@codeweavers.com wrote:
These can be assigned to when compatibility mode is used.
Yep, pretty annoying if you ask me...
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_codegen.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-)
I'm curious, will this (or, rather, texture loads) work even without some form of copy propagation?
FWIW, this patch breaks register allocation for textures. Basically, has_resource_access never gets set for the "actual" extern variables.
On 10/14/21 3:47 AM, Matteo Bruni wrote:
On Tue, Oct 12, 2021 at 4:59 AM Zebediah Figura zfigura@codeweavers.com wrote:
These can be assigned to when compatibility mode is used.
Yep, pretty annoying if you ask me...
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_codegen.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-)
I'm curious, will this (or, rather, texture loads) work even without some form of copy propagation?
Not as such, but I have a follow-up patch to skip generating synthetic temps if they aren't *actually* assigned to (or, in the case of output variables, read from).
But we should really implement copyprop anyway.
FWIW, this patch breaks register allocation for textures. Basically, has_resource_access never gets set for the "actual" extern variables.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
Il 12/10/21 04:58, Zebediah Figura ha scritto:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_codegen.c | 63 ++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 00fe76b2f..bf93a03df 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1197,6 +1197,64 @@ static void allocate_buffers(struct hlsl_ctx *ctx) } }
+static const struct hlsl_ir_var *get_reserved_texture(struct hlsl_ctx *ctx, uint32_t index) +{
- const struct hlsl_ir_var *var;
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry)
- {
if (var->has_resource_access && var->reg_reservation.type == 't' && var->reg_reservation.index == index)
return var;
- }
- return NULL;
+}
+static void allocate_textures(struct hlsl_ctx *ctx) +{
- struct hlsl_ir_var *var;
- uint32_t index = 0;
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
- {
if (!var->has_resource_access || var->data_type->type != HLSL_CLASS_OBJECT
|| var->data_type->base_type != HLSL_TYPE_TEXTURE)
continue;
if (var->reg_reservation.type == 't')
{
const struct hlsl_ir_var *reserved_texture = get_reserved_texture(ctx, var->reg_reservation.index);
if (reserved_texture && reserved_texture != var)
{
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
"Multiple textures bound to t%u.", var->reg_reservation.index);
hlsl_note(ctx, reserved_texture->loc, VKD3D_SHADER_LOG_ERROR,
"Texture '%s' is already bound to t%u.", reserved_texture->name,
var->reg_reservation.index);
}
var->reg.id = var->reg_reservation.index;
var->reg.allocated = true;
TRACE("Allocated reserved %s to t%u.\n", var->name, index);
}
else if (!var->reg_reservation.type)
{
while (get_reserved_texture(ctx, index))
++index;
var->reg.id = index;
var->reg.allocated = true;
TRACE("Allocated %s to t%u.\n", var->name, index);
++index;
}
else
{
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"Textures must be bound to register type 't'.");
}
- }
+}
- static bool type_is_single_reg(const struct hlsl_type *type) { return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR;
@@ -1315,9 +1373,14 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
allocate_temp_registers(ctx, entry_func); if (ctx->profile->major_version < 4)
{ allocate_const_registers(ctx, entry_func);
} else
{ allocate_buffers(ctx);
allocate_textures(ctx);
} allocate_semantic_registers(ctx);
if (ctx->result)
On Tue, Oct 12, 2021 at 4:59 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_codegen.c | 63 ++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 00fe76b2f..bf93a03df 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1197,6 +1197,64 @@ static void allocate_buffers(struct hlsl_ctx *ctx) } }
+static const struct hlsl_ir_var *get_reserved_texture(struct hlsl_ctx *ctx, uint32_t index) +{
- const struct hlsl_ir_var *var;
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry)
- {
if (var->has_resource_access && var->reg_reservation.type == 't' && var->reg_reservation.index == index)
return var;
- }
- return NULL;
+}
+static void allocate_textures(struct hlsl_ctx *ctx) +{
- struct hlsl_ir_var *var;
- uint32_t index = 0;
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
- {
if (!var->has_resource_access || var->data_type->type != HLSL_CLASS_OBJECT
|| var->data_type->base_type != HLSL_TYPE_TEXTURE)
continue;
if (var->reg_reservation.type == 't')
{
const struct hlsl_ir_var *reserved_texture = get_reserved_texture(ctx, var->reg_reservation.index);
if (reserved_texture && reserved_texture != var)
{
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
"Multiple textures bound to t%u.", var->reg_reservation.index);
hlsl_note(ctx, reserved_texture->loc, VKD3D_SHADER_LOG_ERROR,
"Texture '%s' is already bound to t%u.", reserved_texture->name,
var->reg_reservation.index);
}
var->reg.id = var->reg_reservation.index;
var->reg.allocated = true;
TRACE("Allocated reserved %s to t%u.\n", var->name, index);
}
else if (!var->reg_reservation.type)
{
while (get_reserved_texture(ctx, index))
++index;
var->reg.id = index;
var->reg.allocated = true;
TRACE("Allocated %s to t%u.\n", var->name, index);
++index;
}
else
{
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"Textures must be bound to register type 't'.");
}
- }
+}
The reservation lookup seems... suboptimal. It's not new (it's basically the same as what we do for buffers already) and probably there won't be that many extern variables in the usual cases, so maybe this is not going to be an issue in practice. It does kind of raise a red flag for me though... I guess let's keep this in mind if we ever happen to encounter performance issues.
On 10/14/21 3:45 AM, Matteo Bruni wrote:
On Tue, Oct 12, 2021 at 4:59 AM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_codegen.c | 63 ++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 00fe76b2f..bf93a03df 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1197,6 +1197,64 @@ static void allocate_buffers(struct hlsl_ctx *ctx) } }
+static const struct hlsl_ir_var *get_reserved_texture(struct hlsl_ctx *ctx, uint32_t index) +{
- const struct hlsl_ir_var *var;
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, const struct hlsl_ir_var, extern_entry)
- {
if (var->has_resource_access && var->reg_reservation.type == 't' && var->reg_reservation.index == index)
return var;
- }
- return NULL;
+}
+static void allocate_textures(struct hlsl_ctx *ctx) +{
- struct hlsl_ir_var *var;
- uint32_t index = 0;
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
- {
if (!var->has_resource_access || var->data_type->type != HLSL_CLASS_OBJECT
|| var->data_type->base_type != HLSL_TYPE_TEXTURE)
continue;
if (var->reg_reservation.type == 't')
{
const struct hlsl_ir_var *reserved_texture = get_reserved_texture(ctx, var->reg_reservation.index);
if (reserved_texture && reserved_texture != var)
{
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
"Multiple textures bound to t%u.", var->reg_reservation.index);
hlsl_note(ctx, reserved_texture->loc, VKD3D_SHADER_LOG_ERROR,
"Texture '%s' is already bound to t%u.", reserved_texture->name,
var->reg_reservation.index);
}
var->reg.id = var->reg_reservation.index;
var->reg.allocated = true;
TRACE("Allocated reserved %s to t%u.\n", var->name, index);
}
else if (!var->reg_reservation.type)
{
while (get_reserved_texture(ctx, index))
++index;
var->reg.id = index;
var->reg.allocated = true;
TRACE("Allocated %s to t%u.\n", var->name, index);
++index;
}
else
{
hlsl_error(ctx, var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
"Textures must be bound to register type 't'.");
}
- }
+}
The reservation lookup seems... suboptimal. It's not new (it's basically the same as what we do for buffers already) and probably there won't be that many extern variables in the usual cases, so maybe this is not going to be an issue in practice. It does kind of raise a red flag for me though... I guess let's keep this in mind if we ever happen to encounter performance issues.
I don't like how similar it looks to buffers (and samplers and UAVs), but it's not clear to me how to deduplicate it while not being horribly structured.
I certainly haven't seen shaders with a ton of externs yet.