mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/tpf: Introduce struct extern_resource.
This struct is required for handling both whole-variable resources for SM < 5 and single-component resources for SM 5 in the same way, when writting the RDEF block and resource declarations within the shader.
This commit is contained in:
parent
ae6bc398d6
commit
8f8c7a02ee
Notes:
Alexandre Julliard
2023-07-17 23:25:21 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Zebediah Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/209
@ -2970,27 +2970,48 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ
|
||||
}
|
||||
}
|
||||
|
||||
struct extern_resource
|
||||
{
|
||||
/* var is only not NULL if this resource is a whole variable, so it may be responsible for more
|
||||
* than one component. */
|
||||
const struct hlsl_ir_var *var;
|
||||
|
||||
char *name;
|
||||
struct hlsl_type *data_type;
|
||||
bool is_user_packed;
|
||||
|
||||
enum hlsl_regset regset;
|
||||
unsigned int id, bind_count;
|
||||
};
|
||||
|
||||
static int sm4_compare_extern_resources(const void *a, const void *b)
|
||||
{
|
||||
const struct hlsl_ir_var *aa = *(const struct hlsl_ir_var **)a;
|
||||
const struct hlsl_ir_var *bb = *(const struct hlsl_ir_var **)b;
|
||||
enum hlsl_regset aa_regset, bb_regset;
|
||||
const struct extern_resource *aa = (const struct extern_resource *)a;
|
||||
const struct extern_resource *bb = (const struct extern_resource *)b;
|
||||
int r;
|
||||
|
||||
aa_regset = hlsl_type_get_regset(aa->data_type);
|
||||
bb_regset = hlsl_type_get_regset(bb->data_type);
|
||||
if ((r = vkd3d_u32_compare(aa->regset, bb->regset)))
|
||||
return r;
|
||||
|
||||
if (aa_regset != bb_regset)
|
||||
return aa_regset - bb_regset;
|
||||
|
||||
return aa->regs[aa_regset].id - bb->regs[bb_regset].id;
|
||||
return vkd3d_u32_compare(aa->id, bb->id);
|
||||
}
|
||||
|
||||
static const struct hlsl_ir_var **sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count)
|
||||
static void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count)
|
||||
{
|
||||
const struct hlsl_ir_var **extern_resources = NULL;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
vkd3d_free(extern_resources[i].name);
|
||||
vkd3d_free(extern_resources);
|
||||
}
|
||||
|
||||
static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count)
|
||||
{
|
||||
struct extern_resource *extern_resources = NULL;
|
||||
const struct hlsl_ir_var *var;
|
||||
enum hlsl_regset regset;
|
||||
size_t capacity = 0;
|
||||
char *name;
|
||||
|
||||
*count = 0;
|
||||
|
||||
@ -3005,11 +3026,29 @@ static const struct hlsl_ir_var **sm4_get_extern_resources(struct hlsl_ctx *ctx,
|
||||
if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1,
|
||||
sizeof(*extern_resources))))
|
||||
{
|
||||
sm4_free_extern_resources(extern_resources, *count);
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern_resources[*count] = var;
|
||||
if (!(name = hlsl_strdup(ctx, var->name)))
|
||||
{
|
||||
sm4_free_extern_resources(extern_resources, *count);
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern_resources[*count].var = var;
|
||||
|
||||
extern_resources[*count].name = name;
|
||||
extern_resources[*count].data_type = var->data_type;
|
||||
extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type;
|
||||
|
||||
extern_resources[*count].regset = regset;
|
||||
extern_resources[*count].id = var->regs[regset].id;
|
||||
extern_resources[*count].bind_count = var->regs[regset].bind_count;
|
||||
|
||||
|
||||
++*count;
|
||||
}
|
||||
|
||||
@ -3023,8 +3062,8 @@ 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;
|
||||
const struct hlsl_profile_info *profile = ctx->profile;
|
||||
const struct hlsl_ir_var **extern_resources;
|
||||
struct vkd3d_bytecode_buffer buffer = {0};
|
||||
struct extern_resource *extern_resources;
|
||||
const struct hlsl_buffer *cbuffer;
|
||||
const struct hlsl_ir_var *var;
|
||||
|
||||
@ -3078,18 +3117,15 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
|
||||
|
||||
for (i = 0; i < extern_resources_count; ++i)
|
||||
{
|
||||
enum hlsl_regset regset;
|
||||
const struct extern_resource *resource = &extern_resources[i];
|
||||
uint32_t flags = 0;
|
||||
|
||||
var = extern_resources[i];
|
||||
regset = hlsl_type_get_regset(var->data_type);
|
||||
|
||||
if (var->reg_reservation.reg_type)
|
||||
if (resource->is_user_packed)
|
||||
flags |= D3D_SIF_USERPACKED;
|
||||
|
||||
put_u32(&buffer, 0); /* name */
|
||||
put_u32(&buffer, sm4_resource_type(var->data_type));
|
||||
if (regset == HLSL_REGSET_SAMPLERS)
|
||||
put_u32(&buffer, sm4_resource_type(resource->data_type));
|
||||
if (resource->regset == HLSL_REGSET_SAMPLERS)
|
||||
{
|
||||
put_u32(&buffer, 0);
|
||||
put_u32(&buffer, 0);
|
||||
@ -3097,15 +3133,15 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int dimx = hlsl_type_get_component_type(ctx, var->data_type, 0)->e.resource_format->dimx;
|
||||
unsigned int dimx = hlsl_type_get_component_type(ctx, resource->data_type, 0)->e.resource_format->dimx;
|
||||
|
||||
put_u32(&buffer, sm4_resource_format(var->data_type));
|
||||
put_u32(&buffer, sm4_rdef_resource_dimension(var->data_type));
|
||||
put_u32(&buffer, sm4_resource_format(resource->data_type));
|
||||
put_u32(&buffer, sm4_rdef_resource_dimension(resource->data_type));
|
||||
put_u32(&buffer, ~0u); /* FIXME: multisample count */
|
||||
flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT;
|
||||
}
|
||||
put_u32(&buffer, var->regs[regset].id);
|
||||
put_u32(&buffer, var->regs[regset].bind_count);
|
||||
put_u32(&buffer, resource->id);
|
||||
put_u32(&buffer, resource->bind_count);
|
||||
put_u32(&buffer, flags);
|
||||
}
|
||||
|
||||
@ -3131,9 +3167,9 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
|
||||
|
||||
for (i = 0; i < extern_resources_count; ++i)
|
||||
{
|
||||
var = extern_resources[i];
|
||||
const struct extern_resource *resource = &extern_resources[i];
|
||||
|
||||
string_offset = put_string(&buffer, var->name);
|
||||
string_offset = put_string(&buffer, resource->name);
|
||||
set_u32(&buffer, resources_offset + i * 8 * sizeof(uint32_t), string_offset);
|
||||
}
|
||||
|
||||
@ -3239,7 +3275,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
|
||||
|
||||
add_section(dxbc, TAG_RDEF, &buffer);
|
||||
|
||||
vkd3d_free(extern_resources);
|
||||
sm4_free_extern_resources(extern_resources, extern_resources_count);
|
||||
}
|
||||
|
||||
static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_type *type)
|
||||
@ -3693,9 +3729,11 @@ static void write_sm4_dcl_constant_buffer(struct vkd3d_bytecode_buffer *buffer,
|
||||
write_sm4_instruction(buffer, &instr);
|
||||
}
|
||||
|
||||
static void write_sm4_dcl_samplers(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var)
|
||||
static void write_sm4_dcl_samplers(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
|
||||
const struct extern_resource *resource)
|
||||
{
|
||||
unsigned int i, count = var->data_type->reg_size[HLSL_REGSET_SAMPLERS];
|
||||
struct hlsl_type *component_type;
|
||||
unsigned int i;
|
||||
struct sm4_instruction instr =
|
||||
{
|
||||
.opcode = VKD3D_SM4_OP_DCL_SAMPLER,
|
||||
@ -3705,38 +3743,44 @@ static void write_sm4_dcl_samplers(struct vkd3d_bytecode_buffer *buffer, const s
|
||||
.dst_count = 1,
|
||||
};
|
||||
|
||||
if (var->data_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON)
|
||||
component_type = hlsl_type_get_component_type(ctx, resource->data_type, 0);
|
||||
|
||||
if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON)
|
||||
instr.opcode |= VKD3D_SM4_SAMPLER_COMPARISON << VKD3D_SM4_SAMPLER_MODE_SHIFT;
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
assert(resource->regset == HLSL_REGSET_SAMPLERS);
|
||||
|
||||
for (i = 0; i < resource->bind_count; ++i)
|
||||
{
|
||||
if (!var->objects_usage[HLSL_REGSET_SAMPLERS][i].used)
|
||||
if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used)
|
||||
continue;
|
||||
|
||||
instr.dsts[0].reg.idx[0] = var->regs[HLSL_REGSET_SAMPLERS].id + i;
|
||||
instr.dsts[0].reg.idx[0] = resource->id + i;
|
||||
write_sm4_instruction(buffer, &instr);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
|
||||
const struct hlsl_ir_var *var, bool uav)
|
||||
const struct extern_resource *resource, bool uav)
|
||||
{
|
||||
enum hlsl_regset regset = uav ? HLSL_REGSET_UAVS : HLSL_REGSET_TEXTURES;
|
||||
unsigned int i, count = var->data_type->reg_size[regset];
|
||||
struct hlsl_type *component_type;
|
||||
struct sm4_instruction instr;
|
||||
unsigned int i;
|
||||
|
||||
component_type = hlsl_type_get_component_type(ctx, var->data_type, 0);
|
||||
assert(resource->regset == regset);
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
component_type = hlsl_type_get_component_type(ctx, resource->data_type, 0);
|
||||
|
||||
for (i = 0; i < resource->bind_count; ++i)
|
||||
{
|
||||
if (!var->objects_usage[regset][i].used)
|
||||
if (resource->var && !resource->var->objects_usage[regset][i].used)
|
||||
continue;
|
||||
|
||||
instr = (struct sm4_instruction)
|
||||
{
|
||||
.dsts[0].reg.type = uav ? VKD3D_SM5_RT_UAV : VKD3D_SM4_RT_RESOURCE,
|
||||
.dsts[0].reg.idx = {var->regs[regset].id + i},
|
||||
.dsts[0].reg.idx = {resource->id + i},
|
||||
.dsts[0].reg.idx_count = 1,
|
||||
.dst_count = 1,
|
||||
|
||||
@ -3746,11 +3790,11 @@ static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b
|
||||
|
||||
if (uav)
|
||||
{
|
||||
switch (var->data_type->sampler_dim)
|
||||
switch (resource->data_type->sampler_dim)
|
||||
{
|
||||
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
|
||||
instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED;
|
||||
instr.byte_stride = var->data_type->e.resource_format->reg_size[HLSL_REGSET_NUMERIC] * 4;
|
||||
instr.byte_stride = resource->data_type->e.resource_format->reg_size[HLSL_REGSET_NUMERIC] * 4;
|
||||
break;
|
||||
default:
|
||||
instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED;
|
||||
@ -5160,8 +5204,8 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx,
|
||||
const struct hlsl_ir_function_decl *entry_func, struct dxbc_writer *dxbc)
|
||||
{
|
||||
const struct hlsl_profile_info *profile = ctx->profile;
|
||||
const struct hlsl_ir_var **extern_resources;
|
||||
struct vkd3d_bytecode_buffer buffer = {0};
|
||||
struct extern_resource *extern_resources;
|
||||
unsigned int extern_resources_count, i;
|
||||
const struct hlsl_buffer *cbuffer;
|
||||
const struct hlsl_ir_var *var;
|
||||
@ -5193,17 +5237,14 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx,
|
||||
|
||||
for (i = 0; i < extern_resources_count; ++i)
|
||||
{
|
||||
enum hlsl_regset regset;
|
||||
const struct extern_resource *resource = &extern_resources[i];
|
||||
|
||||
var = extern_resources[i];
|
||||
regset = hlsl_type_get_regset(var->data_type);
|
||||
|
||||
if (regset == HLSL_REGSET_SAMPLERS)
|
||||
write_sm4_dcl_samplers(&buffer, var);
|
||||
else if (regset == HLSL_REGSET_TEXTURES)
|
||||
write_sm4_dcl_textures(ctx, &buffer, var, false);
|
||||
else if (regset == HLSL_REGSET_UAVS)
|
||||
write_sm4_dcl_textures(ctx, &buffer, var, true);
|
||||
if (resource->regset == HLSL_REGSET_SAMPLERS)
|
||||
write_sm4_dcl_samplers(ctx, &buffer, resource);
|
||||
else if (resource->regset == HLSL_REGSET_TEXTURES)
|
||||
write_sm4_dcl_textures(ctx, &buffer, resource, false);
|
||||
else if (resource->regset == HLSL_REGSET_UAVS)
|
||||
write_sm4_dcl_textures(ctx, &buffer, resource, true);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
@ -5226,7 +5267,7 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx,
|
||||
|
||||
add_section(dxbc, TAG_SHDR, &buffer);
|
||||
|
||||
vkd3d_free(extern_resources);
|
||||
sm4_free_extern_resources(extern_resources, extern_resources_count);
|
||||
}
|
||||
|
||||
int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out)
|
||||
|
Loading…
Reference in New Issue
Block a user