From a11f5a477206c2815f5891f97527dd9bf70cbcfd Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Sun, 30 Aug 2020 21:35:31 -0400 Subject: [PATCH] spirv: Separate pixel shader outputs from inputs, fix linker accordingly --- mojoshader_common.c | 22 ++++++++++++++++------ mojoshader_internal.h | 1 + profiles/mojoshader_profile_spirv.c | 24 ++++++++++++++---------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/mojoshader_common.c b/mojoshader_common.c index 1f2566f..e5d2144 100644 --- a/mojoshader_common.c +++ b/mojoshader_common.c @@ -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); @@ -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 @@ -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! @@ -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]) diff --git a/mojoshader_internal.h b/mojoshader_internal.h index 455688a..6945e6b 100644 --- a/mojoshader_internal.h +++ b/mojoshader_internal.h @@ -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, diff --git a/profiles/mojoshader_profile_spirv.c b/profiles/mojoshader_profile_spirv.c index c29bb5e..02e5369 100644 --- a/profiles/mojoshader_profile_spirv.c +++ b/profiles/mojoshader_profile_spirv.c @@ -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) { @@ -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 @@ -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); @@ -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));