mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-12-15 08:03:30 -08:00
vkd3d-shader/d3dbc: Create vsir descriptor information in the parser.
This commit is contained in:
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
@@ -248,6 +248,8 @@ struct vkd3d_shader_sm1_parser
|
||||
struct vkd3d_shader_parser p;
|
||||
struct vsir_program *program;
|
||||
|
||||
uint16_t texture_descriptors;
|
||||
|
||||
struct
|
||||
{
|
||||
#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);
|
||||
}
|
||||
|
||||
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
|
||||
* addressing token. */
|
||||
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;
|
||||
|
||||
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,
|
||||
@@ -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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (program->shader_version.major == 1)
|
||||
d3dbc_update_descriptors(sm1, ins);
|
||||
|
||||
shader_sm1_validate_instruction(sm1, ins);
|
||||
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_sm1_parser sm1 = {0};
|
||||
struct vkd3d_shader_descriptor_info1 *d;
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
unsigned int i;
|
||||
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)
|
||||
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)
|
||||
ret = sm1.p.status;
|
||||
|
||||
@@ -747,6 +747,38 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature,
|
||||
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)
|
||||
{
|
||||
static const char components[] = {'x', 'y', 'z', 'w'};
|
||||
|
||||
@@ -1729,6 +1729,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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};
|
||||
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)
|
||||
for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
|
||||
{
|
||||
if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
|
||||
®, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32)))
|
||||
d->buffer_size = size * 16;
|
||||
struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = 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,
|
||||
®, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32)))
|
||||
d->buffer_size = size * 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1589,6 +1589,7 @@ struct vsir_program
|
||||
|
||||
struct vkd3d_shader_scan_descriptor_info1 descriptors;
|
||||
bool has_descriptor_info;
|
||||
size_t descriptors_size;
|
||||
|
||||
unsigned int parameter_count;
|
||||
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,
|
||||
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);
|
||||
void vsir_program_cleanup(struct vsir_program *program);
|
||||
const struct vkd3d_shader_parameter1 *vsir_program_get_parameter(
|
||||
|
||||
Reference in New Issue
Block a user