Skip to content

Commit

Permalink
spirv: Add patch table for vertex attribute types
Browse files Browse the repository at this point in the history
  • Loading branch information
flibitijibibo committed Aug 22, 2024
1 parent 0b3b01b commit 949b09e
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
12 changes: 12 additions & 0 deletions mojoshader_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,18 @@ typedef struct SpirvPatchTable
uint32 tid_pvec4i;
uint32 tid_vec4;

// Patches for vertex attribute types
uint32 tid_vec4_p;
uint32 tid_ivec4_p;
uint32 tid_uvec4_p;
uint32 attrib_type_offsets[MOJOSHADER_USAGE_TOTAL][16];
struct
{
uint32 num_loads;
uint32 *load_types;
uint32 *load_opcodes;
} attrib_type_load_offsets[MOJOSHADER_USAGE_TOTAL][16];

// Patches for linking vertex output/pixel input
uint32 attrib_offsets[MOJOSHADER_USAGE_TOTAL][16];
uint32 output_offsets[16];
Expand Down
63 changes: 59 additions & 4 deletions profiles/mojoshader_profile_spirv.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,9 +785,26 @@ static uint32 spv_access_uniform(Context *ctx, SpirvTypeIdx sti_ptr, RegisterTyp
return id_access;
} // spv_access_uniform

static void spv_add_attrib_fixup(Context *ctx, MOJOSHADER_usage usage, unsigned int index, unsigned int type_offset, unsigned int opcode_offset)
{
#define TYPE_LOAD_OFFSET ctx->spirv.patch_table.attrib_type_load_offsets[usage][index]
TYPE_LOAD_OFFSET.num_loads += 1;
TYPE_LOAD_OFFSET.load_types = realloc(
TYPE_LOAD_OFFSET.load_types,
sizeof(uint32) * TYPE_LOAD_OFFSET.num_loads);
TYPE_LOAD_OFFSET.load_opcodes = realloc(
TYPE_LOAD_OFFSET.load_opcodes,
sizeof(uint32) * TYPE_LOAD_OFFSET.num_loads);

TYPE_LOAD_OFFSET.load_types[TYPE_LOAD_OFFSET.num_loads - 1] = type_offset;
TYPE_LOAD_OFFSET.load_opcodes[TYPE_LOAD_OFFSET.num_loads - 1] = opcode_offset;
#undef TYPE_LOAD_OFFSET
} // spv_add_attrib_fixup

static SpirvResult spv_loadreg(Context *ctx, RegisterList *r)
{
const RegisterType regtype = r->regtype;
uint32 copy_id;

spv_check_read_reg_id(ctx, r);

Expand Down Expand Up @@ -839,7 +856,27 @@ static SpirvResult spv_loadreg(Context *ctx, RegisterList *r)

push_output(ctx, &ctx->mainline);
spv_emit(ctx, 4, SpvOpLoad, result.tid, result.id, id_src);
pop_output(ctx);
if (shader_is_vertex(ctx) && regtype == REG_TYPE_INPUT)
{
copy_id = spv_bumpid(ctx);
spv_emit(ctx, 4, SpvOpCopyObject, result.tid, copy_id, result.id);
result.id = copy_id;
pop_output(ctx);

// Store the offsets of:
// - OpLoad's type id, to change the input type
// - OpCopyObject's opcode, to change to OpConvert if needed
spv_add_attrib_fixup(ctx,
r->usage,
r->index,
(buffer_size(ctx->mainline) >> 2) - 7,
(buffer_size(ctx->mainline) >> 2) - 4);
} // if
else
{
// Nothing left to do for this register
pop_output(ctx);
} // else

return result;
} // spv_loadreg
Expand Down Expand Up @@ -2213,12 +2250,17 @@ void emit_SPIRV_attribute(Context *ctx, RegisterType regtype, int regnum,
{
case REG_TYPE_INPUT:
{
ctx->spirv.patch_table.tid_vec4_p = spv_get_type(ctx, STI_PTR_VEC4_I);
ctx->spirv.patch_table.tid_ivec4_p = spv_get_type(ctx, STI_PTR_IVEC4_I);
ctx->spirv.patch_table.tid_uvec4_p = spv_get_type(ctx, STI_PTR_UVEC4_I);

push_output(ctx, &ctx->mainline_intro);
SpirvTypeIdx sti = STI_PTR_VEC4_I;
tid = spv_get_type(ctx, sti);
tid = spv_get_type(ctx, STI_PTR_VEC4_I);
spv_emit(ctx, 4, SpvOpVariable, tid, r->spirv.iddecl, SpvStorageClassInput);
pop_output(ctx);

ctx->spirv.patch_table.attrib_type_offsets[usage][index] = (buffer_size(ctx->mainline_intro) >> 2) - 3;

// hnn: generate location decorators for the input
spv_output_location(ctx, r->spirv.iddecl, regnum);
break;
Expand Down Expand Up @@ -2379,7 +2421,7 @@ static void spv_emit_uniform_constant_array(Context *ctx,

void emit_SPIRV_finalize(Context *ctx)
{
size_t i, j, max;
size_t i, j, k, max;

/* The generator's magic number, this could be registered with Khronos
* if we wanted to. 0 is fine though, so use that for now. */
Expand Down Expand Up @@ -2683,9 +2725,22 @@ void emit_SPIRV_finalize(Context *ctx)
table->location_count = location_count;

for (i = 0; i < MOJOSHADER_USAGE_TOTAL; i++)
{
for (j = 0; j < 16; j++)
{
if (table->attrib_offsets[i][j])
table->attrib_offsets[i][j] += base_offset;
if (table->attrib_type_offsets[i][j])
{
table->attrib_type_offsets[i][j] += base_offset;
for (k = 0; k < table->attrib_type_load_offsets[i][j].num_loads; k++)
{
table->attrib_type_load_offsets[i][j].load_types[k] += base_offset;
table->attrib_type_load_offsets[i][j].load_opcodes[k] += base_offset;
} // for
} // if
} // for
} // for
for (i = 0; i < 16; i++)
if (table->output_offsets[i])
table->output_offsets[i] += base_offset;
Expand Down

0 comments on commit 949b09e

Please sign in to comment.