Skip to content

Commit

Permalink
spirv: Separate pixel shader outputs from inputs, fix linker accordingly
Browse files Browse the repository at this point in the history
  • Loading branch information
flibitijibibo committed Aug 31, 2020
1 parent 29035a8 commit a11f5a4
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 16 deletions.
22 changes: 16 additions & 6 deletions mojoshader_common.c
Expand Up @@ -1062,7 +1062,7 @@ void MOJOSHADER_spirv_link_attributes(const MOJOSHADER_parseData *vertex,
const MOJOSHADER_parseData *pixel)
{
int i;
uint32 attr_loc = 1; // 0 is reserved for COLOR0
uint32 attr_loc = 0;
uint32 vOffset, pOffset;
int vDataLen = vertex->output_len - sizeof(SpirvPatchTable);
int pDataLen = pixel->output_len - sizeof(SpirvPatchTable);
Expand All @@ -1075,11 +1075,21 @@ void MOJOSHADER_spirv_link_attributes(const MOJOSHADER_parseData *vertex,
{
const MOJOSHADER_attribute *pAttr = &pixel->outputs[i];
assert(pAttr->usage == MOJOSHADER_USAGE_COLOR);
if (pAttr->index == 0)
continue;

pOffset = pTable->attrib_offsets[pAttr->usage][pAttr->index];
// Set the loc for the output declaration...
pOffset = pTable->output_offsets[pAttr->index];
assert(pOffset > 0);
((uint32 *) pixel->output)[pOffset] = attr_loc;

// Set the same value for the vertex output/pixel input...
pOffset = pTable->attrib_offsets[pAttr->usage][pAttr->index];
if (pOffset)
((uint32 *) pixel->output)[pOffset] = attr_loc;
vOffset = vTable->attrib_offsets[pAttr->usage][pAttr->index];
if (vOffset)
((uint32 *) vertex->output)[vOffset] = attr_loc;

// ... increment location index, finally.
attr_loc++;
} // for

Expand All @@ -1089,7 +1099,7 @@ void MOJOSHADER_spirv_link_attributes(const MOJOSHADER_parseData *vertex,
const MOJOSHADER_attribute *pAttr = &pixel->attributes[i];
if (pAttr->usage == MOJOSHADER_USAGE_UNKNOWN)
continue; // Probably something like VPOS, ignore!
if (pAttr->usage == MOJOSHADER_USAGE_COLOR && pAttr->index == 0)
if (pAttr->usage == MOJOSHADER_USAGE_COLOR && pTable->output_offsets[pAttr->index])
continue;

// The input may not exist in the output list!
Expand All @@ -1110,7 +1120,7 @@ void MOJOSHADER_spirv_link_attributes(const MOJOSHADER_parseData *vertex,
continue;
if (vAttr->usage == MOJOSHADER_USAGE_POINTSIZE && vAttr->index == 0)
continue;
if (vAttr->usage == MOJOSHADER_USAGE_COLOR && vAttr->index == 0)
if (vAttr->usage == MOJOSHADER_USAGE_COLOR && pTable->output_offsets[vAttr->index])
continue;

if (!pTable->attrib_offsets[vAttr->usage][vAttr->index])
Expand Down
1 change: 1 addition & 0 deletions mojoshader_internal.h
Expand Up @@ -755,6 +755,7 @@ typedef struct SpirvPatchTable

// Patches for linking vertex output/pixel input
uint32 attrib_offsets[MOJOSHADER_USAGE_TOTAL][16];
uint32 output_offsets[16];
} SpirvPatchTable;

void MOJOSHADER_spirv_link_attributes(const MOJOSHADER_parseData *vertex,
Expand Down
24 changes: 14 additions & 10 deletions profiles/mojoshader_profile_spirv.c
Expand Up @@ -271,6 +271,15 @@ static uint32 spv_output_location(Context *ctx, uint32 id, uint32 loc)
return (buffer_size(ctx->helpers) >> 2) - 1;
} // spv_output_location

static void spv_output_color_location(Context *ctx, uint32 id, uint32 index)
{
SpirvPatchTable* table = &ctx->spirv.patch_table;
push_output(ctx, &ctx->helpers);
spv_emit(ctx, 4, SpvOpDecorate, id, SpvDecorationLocation, index);
pop_output(ctx);
table->output_offsets[index] = (buffer_size(ctx->helpers) >> 2) - 1;
} // spv_output_color_location

static void spv_output_attrib_location(Context *ctx, uint32 id,
MOJOSHADER_usage usage, uint32 index)
{
Expand Down Expand Up @@ -1632,8 +1641,6 @@ static void spv_link_vs_attributes(Context *ctx, uint32 id,
spv_output_builtin(ctx, id, SpvBuiltInPointSize);
ctx->spirv.patch_table.attrib_offsets[usage][index] = 1;
} // else if
else if (usage == MOJOSHADER_USAGE_COLOR && index == 0)
spv_output_location(ctx, id, 0);
else
spv_output_attrib_location(ctx, id, usage, index);
} // spv_link_vs_attributes
Expand All @@ -1652,16 +1659,10 @@ static void spv_link_ps_attributes(Context *ctx, uint32 id, RegisterType regtype
// - decorated with location 0
// - not decorated as a built-in variable.
// There is no implicit broadcast.
if (index == 0)
spv_output_location(ctx, id, 0);
else
spv_output_attrib_location(ctx, id, MOJOSHADER_USAGE_COLOR, index);
spv_output_color_location(ctx, id, index);
break;
case REG_TYPE_INPUT: // v# (MOJOSHADER_USAGE_COLOR aka `oC#` in vertex shader)
if (usage == MOJOSHADER_USAGE_COLOR && index == 0)
spv_output_location(ctx, id, 0);
else
spv_output_attrib_location(ctx, id, usage, index);
spv_output_attrib_location(ctx, id, usage, index);
break;
case REG_TYPE_TEXTURE: // t# (MOJOSHADER_USAGE_TEXCOORD aka `oT#` in vertex shader)
spv_output_attrib_location(ctx, id, MOJOSHADER_USAGE_TEXCOORD, index);
Expand Down Expand Up @@ -2625,6 +2626,9 @@ void emit_SPIRV_finalize(Context *ctx)
for (j = 0; j < 16; j++)
if (table->attrib_offsets[i][j])
table->attrib_offsets[i][j] += base_offset;
for (i = 0; i < 16; i++)
if (table->output_offsets[i])
table->output_offsets[i] += base_offset;

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

0 comments on commit a11f5a4

Please sign in to comment.