mojoshader_opengl.c
changeset 1277 da61410edbc9
parent 1251 cee4402d5ab8
child 1311 448b82b26acb
equal deleted inserted replaced
1276:89c389e4112f 1277:da61410edbc9
   446     const MOJOSHADER_parseData *pd = shader->parseData;
   446     const MOJOSHADER_parseData *pd = shader->parseData;
   447     size_t table_offset = pd->output_len - sizeof(SpirvPatchTable);
   447     size_t table_offset = pd->output_len - sizeof(SpirvPatchTable);
   448     return (const SpirvPatchTable *) (pd->output + table_offset);
   448     return (const SpirvPatchTable *) (pd->output + table_offset);
   449 } // spv_getPatchTable
   449 } // spv_getPatchTable
   450 
   450 
   451 static int spv_CompileShader(const MOJOSHADER_parseData *pd, int32 base_location, GLuint *s, int32 patch_pcoord)
   451 static int spv_CompileShader(const MOJOSHADER_parseData *pd, int32 base_location, GLuint *s)
   452 {
   452 {
   453     GLint ok = 0;
   453     GLint ok = 0;
   454 
   454 
   455     GLsizei data_len = pd->output_len - sizeof(SpirvPatchTable);
   455     GLsizei data_len = pd->output_len - sizeof(SpirvPatchTable);
   456     const GLvoid* data = pd->output;
   456     const GLvoid* data = pd->output;
   457     uint32 *patched_data = NULL;
   457     uint32 *patched_data = NULL;
   458     if (base_location || patch_pcoord)
   458     if (base_location)
   459     {
   459     {
   460         size_t i, max;
   460         size_t i, max;
   461 
   461 
   462         patched_data = (uint32 *) Malloc(data_len);
   462         patched_data = (uint32 *) Malloc(data_len);
   463         memcpy(patched_data, data, data_len);
   463         memcpy(patched_data, data, data_len);
   472             SpirvPatchEntry entry = table->samplers[i];
   472             SpirvPatchEntry entry = table->samplers[i];
   473             if (entry.offset)
   473             if (entry.offset)
   474                 patched_data[entry.offset] += base_location;
   474                 patched_data[entry.offset] += base_location;
   475         } // for
   475         } // for
   476 
   476 
   477         if (patch_pcoord && table->ps_texcoord0_offset)
       
   478         {
       
   479             // Subtract 3 to get from Location value offset to start of op.
       
   480             uint32 op_base = table->ps_texcoord0_offset - 3;
       
   481             assert(patched_data[op_base+0] == (SpvOpDecorate | (4 << 16)));
       
   482             assert(patched_data[op_base+2] == SpvDecorationLocation);
       
   483             patched_data[op_base+2] = SpvDecorationBuiltIn;
       
   484             patched_data[op_base+3] = SpvBuiltInPointCoord;
       
   485         } // if
       
   486 
       
   487         data = patched_data;
   477         data = patched_data;
   488     } // if
   478     } // if
   489 
   479 
   490     const GLuint shader = ctx->glCreateShader(glsl_shader_type(pd->shader_type));
   480     const GLuint shader = ctx->glCreateShader(glsl_shader_type(pd->shader_type));
   491     ctx->glShaderBinary(1, &shader, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, data, data_len);
   481     ctx->glShaderBinary(1, &shader, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, data, data_len);
   519 
   509 
   520 static GLuint impl_SPIRV_LinkProgram(MOJOSHADER_glShader *vshader,
   510 static GLuint impl_SPIRV_LinkProgram(MOJOSHADER_glShader *vshader,
   521                                      MOJOSHADER_glShader *pshader)
   511                                      MOJOSHADER_glShader *pshader)
   522 {
   512 {
   523     GLint ok = 0;
   513     GLint ok = 0;
   524 
       
   525     // Shader compilation postponed until linking due to uniform locations being global in program.
       
   526     // To avoid overlap between VS and PS, we need to know about other shader stages to assign final
       
   527     // uniform locations before compilation.
       
   528     GLuint vs_handle = 0;
   514     GLuint vs_handle = 0;
   529     int32 base_location = 0;
   515     int32 base_location = 0;
   530     int32 patch_pcoord = 0;
   516 
       
   517     // Shader compilation postponed until linking due to locations being global
       
   518     // in program. To avoid overlap between VS and PS, we need to know about
       
   519     // other shader stages to assign final uniform/attrib locations before
       
   520     // compilation.
       
   521 
       
   522     MOJOSHADER_spirv_link_attributes(vshader->parseData, pshader->parseData);
       
   523 
   531     if (vshader)
   524     if (vshader)
   532     {
   525     {
   533         if (!spv_CompileShader(vshader->parseData, base_location, &vs_handle, patch_pcoord))
   526         if (!spv_CompileShader(vshader->parseData, base_location, &vs_handle))
   534             return 0;
   527             return 0;
   535 
   528 
   536         const SpirvPatchTable* patch_table = spv_getPatchTable(vshader);
   529         const SpirvPatchTable* patch_table = spv_getPatchTable(vshader);
   537         base_location += patch_table->location_count;
   530         base_location += patch_table->location_count;
   538         patch_pcoord = patch_table->vs_has_psize;
       
   539     } // if
   531     } // if
   540 
   532 
   541     GLuint ps_handle = 0;
   533     GLuint ps_handle = 0;
   542     if (pshader)
   534     if (pshader)
   543     {
   535     {
   544         if (!spv_CompileShader(pshader->parseData, base_location, &ps_handle, patch_pcoord))
   536         if (!spv_CompileShader(pshader->parseData, base_location, &ps_handle))
   545             return 0;
   537             return 0;
   546     } // if
   538     } // if
   547 
   539 
   548     if (ctx->have_opengl_2)
   540     if (ctx->have_opengl_2)
   549     {
   541     {