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 daf0a95
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 4 deletions.
16 changes: 16 additions & 0 deletions mojoshader_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,23 @@ typedef struct SpirvPatchTable
uint32 tid_pvec2i;
uint32 tid_vec2;
uint32 tid_pvec4i;

/// Patches for TEXCOORD0 and vertex attribute types
uint32 tid_vec4;
uint32 tid_ivec4;
uint32 tid_uvec4;

// 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];
Expand Down
81 changes: 77 additions & 4 deletions profiles/mojoshader_profile_spirv.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,9 +785,36 @@ 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)
{
uint32* next_types;
uint32* next_opcodes;

#define TYPE_LOAD_OFFSET ctx->spirv.patch_table.attrib_type_load_offsets[usage][index]

next_types = (uint32*) Malloc(ctx, sizeof(uint32) * (TYPE_LOAD_OFFSET.num_loads + 1));
next_opcodes = (uint32*) Malloc(ctx, sizeof(uint32) * (TYPE_LOAD_OFFSET.num_loads + 1));

memcpy(next_types, TYPE_LOAD_OFFSET.load_types, sizeof(uint32) * TYPE_LOAD_OFFSET.num_loads);
memcpy(next_opcodes, TYPE_LOAD_OFFSET.load_opcodes, sizeof(uint32) * TYPE_LOAD_OFFSET.num_loads);

Free(ctx, TYPE_LOAD_OFFSET.load_types);
Free(ctx, TYPE_LOAD_OFFSET.load_opcodes);

TYPE_LOAD_OFFSET.load_types = next_types;
TYPE_LOAD_OFFSET.load_opcodes = next_opcodes;

TYPE_LOAD_OFFSET.load_types[TYPE_LOAD_OFFSET.num_loads] = type_offset;
TYPE_LOAD_OFFSET.load_opcodes[TYPE_LOAD_OFFSET.num_loads] = opcode_offset;

TYPE_LOAD_OFFSET.num_loads += 1;
#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 +866,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 +2260,20 @@ 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);
ctx->spirv.patch_table.tid_vec4 = spv_get_type(ctx, STI_VEC4);
ctx->spirv.patch_table.tid_ivec4 = spv_get_type(ctx, STI_IVEC4);
ctx->spirv.patch_table.tid_uvec4 = spv_get_type(ctx, STI_UVEC4);

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 +2434,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 @@ -2698,6 +2753,11 @@ void emit_SPIRV_finalize(Context *ctx)
if (table->pointcoord_var_offset)
table->pointcoord_var_offset += base_offset;

for (i = 0; i < MOJOSHADER_USAGE_TOTAL; i++)
for (j = 0; j < 16; j++)
if (table->attrib_type_offsets[i][j])
table->attrib_type_offsets[i][j] += base_offset;

base_offset <<= 2;
if (ctx->mainline_intro) base_offset += buffer_size(ctx->mainline_intro);
if (ctx->mainline_arguments) base_offset += buffer_size(ctx->mainline_arguments);
Expand All @@ -2706,6 +2766,19 @@ void emit_SPIRV_finalize(Context *ctx)
if (table->pointcoord_load_offset)
table->pointcoord_load_offset += base_offset;

base_offset <<= 2;
if (ctx->mainline_top) base_offset += buffer_size(ctx->mainline_top);
base_offset >>= 2;

for (i = 0; i < MOJOSHADER_USAGE_TOTAL; i++)
for (j = 0; j < 16; j++)
if (table->attrib_type_offsets[i][j])
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

push_output(ctx, &ctx->postflight);
buffer_append(ctx->output, &ctx->spirv.patch_table, sizeof(ctx->spirv.patch_table));
pop_output(ctx);
Expand Down

0 comments on commit daf0a95

Please sign in to comment.