profiles/mojoshader_profile_spirv.c
changeset 1277 da61410edbc9
parent 1274 dda5d1bed2c7
child 1278 be0f548f321f
--- a/profiles/mojoshader_profile_spirv.c	Mon Jul 06 16:23:06 2020 -0400
+++ b/profiles/mojoshader_profile_spirv.c	Tue Jul 07 17:19:45 2020 -0400
@@ -271,6 +271,19 @@
     return (buffer_size(ctx->helpers) >> 2) - 1;
 } // spv_output_location
 
+static uint32 spv_output_attrib_location(Context *ctx, uint32 id,
+                                         MOJOSHADER_usage usage, uint32 index)
+{
+    uint32 result;
+    SpirvPatchTable* table = &ctx->spirv.patch_table;
+    push_output(ctx, &ctx->helpers);
+    spv_emit(ctx, 4, SpvOpDecorate, id, SpvDecorationLocation, 0xDEADBEEF);
+    pop_output(ctx);
+    result = (buffer_size(ctx->helpers) >> 2) - 1;
+    table->attrib_offsets[usage][index] = result;
+    return result;
+} // spv_output_attrib_location
+
 static void spv_output_sampler_binding(Context *ctx, uint32 id, uint32 binding)
 {
     if (isfail(ctx))
@@ -1510,65 +1523,6 @@
     pop_output(ctx);
 } // spv_emit_func_end
 
-// These are prioritized by most common to least common...
-#define SPV_OFFSET_COLOR        0
-#define SPV_LENGTH_COLOR        4 // Based on max render target count for XNA
-#define SPV_OFFSET_TEXCOORD     (SPV_OFFSET_COLOR + SPV_LENGTH_COLOR)
-#define SPV_LENGTH_TEXCOORD     16
-#define SPV_OFFSET_NORMAL       (SPV_OFFSET_TEXCOORD + SPV_LENGTH_TEXCOORD)
-#define SPV_LENGTH_NORMAL       8 // Arbitrary!
-#define SPV_OFFSET_FOG          (SPV_OFFSET_NORMAL + SPV_LENGTH_NORMAL)
-#define SPV_LENGTH_FOG          2 // Arbitrary!
-#define SPV_OFFSET_TANGENT      (SPV_OFFSET_FOG + SPV_LENGTH_FOG)
-#define SPV_LENGTH_TANGENT      1 // Arbitrary!
-#define SPV_OFFSET_BLENDINDICES (SPV_OFFSET_TANGENT + SPV_LENGTH_TANGENT)
-#define SPV_LENGTH_BLENDINDICES 4 // Arbitrary!
-#define SPV_OFFSET_POSITION     (SPV_OFFSET_BLENDINDICES + SPV_LENGTH_BLENDINDICES)
-#define SPV_LENGTH_POSITION     (4 - 1) // Arbitrary!
-#define SPV_OFFSET_PSIZE        (SPV_OFFSET_POSITION + SPV_LENGTH_POSITION)
-#define SPV_LENGTH_PSIZE        (4 - 1) // Arbitrary!
-
-static void spv_link_vs_attributes(Context *ctx, uint32 id, MOJOSHADER_usage usage, int index)
-{
-    // Some usages map to specific ranges. Keep those in sync with spv_link_ps_attributes().
-    switch (usage)
-    {
-        case MOJOSHADER_USAGE_POSITION:
-            if (index == 0)
-                spv_output_builtin(ctx, id, SpvBuiltInPosition);
-            else
-            {
-                assert(index <= SPV_LENGTH_POSITION);
-                spv_output_location(ctx, id, SPV_OFFSET_POSITION + (index - 1));
-            } // else
-            break;
-        case MOJOSHADER_USAGE_POINTSIZE:
-            if (index == 0)
-                spv_output_builtin(ctx, id, SpvBuiltInPointSize);
-            else
-            {
-                assert(index <= SPV_LENGTH_PSIZE);
-                spv_output_location(ctx, id, SPV_OFFSET_PSIZE + (index - 1));
-            }
-            break;
-        #define SPV_DECORATION_USAGE(usage) \
-            case MOJOSHADER_USAGE_##usage: \
-                assert(index < SPV_LENGTH_##usage); \
-                spv_output_location(ctx, id, SPV_OFFSET_##usage + index); \
-                break;
-        SPV_DECORATION_USAGE(COLOR)
-        SPV_DECORATION_USAGE(TEXCOORD)
-        SPV_DECORATION_USAGE(NORMAL)
-        SPV_DECORATION_USAGE(FOG)
-        SPV_DECORATION_USAGE(TANGENT)
-        SPV_DECORATION_USAGE(BLENDINDICES)
-        #undef SPV_DECORATION_USAGE
-        default:
-            failf(ctx, "unexpected attribute usage %d in vertex shader", usage);
-            break;
-    } // switch
-} // spv_link_vs_attributes
-
 static void spv_emit_vpos_glmode(Context *ctx, uint32 id)
 {
     // In SM3.0 vPos only has x and y defined, but we should be
@@ -1671,7 +1625,21 @@
     ctx->spirv.id_var_vpos = id_var_vpos;
 } // spv_emit_vpos_vkmode
 
-static void spv_link_ps_attributes(Context *ctx, uint32 id, RegisterType regtype, MOJOSHADER_usage usage, int index)
+static void spv_link_vs_attributes(Context *ctx, uint32 id,
+                                   MOJOSHADER_usage usage, int index)
+{
+    if (usage == MOJOSHADER_USAGE_POSITION && index == 0)
+        spv_output_builtin(ctx, id, SpvBuiltInPosition);
+    else if (usage == MOJOSHADER_USAGE_POINTSIZE && index == 0)
+        spv_output_builtin(ctx, id, SpvBuiltInPointSize);
+    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
+
+static void spv_link_ps_attributes(Context *ctx, uint32 id, RegisterType regtype,
+                                   MOJOSHADER_usage usage, int index)
 {
     switch (regtype)
     {
@@ -1684,48 +1652,19 @@
             // - decorated with location 0
             // - not decorated as a built-in variable.
             // There is no implicit broadcast.
-            assert(index < SPV_LENGTH_COLOR);
-            spv_output_location(ctx, id, SPV_OFFSET_COLOR + index);
+            if (index == 0)
+                spv_output_location(ctx, id, 0);
+            else
+                spv_output_attrib_location(ctx, id, MOJOSHADER_USAGE_COLOR, index);
             break;
         case REG_TYPE_INPUT: // v# (MOJOSHADER_USAGE_COLOR aka `oC#` in vertex shader)
-            switch (usage)
-            {
-                #define SPV_DECORATION_USAGE(usage) \
-                    case MOJOSHADER_USAGE_##usage: \
-                        assert(index < SPV_LENGTH_##usage); \
-                        spv_output_location(ctx, id, SPV_OFFSET_##usage + index); \
-                        break;
-                SPV_DECORATION_USAGE(COLOR)
-                SPV_DECORATION_USAGE(NORMAL)
-                SPV_DECORATION_USAGE(FOG)
-                SPV_DECORATION_USAGE(TANGENT)
-                SPV_DECORATION_USAGE(BLENDINDICES)
-                #undef SPV_DECORATION_USAGE
-                case MOJOSHADER_USAGE_TEXCOORD:
-                {
-                    uint32 location_offset = spv_output_location(ctx, id, SPV_OFFSET_TEXCOORD + index);
-                    if (index == 0)
-                        ctx->spirv.patch_table.ps_texcoord0_offset = location_offset;
-                    break;
-                } // case
-                case MOJOSHADER_USAGE_POSITION:
-                {
-                    assert(index <= SPV_LENGTH_POSITION);
-                    spv_output_location(ctx, id, SPV_OFFSET_POSITION + (index - 1));
-                } // case
-                case MOJOSHADER_USAGE_POINTSIZE:
-                {
-                    assert(index <= SPV_LENGTH_PSIZE);
-                    spv_output_location(ctx, id, SPV_OFFSET_PSIZE + (index - 1));
-                } // case
-                default:
-                    failf(ctx, "unexpected attribute usage %d in pixel shader", usage);
-                    break;
-            } // switch
+            if (usage == MOJOSHADER_USAGE_COLOR && index == 0)
+                spv_output_location(ctx, id, 0);
+            else
+                spv_output_attrib_location(ctx, id, usage, index);
             break;
         case REG_TYPE_TEXTURE: // t# (MOJOSHADER_USAGE_TEXCOORD aka `oT#` in vertex shader)
-            assert(index < SPV_LENGTH_TEXCOORD);
-            spv_output_location(ctx, id, SPV_OFFSET_TEXCOORD + index);
+            spv_output_attrib_location(ctx, id, MOJOSHADER_USAGE_TEXCOORD, index);
             break;
         case REG_TYPE_DEPTHOUT:
             spv_output_builtin(ctx, id, SpvBuiltInFragDepth);
@@ -2277,13 +2216,11 @@
             {
                 push_output(ctx, &ctx->mainline_intro);
                 SpirvTypeIdx sti = STI_PTR_VEC4_O;
-                if (usage == MOJOSHADER_USAGE_POINTSIZE)
+                if (usage == MOJOSHADER_USAGE_POINTSIZE
+                 || usage == MOJOSHADER_USAGE_FOG)
                 {
                     sti = STI_PTR_FLOAT_O;
-                    ctx->spirv.patch_table.vs_has_psize = 1;
                 } // if
-                else if (usage == MOJOSHADER_USAGE_FOG)
-                    sti = STI_PTR_FLOAT_O;
 
                 tid = spv_get_type(ctx, sti);
                 spv_emit(ctx, 4, SpvOpVariable, tid, r->spirv.iddecl, SpvStorageClassOutput);
@@ -2385,7 +2322,7 @@
 
 void emit_SPIRV_finalize(Context *ctx)
 {
-    size_t i, max;
+    size_t i, j, 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. */
@@ -2657,11 +2594,13 @@
             entry->location = -1;
     } // for
 
-    if (shader_is_pixel(ctx) && table->ps_texcoord0_offset)
-        table->ps_texcoord0_offset += base_offset;
-
     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;
+
     push_output(ctx, &ctx->postflight);
     buffer_append(ctx->output, &ctx->spirv.patch_table, sizeof(ctx->spirv.patch_table));
     pop_output(ctx);