mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07: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)
|
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 extern_resource *aa = (const struct extern_resource *)a;
|
||||||
const struct hlsl_ir_var *bb = *(const struct hlsl_ir_var **)b;
|
const struct extern_resource *bb = (const struct extern_resource *)b;
|
||||||
enum hlsl_regset aa_regset, bb_regset;
|
int r;
|
||||||
|
|
||||||
aa_regset = hlsl_type_get_regset(aa->data_type);
|
if ((r = vkd3d_u32_compare(aa->regset, bb->regset)))
|
||||||
bb_regset = hlsl_type_get_regset(bb->data_type);
|
return r;
|
||||||
|
|
||||||
if (aa_regset != bb_regset)
|
return vkd3d_u32_compare(aa->id, bb->id);
|
||||||
return aa_regset - bb_regset;
|
|
||||||
|
|
||||||
return aa->regs[aa_regset].id - bb->regs[bb_regset].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;
|
const struct hlsl_ir_var *var;
|
||||||
enum hlsl_regset regset;
|
enum hlsl_regset regset;
|
||||||
size_t capacity = 0;
|
size_t capacity = 0;
|
||||||
|
char *name;
|
||||||
|
|
||||||
*count = 0;
|
*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,
|
if (!(hlsl_array_reserve(ctx, (void **)&extern_resources, &capacity, *count + 1,
|
||||||
sizeof(*extern_resources))))
|
sizeof(*extern_resources))))
|
||||||
{
|
{
|
||||||
|
sm4_free_extern_resources(extern_resources, *count);
|
||||||
*count = 0;
|
*count = 0;
|
||||||
return NULL;
|
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;
|
++*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 cbuffers_offset, resources_offset, creator_offset, string_offset;
|
||||||
size_t cbuffer_position, resource_position, creator_position;
|
size_t cbuffer_position, resource_position, creator_position;
|
||||||
const struct hlsl_profile_info *profile = ctx->profile;
|
const struct hlsl_profile_info *profile = ctx->profile;
|
||||||
const struct hlsl_ir_var **extern_resources;
|
|
||||||
struct vkd3d_bytecode_buffer buffer = {0};
|
struct vkd3d_bytecode_buffer buffer = {0};
|
||||||
|
struct extern_resource *extern_resources;
|
||||||
const struct hlsl_buffer *cbuffer;
|
const struct hlsl_buffer *cbuffer;
|
||||||
const struct hlsl_ir_var *var;
|
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)
|
for (i = 0; i < extern_resources_count; ++i)
|
||||||
{
|
{
|
||||||
enum hlsl_regset regset;
|
const struct extern_resource *resource = &extern_resources[i];
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
|
|
||||||
var = extern_resources[i];
|
if (resource->is_user_packed)
|
||||||
regset = hlsl_type_get_regset(var->data_type);
|
|
||||||
|
|
||||||
if (var->reg_reservation.reg_type)
|
|
||||||
flags |= D3D_SIF_USERPACKED;
|
flags |= D3D_SIF_USERPACKED;
|
||||||
|
|
||||||
put_u32(&buffer, 0); /* name */
|
put_u32(&buffer, 0); /* name */
|
||||||
put_u32(&buffer, sm4_resource_type(var->data_type));
|
put_u32(&buffer, sm4_resource_type(resource->data_type));
|
||||||
if (regset == HLSL_REGSET_SAMPLERS)
|
if (resource->regset == HLSL_REGSET_SAMPLERS)
|
||||||
{
|
{
|
||||||
put_u32(&buffer, 0);
|
put_u32(&buffer, 0);
|
||||||
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
|
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_resource_format(resource->data_type));
|
||||||
put_u32(&buffer, sm4_rdef_resource_dimension(var->data_type));
|
put_u32(&buffer, sm4_rdef_resource_dimension(resource->data_type));
|
||||||
put_u32(&buffer, ~0u); /* FIXME: multisample count */
|
put_u32(&buffer, ~0u); /* FIXME: multisample count */
|
||||||
flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT;
|
flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT;
|
||||||
}
|
}
|
||||||
put_u32(&buffer, var->regs[regset].id);
|
put_u32(&buffer, resource->id);
|
||||||
put_u32(&buffer, var->regs[regset].bind_count);
|
put_u32(&buffer, resource->bind_count);
|
||||||
put_u32(&buffer, flags);
|
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)
|
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);
|
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);
|
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)
|
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);
|
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 =
|
struct sm4_instruction instr =
|
||||||
{
|
{
|
||||||
.opcode = VKD3D_SM4_OP_DCL_SAMPLER,
|
.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,
|
.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;
|
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;
|
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);
|
write_sm4_instruction(buffer, &instr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
|
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;
|
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 hlsl_type *component_type;
|
||||||
struct sm4_instruction instr;
|
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;
|
continue;
|
||||||
|
|
||||||
instr = (struct sm4_instruction)
|
instr = (struct sm4_instruction)
|
||||||
{
|
{
|
||||||
.dsts[0].reg.type = uav ? VKD3D_SM5_RT_UAV : VKD3D_SM4_RT_RESOURCE,
|
.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,
|
.dsts[0].reg.idx_count = 1,
|
||||||
.dst_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)
|
if (uav)
|
||||||
{
|
{
|
||||||
switch (var->data_type->sampler_dim)
|
switch (resource->data_type->sampler_dim)
|
||||||
{
|
{
|
||||||
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
|
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
|
||||||
instr.opcode = VKD3D_SM5_OP_DCL_UAV_STRUCTURED;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED;
|
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_ir_function_decl *entry_func, struct dxbc_writer *dxbc)
|
||||||
{
|
{
|
||||||
const struct hlsl_profile_info *profile = ctx->profile;
|
const struct hlsl_profile_info *profile = ctx->profile;
|
||||||
const struct hlsl_ir_var **extern_resources;
|
|
||||||
struct vkd3d_bytecode_buffer buffer = {0};
|
struct vkd3d_bytecode_buffer buffer = {0};
|
||||||
|
struct extern_resource *extern_resources;
|
||||||
unsigned int extern_resources_count, i;
|
unsigned int extern_resources_count, i;
|
||||||
const struct hlsl_buffer *cbuffer;
|
const struct hlsl_buffer *cbuffer;
|
||||||
const struct hlsl_ir_var *var;
|
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)
|
for (i = 0; i < extern_resources_count; ++i)
|
||||||
{
|
{
|
||||||
enum hlsl_regset regset;
|
const struct extern_resource *resource = &extern_resources[i];
|
||||||
|
|
||||||
var = extern_resources[i];
|
if (resource->regset == HLSL_REGSET_SAMPLERS)
|
||||||
regset = hlsl_type_get_regset(var->data_type);
|
write_sm4_dcl_samplers(ctx, &buffer, resource);
|
||||||
|
else if (resource->regset == HLSL_REGSET_TEXTURES)
|
||||||
if (regset == HLSL_REGSET_SAMPLERS)
|
write_sm4_dcl_textures(ctx, &buffer, resource, false);
|
||||||
write_sm4_dcl_samplers(&buffer, var);
|
else if (resource->regset == HLSL_REGSET_UAVS)
|
||||||
else if (regset == HLSL_REGSET_TEXTURES)
|
write_sm4_dcl_textures(ctx, &buffer, resource, true);
|
||||||
write_sm4_dcl_textures(ctx, &buffer, var, false);
|
|
||||||
else if (regset == HLSL_REGSET_UAVS)
|
|
||||||
write_sm4_dcl_textures(ctx, &buffer, var, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
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);
|
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)
|
int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user