vkd3d-shader/d3dbc: Create vsir descriptor information in the parser.

This commit is contained in:
Elizabeth Figura
2025-10-09 14:52:30 -05:00
committed by Henri Verbeet
parent 781bb10ed0
commit 8d8132b2c7
Notes: Henri Verbeet 2025-10-13 19:31:51 +02:00
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1769
4 changed files with 129 additions and 11 deletions

View File

@@ -248,6 +248,8 @@ struct vkd3d_shader_sm1_parser
struct vkd3d_shader_parser p; struct vkd3d_shader_parser p;
struct vsir_program *program; struct vsir_program *program;
uint16_t texture_descriptors;
struct struct
{ {
#define MAX_CONSTANT_COUNT 8192 #define MAX_CONSTANT_COUNT 8192
@@ -938,6 +940,23 @@ static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1,
add_signature_element_from_register(sm1, reg, false, mask, 0); add_signature_element_from_register(sm1, reg, false, mask, 0);
} }
static void d3dbc_add_combined_sampler_descriptor(struct vkd3d_shader_sm1_parser *d3dbc,
unsigned int sampler_idx, enum vkd3d_shader_resource_type resource_type)
{
struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx};
struct vsir_program *program = d3dbc->program;
if (!vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV,
sampler_idx, &range, resource_type, VSIR_DATA_F32))
vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Failed to create SRV descriptor for combined sampler %u.", sampler_idx);
if (!vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER,
sampler_idx, &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))
vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Failed to create sampler descriptor for combined sampler %u.", sampler_idx);
}
/* Read a parameter token from the input stream, and possibly a relative /* Read a parameter token from the input stream, and possibly a relative
* addressing token. */ * addressing token. */
static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1, static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1,
@@ -1102,6 +1121,11 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1,
range->first = range->last = semantic->resource.reg.reg.idx[0].offset; range->first = range->last = semantic->resource.reg.reg.idx[0].offset;
add_signature_element_from_semantic(sm1, semantic); add_signature_element_from_semantic(sm1, semantic);
if (semantic->resource_type)
{
d3dbc_add_combined_sampler_descriptor(sm1, range->first, semantic->resource_type);
sm1->texture_descriptors |= (1u << range->first);
}
} }
static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
@@ -1196,6 +1220,38 @@ static void shader_sm1_read_comment(struct vkd3d_shader_sm1_parser *sm1)
} }
} }
static void d3dbc_update_descriptors(struct vkd3d_shader_sm1_parser *d3dbc,
const struct vkd3d_shader_instruction *ins)
{
unsigned int sampler_idx;
switch (ins->opcode)
{
case VSIR_OP_TEX:
case VSIR_OP_TEXBEM:
case VSIR_OP_TEXBEML:
case VSIR_OP_TEXDP3TEX:
case VSIR_OP_TEXLD:
case VSIR_OP_TEXM3x2TEX:
case VSIR_OP_TEXM3x3SPEC:
case VSIR_OP_TEXM3x3TEX:
case VSIR_OP_TEXM3x3VSPEC:
case VSIR_OP_TEXREG2AR:
case VSIR_OP_TEXREG2GB:
case VSIR_OP_TEXREG2RGB:
sampler_idx = ins->dst[0].reg.idx[0].offset;
if ((d3dbc->texture_descriptors & (1u << sampler_idx)))
break;
d3dbc_add_combined_sampler_descriptor(d3dbc, sampler_idx, VKD3D_SHADER_RESOURCE_TEXTURE_2D);
d3dbc->texture_descriptors |= (1u << sampler_idx);
break;
default:
break;
}
}
static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins) static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins)
{ {
if ((ins->opcode == VSIR_OP_BREAKP || ins->opcode == VSIR_OP_IF) && ins->flags) if ((ins->opcode == VSIR_OP_BREAKP || ins->opcode == VSIR_OP_IF) && ins->flags)
@@ -1360,6 +1416,9 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
goto fail; goto fail;
} }
if (program->shader_version.major == 1)
d3dbc_update_descriptors(sm1, ins);
shader_sm1_validate_instruction(sm1, ins); shader_sm1_validate_instruction(sm1, ins);
return; return;
@@ -1478,6 +1537,7 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c
struct vkd3d_shader_message_context *message_context, struct vsir_program *program) struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
{ {
struct vkd3d_shader_sm1_parser sm1 = {0}; struct vkd3d_shader_sm1_parser sm1 = {0};
struct vkd3d_shader_descriptor_info1 *d;
struct vkd3d_shader_instruction *ins; struct vkd3d_shader_instruction *ins;
unsigned int i; unsigned int i;
int ret; int ret;
@@ -1507,7 +1567,22 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c
} }
for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
program->flat_constant_count[i] = get_external_constant_count(&sm1, i); {
struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i};
unsigned int size = get_external_constant_count(&sm1, i);
if ((program->flat_constant_count[i] = size))
{
if (!(d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
i, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32)))
vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Failed to create CBV descriptor.");
else
d->buffer_size = size * 16;
}
}
program->has_descriptor_info = true;
if (ret >= 0 && sm1.p.status < 0) if (ret >= 0 && sm1.p.status < 0)
ret = sm1.p.status; ret = sm1.p.status;

View File

@@ -747,6 +747,38 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature,
return false; return false;
} }
struct vkd3d_shader_descriptor_info1 *vsir_program_add_descriptor(struct vsir_program *program,
enum vkd3d_shader_descriptor_type type, unsigned int register_id,
const struct vkd3d_shader_register_range *range,
enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type)
{
struct vkd3d_shader_scan_descriptor_info1 *info = &program->descriptors;
struct vkd3d_shader_descriptor_info1 *d;
if (!info)
return NULL;
if (!vkd3d_array_reserve((void **)&info->descriptors, &program->descriptors_size,
info->descriptor_count + 1, sizeof(*info->descriptors)))
{
ERR("Failed to allocate descriptor info.\n");
return NULL;
}
d = &info->descriptors[info->descriptor_count];
memset(d, 0, sizeof(*d));
d->type = type;
d->register_id = register_id;
d->register_space = range->space;
d->register_index = range->first;
d->resource_type = resource_type;
d->resource_data_type = resource_data_type;
d->count = (range->last == ~0u) ? ~0u : range->last - range->first + 1;
++info->descriptor_count;
return d;
}
const char *debug_vsir_writemask(unsigned int writemask) const char *debug_vsir_writemask(unsigned int writemask)
{ {
static const char components[] = {'x', 'y', 'z', 'w'}; static const char components[] = {'x', 'y', 'z', 'w'};

View File

@@ -1729,6 +1729,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
add_descriptor_info = true; add_descriptor_info = true;
} }
if (program->has_descriptor_info)
add_descriptor_info = false;
tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO); tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO);
thread_group_size_info = vkd3d_find_struct(compile_info->next, SCAN_THREAD_GROUP_SIZE_INFO); thread_group_size_info = vkd3d_find_struct(compile_info->next, SCAN_THREAD_GROUP_SIZE_INFO);
@@ -1747,18 +1750,21 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
break; break;
} }
for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) if (add_descriptor_info)
{ {
struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
struct vkd3d_shader_register reg = {.idx[0].offset = i, .idx_count = 1};
unsigned int size = program->flat_constant_count[i];
struct vkd3d_shader_descriptor_info1 *d;
if (size)
{ {
if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i};
&reg, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) struct vkd3d_shader_register reg = {.idx[0].offset = i, .idx_count = 1};
d->buffer_size = size * 16; unsigned int size = program->flat_constant_count[i];
struct vkd3d_shader_descriptor_info1 *d;
if (size)
{
if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
&reg, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32)))
d->buffer_size = size * 16;
}
} }
} }

View File

@@ -1589,6 +1589,7 @@ struct vsir_program
struct vkd3d_shader_scan_descriptor_info1 descriptors; struct vkd3d_shader_scan_descriptor_info1 descriptors;
bool has_descriptor_info; bool has_descriptor_info;
size_t descriptors_size;
unsigned int parameter_count; unsigned int parameter_count;
const struct vkd3d_shader_parameter1 *parameters; const struct vkd3d_shader_parameter1 *parameters;
@@ -1635,6 +1636,10 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program,
enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program,
struct vkd3d_shader_message_context *message_context); struct vkd3d_shader_message_context *message_context);
struct vkd3d_shader_descriptor_info1 *vsir_program_add_descriptor(struct vsir_program *program,
enum vkd3d_shader_descriptor_type type, unsigned int register_id,
const struct vkd3d_shader_register_range *range,
enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type);
bool vsir_program_add_icb(struct vsir_program *program, struct vkd3d_shader_immediate_constant_buffer *icb); bool vsir_program_add_icb(struct vsir_program *program, struct vkd3d_shader_immediate_constant_buffer *icb);
void vsir_program_cleanup(struct vsir_program *program); void vsir_program_cleanup(struct vsir_program *program);
const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( const struct vkd3d_shader_parameter1 *vsir_program_get_parameter(