mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader: Write SM5.1 register indices.
Separate ID and index. Allocate IDs for all external resources (but ignore them for shader models other than 5).
This commit is contained in:
parent
19a13740de
commit
28a5e23814
Notes:
Henri Verbeet
2024-06-11 17:09:29 +02:00
Approved-by: Francisco Casas (@fcasas) Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/865
@ -1739,7 +1739,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe
|
||||
}
|
||||
else
|
||||
{
|
||||
put_u32(buffer, vkd3d_make_u32(D3DXRS_SAMPLER, var->regs[r].id));
|
||||
put_u32(buffer, vkd3d_make_u32(D3DXRS_SAMPLER, var->regs[r].index));
|
||||
put_u32(buffer, var->bind_count[r]);
|
||||
}
|
||||
put_u32(buffer, 0); /* type */
|
||||
@ -2266,7 +2266,7 @@ static void write_sm1_sampler_dcls(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b
|
||||
continue;
|
||||
}
|
||||
|
||||
reg_id = var->regs[HLSL_REGSET_SAMPLERS].id + i;
|
||||
reg_id = var->regs[HLSL_REGSET_SAMPLERS].index + i;
|
||||
write_sm1_sampler_dcl(ctx, buffer, reg_id, sampler_dim);
|
||||
}
|
||||
}
|
||||
@ -2571,7 +2571,7 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_
|
||||
struct sm1_instruction sm1_instr;
|
||||
|
||||
sampler_offset = hlsl_offset_from_deref_safe(ctx, &load->resource);
|
||||
reg_id = load->resource.var->regs[HLSL_REGSET_SAMPLERS].id + sampler_offset;
|
||||
reg_id = load->resource.var->regs[HLSL_REGSET_SAMPLERS].index + sampler_offset;
|
||||
|
||||
sm1_instr = (struct sm1_instruction)
|
||||
{
|
||||
|
@ -259,8 +259,18 @@ struct hlsl_struct_field
|
||||
* struct. */
|
||||
struct hlsl_reg
|
||||
{
|
||||
/* Index of the first register allocated. */
|
||||
/* Register number of the first register allocated. */
|
||||
uint32_t id;
|
||||
/* For descriptors (buffer, texture, sampler, UAV) this is the base binding
|
||||
* index of the descriptor.
|
||||
* For 5.1 and above descriptors have space and may be arrayed, in which
|
||||
* case the array shares a single register ID but has a range of register
|
||||
* indices, and "id" and "index" are as a rule not equal.
|
||||
* For versions below 5.1, the register number for descriptors is the same
|
||||
* as its external binding index, so only "index" is used, and "id" is
|
||||
* ignored.
|
||||
* For numeric registers "index" is not used. */
|
||||
uint32_t index;
|
||||
/* Number of registers to be allocated.
|
||||
* Unlike the variable's type's regsize, it is not expressed in register components, but rather
|
||||
* in whole registers, and may depend on which components are used within the shader. */
|
||||
|
@ -3847,10 +3847,7 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx)
|
||||
else
|
||||
{
|
||||
var->regs[r].allocated = true;
|
||||
var->regs[r].id = var->reg_reservation.reg_index;
|
||||
TRACE("Allocated reserved %s to %c%u-%c%u.\n", var->name, var->reg_reservation.reg_type,
|
||||
var->reg_reservation.reg_index, var->reg_reservation.reg_type,
|
||||
var->reg_reservation.reg_index + var->regs[r].allocation_size);
|
||||
var->regs[r].index = var->reg_reservation.reg_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4924,8 +4921,8 @@ void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx)
|
||||
static void allocate_buffers(struct hlsl_ctx *ctx)
|
||||
{
|
||||
struct hlsl_buffer *buffer;
|
||||
uint32_t index = 0, id = 0;
|
||||
struct hlsl_ir_var *var;
|
||||
uint32_t index = 0;
|
||||
|
||||
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
|
||||
{
|
||||
@ -4953,25 +4950,34 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
|
||||
if (reserved_buffer && reserved_buffer != buffer)
|
||||
{
|
||||
hlsl_error(ctx, &buffer->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
|
||||
"Multiple buffers bound to cb%u.", buffer->reservation.reg_index);
|
||||
"Multiple buffers bound to index %u.", buffer->reservation.reg_index);
|
||||
hlsl_note(ctx, &reserved_buffer->loc, VKD3D_SHADER_LOG_ERROR,
|
||||
"Buffer %s is already bound to cb%u.", reserved_buffer->name, buffer->reservation.reg_index);
|
||||
"Buffer %s is already bound to index %u.",
|
||||
reserved_buffer->name, buffer->reservation.reg_index);
|
||||
}
|
||||
|
||||
buffer->reg.id = buffer->reservation.reg_index;
|
||||
buffer->reg.index = buffer->reservation.reg_index;
|
||||
if (hlsl_version_ge(ctx, 5, 1))
|
||||
buffer->reg.id = id++;
|
||||
else
|
||||
buffer->reg.id = buffer->reg.index;
|
||||
buffer->reg.allocation_size = 1;
|
||||
buffer->reg.allocated = true;
|
||||
TRACE("Allocated reserved %s to cb%u.\n", buffer->name, index);
|
||||
TRACE("Allocated reserved %s to index %u, id %u.\n", buffer->name, buffer->reg.index, buffer->reg.id);
|
||||
}
|
||||
else if (!buffer->reservation.reg_type)
|
||||
{
|
||||
while (get_reserved_buffer(ctx, index))
|
||||
++index;
|
||||
|
||||
buffer->reg.id = index;
|
||||
buffer->reg.index = index;
|
||||
if (hlsl_version_ge(ctx, 5, 1))
|
||||
buffer->reg.id = id++;
|
||||
else
|
||||
buffer->reg.id = buffer->reg.index;
|
||||
buffer->reg.allocation_size = 1;
|
||||
buffer->reg.allocated = true;
|
||||
TRACE("Allocated %s to cb%u.\n", buffer->name, index);
|
||||
TRACE("Allocated %s to index %u, id %u.\n", buffer->name, buffer->reg.index, buffer->reg.id);
|
||||
++index;
|
||||
}
|
||||
else
|
||||
@ -5008,7 +5014,7 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum
|
||||
}
|
||||
else if (var->regs[regset].allocated)
|
||||
{
|
||||
start = var->regs[regset].id;
|
||||
start = var->regs[regset].index;
|
||||
count = var->regs[regset].allocation_size;
|
||||
}
|
||||
else
|
||||
@ -5025,8 +5031,8 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum
|
||||
static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset)
|
||||
{
|
||||
char regset_name = get_regset_name(regset);
|
||||
uint32_t min_index = 0, id = 0;
|
||||
struct hlsl_ir_var *var;
|
||||
uint32_t min_index = 0;
|
||||
|
||||
if (regset == HLSL_REGSET_UAVS)
|
||||
{
|
||||
@ -5051,18 +5057,18 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset)
|
||||
const struct hlsl_ir_var *reserved_object, *last_reported = NULL;
|
||||
unsigned int index, i;
|
||||
|
||||
if (var->regs[regset].id < min_index)
|
||||
if (var->regs[regset].index < min_index)
|
||||
{
|
||||
assert(regset == HLSL_REGSET_UAVS);
|
||||
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS,
|
||||
"UAV index (%u) must be higher than the maximum render target index (%u).",
|
||||
var->regs[regset].id, min_index - 1);
|
||||
var->regs[regset].index, min_index - 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
index = var->regs[regset].id + i;
|
||||
index = var->regs[regset].index + i;
|
||||
|
||||
/* get_allocated_object() may return "var" itself, but we
|
||||
* actually want that, otherwise we'll end up reporting the
|
||||
@ -5078,6 +5084,14 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset)
|
||||
last_reported = reserved_object;
|
||||
}
|
||||
}
|
||||
|
||||
if (hlsl_version_ge(ctx, 5, 1))
|
||||
var->regs[regset].id = id++;
|
||||
else
|
||||
var->regs[regset].id = var->regs[regset].index;
|
||||
TRACE("Allocated reserved variable %s to indices %c%u-%c%u, id %u.\n",
|
||||
var->name, regset_name, var->regs[regset].index,
|
||||
regset_name, var->regs[regset].index + count, var->regs[regset].id);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5094,10 +5108,14 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset)
|
||||
}
|
||||
index -= count;
|
||||
|
||||
var->regs[regset].id = index;
|
||||
var->regs[regset].index = index;
|
||||
if (hlsl_version_ge(ctx, 5, 1))
|
||||
var->regs[regset].id = id++;
|
||||
else
|
||||
var->regs[regset].id = var->regs[regset].index;
|
||||
var->regs[regset].allocated = true;
|
||||
TRACE("Allocated variable %s to %c%u-%c%u.\n", var->name, regset_name, index, regset_name,
|
||||
index + count);
|
||||
TRACE("Allocated variable %s to indices %c%u-%c%u, id %u.\n", var->name,
|
||||
regset_name, index, regset_name, index + count, var->regs[regset].id);
|
||||
++index;
|
||||
}
|
||||
}
|
||||
@ -5303,6 +5321,7 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere
|
||||
assert(deref->data_type);
|
||||
assert(hlsl_is_numeric_type(deref->data_type));
|
||||
|
||||
ret.index += offset / 4;
|
||||
ret.id += offset / 4;
|
||||
|
||||
ret.writemask = 0xf & (0xf << (offset % 4));
|
||||
|
@ -3185,7 +3185,7 @@ struct extern_resource
|
||||
bool is_user_packed;
|
||||
|
||||
enum hlsl_regset regset;
|
||||
unsigned int id, bind_count;
|
||||
unsigned int id, index, bind_count;
|
||||
};
|
||||
|
||||
static int sm4_compare_extern_resources(const void *a, const void *b)
|
||||
@ -3197,7 +3197,7 @@ static int sm4_compare_extern_resources(const void *a, const void *b)
|
||||
if ((r = vkd3d_u32_compare(aa->regset, bb->regset)))
|
||||
return r;
|
||||
|
||||
return vkd3d_u32_compare(aa->id, bb->id);
|
||||
return vkd3d_u32_compare(aa->index, bb->index);
|
||||
}
|
||||
|
||||
static void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count)
|
||||
@ -3281,7 +3281,8 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un
|
||||
extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type;
|
||||
|
||||
extern_resources[*count].regset = regset;
|
||||
extern_resources[*count].id = var->regs[regset].id + regset_offset;
|
||||
extern_resources[*count].id = var->regs[regset].id;
|
||||
extern_resources[*count].index = var->regs[regset].index + regset_offset;
|
||||
extern_resources[*count].bind_count = 1;
|
||||
|
||||
++*count;
|
||||
@ -3324,6 +3325,7 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un
|
||||
|
||||
extern_resources[*count].regset = r;
|
||||
extern_resources[*count].id = var->regs[r].id;
|
||||
extern_resources[*count].index = var->regs[r].index;
|
||||
extern_resources[*count].bind_count = var->bind_count[r];
|
||||
|
||||
++*count;
|
||||
@ -3360,6 +3362,7 @@ static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, un
|
||||
|
||||
extern_resources[*count].regset = HLSL_REGSET_NUMERIC;
|
||||
extern_resources[*count].id = buffer->reg.id;
|
||||
extern_resources[*count].index = buffer->reg.index;
|
||||
extern_resources[*count].bind_count = 1;
|
||||
|
||||
++*count;
|
||||
@ -3456,7 +3459,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
|
||||
put_u32(&buffer, 0);
|
||||
put_u32(&buffer, 0);
|
||||
}
|
||||
put_u32(&buffer, resource->id);
|
||||
put_u32(&buffer, resource->index);
|
||||
put_u32(&buffer, resource->bind_count);
|
||||
put_u32(&buffer, flags);
|
||||
}
|
||||
@ -3754,30 +3757,57 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re
|
||||
{
|
||||
reg->type = VKD3DSPR_RESOURCE;
|
||||
reg->dimension = VSIR_DIMENSION_VEC4;
|
||||
reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id;
|
||||
reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref);
|
||||
if (hlsl_version_ge(ctx, 5, 1))
|
||||
{
|
||||
reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id;
|
||||
reg->idx[1].offset = var->regs[HLSL_REGSET_TEXTURES].index; /* FIXME: array index */
|
||||
reg->idx_count = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].index;
|
||||
reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref);
|
||||
reg->idx_count = 1;
|
||||
}
|
||||
assert(regset == HLSL_REGSET_TEXTURES);
|
||||
reg->idx_count = 1;
|
||||
*writemask = VKD3DSP_WRITEMASK_ALL;
|
||||
}
|
||||
else if (regset == HLSL_REGSET_UAVS)
|
||||
{
|
||||
reg->type = VKD3DSPR_UAV;
|
||||
reg->dimension = VSIR_DIMENSION_VEC4;
|
||||
reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id;
|
||||
reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref);
|
||||
if (hlsl_version_ge(ctx, 5, 1))
|
||||
{
|
||||
reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id;
|
||||
reg->idx[1].offset = var->regs[HLSL_REGSET_UAVS].index; /* FIXME: array index */
|
||||
reg->idx_count = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].index;
|
||||
reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref);
|
||||
reg->idx_count = 1;
|
||||
}
|
||||
assert(regset == HLSL_REGSET_UAVS);
|
||||
reg->idx_count = 1;
|
||||
*writemask = VKD3DSP_WRITEMASK_ALL;
|
||||
}
|
||||
else if (regset == HLSL_REGSET_SAMPLERS)
|
||||
{
|
||||
reg->type = VKD3DSPR_SAMPLER;
|
||||
reg->dimension = VSIR_DIMENSION_NONE;
|
||||
reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id;
|
||||
reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref);
|
||||
if (hlsl_version_ge(ctx, 5, 1))
|
||||
{
|
||||
reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id;
|
||||
reg->idx[1].offset = var->regs[HLSL_REGSET_SAMPLERS].index; /* FIXME: array index */
|
||||
reg->idx_count = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].index;
|
||||
reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref);
|
||||
reg->idx_count = 1;
|
||||
}
|
||||
assert(regset == HLSL_REGSET_SAMPLERS);
|
||||
reg->idx_count = 1;
|
||||
*writemask = VKD3DSP_WRITEMASK_ALL;
|
||||
}
|
||||
else
|
||||
@ -3787,9 +3817,19 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct vkd3d_shader_re
|
||||
assert(data_type->class <= HLSL_CLASS_VECTOR);
|
||||
reg->type = VKD3DSPR_CONSTBUFFER;
|
||||
reg->dimension = VSIR_DIMENSION_VEC4;
|
||||
reg->idx[0].offset = var->buffer->reg.id;
|
||||
reg->idx[1].offset = offset / 4;
|
||||
reg->idx_count = 2;
|
||||
if (hlsl_version_ge(ctx, 5, 1))
|
||||
{
|
||||
reg->idx[0].offset = var->buffer->reg.id;
|
||||
reg->idx[1].offset = var->buffer->reg.index; /* FIXME: array index */
|
||||
reg->idx[2].offset = offset / 4;
|
||||
reg->idx_count = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
reg->idx[0].offset = var->buffer->reg.index;
|
||||
reg->idx[1].offset = offset / 4;
|
||||
reg->idx_count = 2;
|
||||
}
|
||||
*writemask = ((1u << data_type->dimx) - 1) << (offset & 3);
|
||||
}
|
||||
}
|
||||
@ -4173,18 +4213,35 @@ static bool encode_texel_offset_as_aoffimmi(struct sm4_instruction *instr,
|
||||
|
||||
static void write_sm4_dcl_constant_buffer(const struct tpf_writer *tpf, const struct hlsl_buffer *cbuffer)
|
||||
{
|
||||
const struct sm4_instruction instr =
|
||||
size_t size = (cbuffer->used_size + 3) / 4;
|
||||
|
||||
struct sm4_instruction instr =
|
||||
{
|
||||
.opcode = VKD3D_SM4_OP_DCL_CONSTANT_BUFFER,
|
||||
|
||||
.srcs[0].reg.dimension = VSIR_DIMENSION_VEC4,
|
||||
.srcs[0].reg.type = VKD3DSPR_CONSTBUFFER,
|
||||
.srcs[0].reg.idx[0].offset = cbuffer->reg.id,
|
||||
.srcs[0].reg.idx[1].offset = (cbuffer->used_size + 3) / 4,
|
||||
.srcs[0].reg.idx_count = 2,
|
||||
.srcs[0].swizzle = VKD3D_SHADER_NO_SWIZZLE,
|
||||
.src_count = 1,
|
||||
};
|
||||
|
||||
if (hlsl_version_ge(tpf->ctx, 5, 1))
|
||||
{
|
||||
instr.srcs[0].reg.idx[0].offset = cbuffer->reg.id;
|
||||
instr.srcs[0].reg.idx[1].offset = cbuffer->reg.index;
|
||||
instr.srcs[0].reg.idx[2].offset = cbuffer->reg.index; /* FIXME: array end */
|
||||
instr.srcs[0].reg.idx_count = 3;
|
||||
|
||||
instr.idx[0] = size;
|
||||
instr.idx_count = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
instr.srcs[0].reg.idx[0].offset = cbuffer->reg.index;
|
||||
instr.srcs[0].reg.idx[1].offset = size;
|
||||
instr.srcs[0].reg.idx_count = 2;
|
||||
}
|
||||
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
|
||||
@ -4197,7 +4254,6 @@ static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct ex
|
||||
.opcode = VKD3D_SM4_OP_DCL_SAMPLER,
|
||||
|
||||
.dsts[0].reg.type = VKD3DSPR_SAMPLER,
|
||||
.dsts[0].reg.idx_count = 1,
|
||||
.dst_count = 1,
|
||||
};
|
||||
|
||||
@ -4213,7 +4269,19 @@ static void write_sm4_dcl_samplers(const struct tpf_writer *tpf, const struct ex
|
||||
if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used)
|
||||
continue;
|
||||
|
||||
instr.dsts[0].reg.idx[0].offset = resource->id + i;
|
||||
if (hlsl_version_ge(tpf->ctx, 5, 1))
|
||||
{
|
||||
assert(!i);
|
||||
instr.dsts[0].reg.idx[0].offset = resource->id;
|
||||
instr.dsts[0].reg.idx[1].offset = resource->index;
|
||||
instr.dsts[0].reg.idx[2].offset = resource->index; /* FIXME: array end */
|
||||
instr.dsts[0].reg.idx_count = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
instr.dsts[0].reg.idx[0].offset = resource->index + i;
|
||||
instr.dsts[0].reg.idx_count = 1;
|
||||
}
|
||||
write_sm4_instruction(tpf, &instr);
|
||||
}
|
||||
}
|
||||
@ -4246,6 +4314,20 @@ static void write_sm4_dcl_textures(const struct tpf_writer *tpf, const struct ex
|
||||
.idx_count = 1,
|
||||
};
|
||||
|
||||
if (hlsl_version_ge(tpf->ctx, 5, 1))
|
||||
{
|
||||
assert(!i);
|
||||
instr.dsts[0].reg.idx[0].offset = resource->id;
|
||||
instr.dsts[0].reg.idx[1].offset = resource->index;
|
||||
instr.dsts[0].reg.idx[2].offset = resource->index; /* FIXME: array end */
|
||||
instr.dsts[0].reg.idx_count = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
instr.dsts[0].reg.idx[0].offset = resource->index + i;
|
||||
instr.dsts[0].reg.idx_count = 1;
|
||||
}
|
||||
|
||||
if (uav)
|
||||
{
|
||||
switch (resource->data_type->sampler_dim)
|
||||
|
Loading…
Reference in New Issue
Block a user