aboutsummaryrefslogtreecommitdiff
path: root/build/tools/HLSLcc/May_2014/src/toGLSL.c
diff options
context:
space:
mode:
authorlbavoil <[email protected]>2016-03-25 13:01:54 +0100
committerlbavoil <[email protected]>2016-03-25 13:01:54 +0100
commit99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c (patch)
treefbcd4260d6c953d569a887505336a1c3f202e10f /build/tools/HLSLcc/May_2014/src/toGLSL.c
downloadhbaoplus-99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c.tar.xz
hbaoplus-99174e4e5fb4b7079da80b35a6dfd68f3fd56a1c.zip
GFSDK_HBAO+_distro_r3.0_cl20573789
Diffstat (limited to 'build/tools/HLSLcc/May_2014/src/toGLSL.c')
-rw-r--r--build/tools/HLSLcc/May_2014/src/toGLSL.c900
1 files changed, 900 insertions, 0 deletions
diff --git a/build/tools/HLSLcc/May_2014/src/toGLSL.c b/build/tools/HLSLcc/May_2014/src/toGLSL.c
new file mode 100644
index 0000000..471416b
--- /dev/null
+++ b/build/tools/HLSLcc/May_2014/src/toGLSL.c
@@ -0,0 +1,900 @@
+#include "internal_includes/tokens.h"
+#include "internal_includes/structs.h"
+#include "internal_includes/decode.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "bstrlib.h"
+#include "internal_includes/toGLSLInstruction.h"
+#include "internal_includes/toGLSLOperand.h"
+#include "internal_includes/toGLSLDeclaration.h"
+#include "internal_includes/languages.h"
+#include "internal_includes/debug.h"
+#include "internal_includes/hlslcc_malloc.h"
+
+#ifndef GL_VERTEX_SHADER_ARB
+#define GL_VERTEX_SHADER_ARB 0x8B31
+#endif
+#ifndef GL_FRAGMENT_SHADER_ARB
+#define GL_FRAGMENT_SHADER_ARB 0x8B30
+#endif
+#ifndef GL_GEOMETRY_SHADER
+#define GL_GEOMETRY_SHADER 0x8DD9
+#endif
+#ifndef GL_TESS_EVALUATION_SHADER
+#define GL_TESS_EVALUATION_SHADER 0x8E87
+#endif
+#ifndef GL_TESS_CONTROL_SHADER
+#define GL_TESS_CONTROL_SHADER 0x8E88
+#endif
+#ifndef GL_COMPUTE_SHADER
+#define GL_COMPUTE_SHADER 0x91B9
+#endif
+
+
+HLSLCC_API void HLSLCC_APIENTRY HLSLcc_SetMemoryFunctions(void* (*malloc_override)(size_t),void* (*calloc_override)(size_t,size_t),void (*free_override)(void *),void* (*realloc_override)(void*,size_t))
+{
+ hlslcc_malloc = malloc_override;
+ hlslcc_calloc = calloc_override;
+ hlslcc_free = free_override;
+ hlslcc_realloc = realloc_override;
+}
+
+static void ClearDependencyData(SHADER_TYPE eType, GLSLCrossDependencyData* depends)
+{
+ if(depends == NULL)
+ {
+ return;
+ }
+
+ switch(eType)
+ {
+ case PIXEL_SHADER:
+ {
+ uint32_t i;
+ for(i=0;i<MAX_SHADER_VEC4_INPUT; ++i)
+ {
+ depends->aePixelInputInterpolation[i] = INTERPOLATION_UNDEFINED;
+ }
+ break;
+ }
+ case HULL_SHADER:
+ {
+ depends->eTessPartitioning = TESSELLATOR_PARTITIONING_UNDEFINED;
+ depends->eTessOutPrim = TESSELLATOR_OUTPUT_UNDEFINED;
+ break;
+ }
+ }
+}
+
+void AddIndentation(HLSLCrossCompilerContext* psContext)
+{
+ int i;
+ int indent = psContext->indent;
+ bstring glsl = *psContext->currentGLSLString;
+ for(i=0; i < indent; ++i)
+ {
+ bcatcstr(glsl, " ");
+ }
+}
+
+void AddVersionDependentCode(HLSLCrossCompilerContext* psContext)
+{
+ bstring glsl = *psContext->currentGLSLString;
+
+ if(psContext->psShader->ui32MajorVersion <= 3)
+ {
+ bcatcstr(glsl, "int RepCounter;\n");
+ bcatcstr(glsl, "int LoopCounter;\n");
+ bcatcstr(glsl, "int ZeroBasedCounter;\n");
+ if(psContext->psShader->eShaderType == VERTEX_SHADER)
+ {
+ uint32_t texCoord;
+ bcatcstr(glsl, "ivec4 Address;\n");
+
+ if(InOutSupported(psContext->psShader->eTargetLanguage))
+ {
+ bcatcstr(glsl, "out vec4 OffsetColour;\n");
+ bcatcstr(glsl, "out vec4 BaseColour;\n");
+
+ bcatcstr(glsl, "out vec4 Fog;\n");
+
+ for(texCoord=0; texCoord<8; ++texCoord)
+ {
+ bformata(glsl, "out vec4 TexCoord%d;\n", texCoord);
+ }
+ }
+ else
+ {
+ bcatcstr(glsl, "varying vec4 OffsetColour;\n");
+ bcatcstr(glsl, "varying vec4 BaseColour;\n");
+
+ bcatcstr(glsl, "varying vec4 Fog;\n");
+
+ for(texCoord=0; texCoord<8; ++texCoord)
+ {
+ bformata(glsl, "varying vec4 TexCoord%d;\n", texCoord);
+ }
+ }
+ }
+ else
+ {
+ uint32_t renderTargets, texCoord;
+
+ bcatcstr(glsl, "varying vec4 OffsetColour;\n");
+ bcatcstr(glsl, "varying vec4 BaseColour;\n");
+
+ bcatcstr(glsl, "varying vec4 Fog;\n");
+
+ for(texCoord=0; texCoord<8; ++texCoord)
+ {
+ bformata(glsl, "varying vec4 TexCoord%d;\n", texCoord);
+ }
+
+ for(renderTargets=0; renderTargets<8; ++renderTargets)
+ {
+ bformata(glsl, "#define Output%d gl_FragData[%d]\n", renderTargets, renderTargets);
+ }
+ }
+ }
+
+ if(!HaveCompute(psContext->psShader->eTargetLanguage))
+ {
+ if(psContext->psShader->eShaderType == COMPUTE_SHADER)
+ {
+ bcatcstr(glsl,"#extension GL_ARB_compute_shader : enable\n");
+ bcatcstr(glsl,"#extension GL_ARB_shader_storage_buffer_object : enable\n");
+ }
+ }
+
+ if (!HaveAtomicMem(psContext->psShader->eTargetLanguage) ||
+ !HaveAtomicCounter(psContext->psShader->eTargetLanguage))
+ {
+ if( psContext->psShader->aiOpcodeUsed[OPCODE_IMM_ATOMIC_ALLOC] ||
+ psContext->psShader->aiOpcodeUsed[OPCODE_IMM_ATOMIC_CONSUME] ||
+ psContext->psShader->aiOpcodeUsed[OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED])
+ {
+ bcatcstr(glsl,"#extension GL_ARB_shader_atomic_counters : enable\n");
+
+ bcatcstr(glsl,"#extension GL_ARB_shader_storage_buffer_object : enable\n");
+ }
+ }
+
+ if(!HaveGather(psContext->psShader->eTargetLanguage))
+ {
+ if(psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4] ||
+ psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4_PO_C] ||
+ psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4_PO] ||
+ psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4_C])
+ {
+ bcatcstr(glsl,"#extension GL_ARB_texture_gather : enable\n");
+ }
+ }
+
+ if(!HaveGatherNonConstOffset(psContext->psShader->eTargetLanguage))
+ {
+ if(psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4_PO_C] ||
+ psContext->psShader->aiOpcodeUsed[OPCODE_GATHER4_PO])
+ {
+ bcatcstr(glsl,"#extension GL_ARB_gpu_shader5 : enable\n");
+ }
+ }
+
+ if(!HaveQueryLod(psContext->psShader->eTargetLanguage))
+ {
+ if(psContext->psShader->aiOpcodeUsed[OPCODE_LOD])
+ {
+ bcatcstr(glsl,"#extension GL_ARB_texture_query_lod : enable\n");
+ }
+ }
+
+ if(!HaveQueryLevels(psContext->psShader->eTargetLanguage))
+ {
+ if(psContext->psShader->aiOpcodeUsed[OPCODE_RESINFO])
+ {
+ bcatcstr(glsl,"#extension GL_ARB_texture_query_levels : enable\n");
+ }
+ }
+
+ if(!HaveImageLoadStore(psContext->psShader->eTargetLanguage))
+ {
+ if(psContext->psShader->aiOpcodeUsed[OPCODE_STORE_UAV_TYPED] ||
+ psContext->psShader->aiOpcodeUsed[OPCODE_STORE_RAW] ||
+ psContext->psShader->aiOpcodeUsed[OPCODE_STORE_STRUCTURED])
+ {
+ bcatcstr(glsl,"#extension GL_ARB_shader_image_load_store : enable\n");
+ bcatcstr(glsl,"#extension GL_ARB_shader_bit_encoding : enable\n");
+ }
+ else
+ if(psContext->psShader->aiOpcodeUsed[OPCODE_LD_UAV_TYPED] ||
+ psContext->psShader->aiOpcodeUsed[OPCODE_LD_RAW] ||
+ psContext->psShader->aiOpcodeUsed[OPCODE_LD_STRUCTURED])
+ {
+ bcatcstr(glsl,"#extension GL_ARB_shader_image_load_store : enable\n");
+ }
+ }
+
+
+ if((psContext->flags & HLSLCC_FLAG_ORIGIN_UPPER_LEFT)
+ && (psContext->psShader->eTargetLanguage >= LANG_150))
+ {
+ bcatcstr(glsl,"layout(origin_upper_left) in vec4 gl_FragCoord;\n");
+ }
+
+ if((psContext->flags & HLSLCC_FLAG_PIXEL_CENTER_INTEGER)
+ && (psContext->psShader->eTargetLanguage >= LANG_150))
+ {
+ bcatcstr(glsl,"layout(pixel_center_integer) in vec4 gl_FragCoord;\n");
+ }
+
+ //The fragment language has no default precision qualifier for floating point types.
+ if(psContext->psShader->eShaderType == PIXEL_SHADER &&
+ psContext->psShader->eTargetLanguage == LANG_ES_100 || psContext->psShader->eTargetLanguage == LANG_ES_300 )
+ {
+ bcatcstr(glsl,"precision highp float;\n");
+ }
+
+ /* For versions which do not support a vec1 (currently all versions) */
+ bcatcstr(glsl,"struct vec1 {\n");
+ bcatcstr(glsl,"\tfloat x;\n");
+ bcatcstr(glsl,"};\n");
+
+ if(HaveUVec(psContext->psShader->eTargetLanguage))
+ {
+ bcatcstr(glsl,"struct uvec1 {\n");
+ bcatcstr(glsl,"\tuint x;\n");
+ bcatcstr(glsl,"};\n");
+ }
+
+ bcatcstr(glsl,"struct ivec1 {\n");
+ bcatcstr(glsl,"\tint x;\n");
+ bcatcstr(glsl,"};\n");
+
+ /*
+ OpenGL 4.1 API spec:
+ To use any built-in input or output in the gl_PerVertex block in separable
+ program objects, shader code must redeclare that block prior to use.
+ */
+ if(psContext->psShader->eShaderType == VERTEX_SHADER && psContext->psShader->eTargetLanguage >= LANG_410)
+ {
+ bcatcstr(glsl, "out gl_PerVertex {\n");
+ bcatcstr(glsl, "vec4 gl_Position;\n");
+ bcatcstr(glsl, "float gl_PointSize;\n");
+ bcatcstr(glsl, "float gl_ClipDistance[];");
+ bcatcstr(glsl, "};\n");
+ }
+
+ /* There is no default precision qualifier for the following sampler types in either the vertex or fragment language: */
+ if(psContext->psShader->eTargetLanguage == LANG_ES_300 || psContext->psShader->eTargetLanguage == LANG_ES_310)
+ {
+ bcatcstr(glsl,"precision lowp sampler3D;\n");
+ bcatcstr(glsl,"precision lowp samplerCubeShadow;\n");
+ bcatcstr(glsl,"precision lowp sampler2DShadow;\n");
+ bcatcstr(glsl,"precision lowp sampler2DArray;\n");
+ bcatcstr(glsl,"precision lowp sampler2DArrayShadow;\n");
+ bcatcstr(glsl,"precision lowp isampler2D;\n");
+ bcatcstr(glsl,"precision lowp isampler3D;\n");
+ bcatcstr(glsl,"precision lowp isamplerCube;\n");
+ bcatcstr(glsl,"precision lowp isampler2DArray;\n");
+ bcatcstr(glsl,"precision lowp usampler2D;\n");
+ bcatcstr(glsl,"precision lowp usampler3D;\n");
+ bcatcstr(glsl,"precision lowp usamplerCube;\n");
+ bcatcstr(glsl,"precision lowp usampler2DArray;\n");
+
+ if(psContext->psShader->eTargetLanguage == LANG_ES_310)
+ {
+ bcatcstr(glsl,"precision lowp isampler2DMS;\n");
+ bcatcstr(glsl,"precision lowp usampler2D;\n");
+ bcatcstr(glsl,"precision lowp usampler3D;\n");
+ bcatcstr(glsl,"precision lowp usamplerCube;\n");
+ bcatcstr(glsl,"precision lowp usampler2DArray;\n");
+ bcatcstr(glsl,"precision lowp usampler2DMS;\n");
+ bcatcstr(glsl,"precision lowp image2D;\n");
+ bcatcstr(glsl,"precision lowp image3D;\n");
+ bcatcstr(glsl,"precision lowp imageCube;\n");
+ bcatcstr(glsl,"precision lowp image2DArray;\n");
+ bcatcstr(glsl,"precision lowp iimage2D;\n");
+ bcatcstr(glsl,"precision lowp iimage3D;\n");
+ bcatcstr(glsl,"precision lowp iimageCube;\n");
+ bcatcstr(glsl,"precision lowp uimage2DArray;\n");
+ //Only highp is valid for atomic_uint
+ bcatcstr(glsl,"precision highp atomic_uint;\n");
+ }
+ }
+
+ if(SubroutinesSupported(psContext->psShader->eTargetLanguage))
+ {
+ bcatcstr(glsl, "subroutine void SubroutineType();\n");
+ }
+}
+
+GLLang ChooseLanguage(Shader* psShader)
+{
+ // Depends on the HLSL shader model extracted from bytecode.
+ switch(psShader->ui32MajorVersion)
+ {
+ case 5:
+ {
+ return LANG_430;
+ }
+ case 4:
+ {
+ return LANG_330;
+ }
+ default:
+ {
+ return LANG_120;
+ }
+ }
+}
+
+const char* GetVersionString(GLLang language)
+{
+ switch(language)
+ {
+ case LANG_ES_100:
+ {
+ return "#version 100\n";
+ break;
+ }
+ case LANG_ES_300:
+ {
+ return "#version 300 es\n";
+ break;
+ }
+ case LANG_ES_310:
+ {
+ return "#version 310 es\n";
+ break;
+ }
+ case LANG_120:
+ {
+ return "#version 120\n";
+ break;
+ }
+ case LANG_130:
+ {
+ return "#version 130\n";
+ break;
+ }
+ case LANG_140:
+ {
+ return "#version 140\n";
+ break;
+ }
+ case LANG_150:
+ {
+ return "#version 150\n";
+ break;
+ }
+ case LANG_330:
+ {
+ return "#version 330\n";
+ break;
+ }
+ case LANG_400:
+ {
+ return "#version 400\n";
+ break;
+ }
+ case LANG_410:
+ {
+ return "#version 410\n";
+ break;
+ }
+ case LANG_420:
+ {
+ return "#version 420\n";
+ break;
+ }
+ case LANG_430:
+ {
+ return "#version 430\n";
+ break;
+ }
+ case LANG_440:
+ {
+ return "#version 440\n";
+ break;
+ }
+ default:
+ {
+ return "";
+ break;
+ }
+ }
+}
+
+void TranslateToGLSL(HLSLCrossCompilerContext* psContext, GLLang* planguage,const GlExtensions *extensions)
+{
+ bstring glsl;
+ uint32_t i;
+ Shader* psShader = psContext->psShader;
+ GLLang language = *planguage;
+ const uint32_t ui32InstCount = psShader->ui32InstCount;
+ const uint32_t ui32DeclCount = psShader->ui32DeclCount;
+
+ psContext->indent = 0;
+
+ if(language == LANG_DEFAULT)
+ {
+ language = ChooseLanguage(psShader);
+ *planguage = language;
+ }
+
+ glsl = bfromcstralloc (1024, GetVersionString(language));
+
+ psContext->glsl = glsl;
+ psContext->earlyMain = bfromcstralloc (1024, "");
+ for(i=0; i<NUM_PHASES;++i)
+ {
+ psContext->postShaderCode[i] = bfromcstralloc (1024, "");
+ }
+ psContext->currentGLSLString = &glsl;
+ psShader->eTargetLanguage = language;
+ psShader->extensions = (const struct GlExtensions*)extensions;
+ psContext->currentPhase = MAIN_PHASE;
+
+ if(extensions)
+ {
+ if(extensions->ARB_explicit_attrib_location)
+ bcatcstr(glsl,"#extension GL_ARB_explicit_attrib_location : require\n");
+ if(extensions->ARB_explicit_uniform_location)
+ bcatcstr(glsl,"#extension GL_ARB_explicit_uniform_location : require\n");
+ if(extensions->ARB_shading_language_420pack)
+ bcatcstr(glsl,"#extension GL_ARB_shading_language_420pack : require\n");
+ }
+
+ ClearDependencyData(psShader->eShaderType, psContext->psDependencies);
+
+ AddVersionDependentCode(psContext);
+
+ if(psContext->flags & HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT)
+ {
+ bcatcstr(glsl, "layout(std140) uniform;\n");
+ }
+
+ //Special case. Can have multiple phases.
+ if(psShader->eShaderType == HULL_SHADER)
+ {
+ int haveInstancedForkPhase = 0;
+ uint32_t forkIndex = 0;
+
+ ConsolidateHullTempVars(psShader);
+
+ for(i=0; i < psShader->ui32HSDeclCount; ++i)
+ {
+ TranslateDeclaration(psContext, psShader->psHSDecl+i);
+ }
+
+ //control
+ psContext->currentPhase = HS_CTRL_POINT_PHASE;
+
+ if(psShader->ui32HSControlPointDeclCount)
+ {
+ bcatcstr(glsl, "//Control point phase declarations\n");
+ for(i=0; i < psShader->ui32HSControlPointDeclCount; ++i)
+ {
+ TranslateDeclaration(psContext, psShader->psHSControlPointPhaseDecl+i);
+ }
+ }
+
+ if(psShader->ui32HSControlPointInstrCount)
+ {
+ SetDataTypes(psContext, psShader->psHSControlPointPhaseInstr, psShader->ui32HSControlPointInstrCount);
+
+ bcatcstr(glsl, "void control_point_phase()\n{\n");
+ psContext->indent++;
+
+ for(i=0; i < psShader->ui32HSControlPointInstrCount; ++i)
+ {
+ TranslateInstruction(psContext, psShader->psHSControlPointPhaseInstr+i);
+ }
+ psContext->indent--;
+ bcatcstr(glsl, "}\n");
+ }
+
+ //fork
+ psContext->currentPhase = HS_FORK_PHASE;
+ for(forkIndex = 0; forkIndex < psShader->ui32ForkPhaseCount; ++forkIndex)
+ {
+ bcatcstr(glsl, "//Fork phase declarations\n");
+ for(i=0; i < psShader->aui32HSForkDeclCount[forkIndex]; ++i)
+ {
+ TranslateDeclaration(psContext, psShader->apsHSForkPhaseDecl[forkIndex]+i);
+ if(psShader->apsHSForkPhaseDecl[forkIndex][i].eOpcode == OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT)
+ {
+ haveInstancedForkPhase = 1;
+ }
+ }
+
+ bformata(glsl, "void fork_phase%d()\n{\n", forkIndex);
+ psContext->indent++;
+
+ SetDataTypes(psContext, psShader->apsHSForkPhaseInstr[forkIndex], psShader->aui32HSForkInstrCount[forkIndex]-1);
+
+ if(haveInstancedForkPhase)
+ {
+ AddIndentation(psContext);
+ bformata(glsl, "for(int forkInstanceID = 0; forkInstanceID < HullPhase%dInstanceCount; ++forkInstanceID) {\n", forkIndex);
+ psContext->indent++;
+ }
+
+ //The minus one here is remove the return statement at end of phases.
+ //This is needed otherwise the for loop will only run once.
+ ASSERT(psShader->apsHSForkPhaseInstr[forkIndex][psShader->aui32HSForkInstrCount[forkIndex]-1].eOpcode == OPCODE_RET);
+ for(i=0; i < psShader->aui32HSForkInstrCount[forkIndex]-1; ++i)
+ {
+ TranslateInstruction(psContext, psShader->apsHSForkPhaseInstr[forkIndex]+i);
+ }
+
+ if(haveInstancedForkPhase)
+ {
+ psContext->indent--;
+ AddIndentation(psContext);
+ bcatcstr(glsl, "}\n");
+
+ if(psContext->havePostShaderCode[psContext->currentPhase])
+ {
+#ifdef _DEBUG
+ AddIndentation(psContext);
+ bcatcstr(glsl, "//--- Post shader code ---\n");
+#endif
+ bconcat(glsl, psContext->postShaderCode[psContext->currentPhase]);
+#ifdef _DEBUG
+ AddIndentation(psContext);
+ bcatcstr(glsl, "//--- End post shader code ---\n");
+#endif
+ }
+ }
+
+ psContext->indent--;
+ bcatcstr(glsl, "}\n");
+ }
+
+
+ //join
+ psContext->currentPhase = HS_JOIN_PHASE;
+ if(psShader->ui32HSJoinDeclCount)
+ {
+ bcatcstr(glsl, "//Join phase declarations\n");
+ for(i=0; i < psShader->ui32HSJoinDeclCount; ++i)
+ {
+ TranslateDeclaration(psContext, psShader->psHSJoinPhaseDecl+i);
+ }
+ }
+
+ if(psShader->ui32HSJoinInstrCount)
+ {
+ SetDataTypes(psContext, psShader->psHSJoinPhaseInstr, psShader->ui32HSJoinInstrCount);
+
+ bcatcstr(glsl, "void join_phase()\n{\n");
+ psContext->indent++;
+
+ for(i=0; i < psShader->ui32HSJoinInstrCount; ++i)
+ {
+ TranslateInstruction(psContext, psShader->psHSJoinPhaseInstr+i);
+ }
+
+ psContext->indent--;
+ bcatcstr(glsl, "}\n");
+ }
+
+ bcatcstr(glsl, "void main()\n{\n");
+
+ psContext->indent++;
+
+#ifdef _DEBUG
+ AddIndentation(psContext);
+ bcatcstr(glsl, "//--- Start Early Main ---\n");
+#endif
+ bconcat(glsl, psContext->earlyMain);
+#ifdef _DEBUG
+ AddIndentation(psContext);
+ bcatcstr(glsl, "//--- End Early Main ---\n");
+#endif
+
+ if(psShader->ui32HSControlPointInstrCount)
+ {
+ AddIndentation(psContext);
+ bcatcstr(glsl, "control_point_phase();\n");
+
+ if(psShader->ui32ForkPhaseCount || psShader->ui32HSJoinInstrCount)
+ {
+ AddIndentation(psContext);
+ bcatcstr(glsl, "barrier();\n");
+ }
+ }
+ for(forkIndex = 0; forkIndex < psShader->ui32ForkPhaseCount; ++forkIndex)
+ {
+ AddIndentation(psContext);
+ bformata(glsl, "fork_phase%d();\n", forkIndex);
+
+ if(psShader->ui32HSJoinInstrCount || (forkIndex+1 < psShader->ui32ForkPhaseCount))
+ {
+ AddIndentation(psContext);
+ bcatcstr(glsl, "barrier();\n");
+ }
+ }
+ if(psShader->ui32HSJoinInstrCount)
+ {
+ AddIndentation(psContext);
+ bcatcstr(glsl, "join_phase();\n");
+ }
+
+ psContext->indent--;
+
+ bcatcstr(glsl, "}\n");
+
+ if(psContext->psDependencies)
+ {
+ //Save partitioning and primitive type for use by domain shader.
+ psContext->psDependencies->eTessOutPrim = psShader->sInfo.eTessOutPrim;
+
+ psContext->psDependencies->eTessPartitioning = psShader->sInfo.eTessPartitioning;
+ }
+
+ return;
+ }
+
+ if(psShader->eShaderType == DOMAIN_SHADER && psContext->psDependencies)
+ {
+ //Load partitioning and primitive type from hull shader.
+ switch(psContext->psDependencies->eTessOutPrim)
+ {
+ case TESSELLATOR_OUTPUT_TRIANGLE_CW:
+ {
+ bcatcstr(glsl, "layout(cw) in;\n");
+ break;
+ }
+ case TESSELLATOR_OUTPUT_POINT:
+ {
+ bcatcstr(glsl, "layout(point_mode) in;\n");
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ switch(psContext->psDependencies->eTessPartitioning)
+ {
+ case TESSELLATOR_PARTITIONING_FRACTIONAL_ODD:
+ {
+ bcatcstr(glsl, "layout(fractional_odd_spacing) in;\n");
+ break;
+ }
+ case TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN:
+ {
+ bcatcstr(glsl, "layout(fractional_even_spacing) in;\n");
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ for(i=0; i < ui32DeclCount; ++i)
+ {
+ TranslateDeclaration(psContext, psShader->psDecl+i);
+ }
+
+ if(psContext->psShader->ui32NumDx9ImmConst)
+ {
+ bformata(psContext->glsl, "vec4 ImmConstArray [%d];\n", psContext->psShader->ui32NumDx9ImmConst);
+ }
+
+ bcatcstr(glsl, "void main()\n{\n");
+
+ psContext->indent++;
+
+#ifdef _DEBUG
+ AddIndentation(psContext);
+ bcatcstr(glsl, "//--- Start Early Main ---\n");
+#endif
+ bconcat(glsl, psContext->earlyMain);
+#ifdef _DEBUG
+ AddIndentation(psContext);
+ bcatcstr(glsl, "//--- End Early Main ---\n");
+#endif
+
+ MarkIntegerImmediates(psContext);
+
+ SetDataTypes(psContext, psShader->psInst, ui32InstCount);
+
+ for(i=0; i < ui32InstCount; ++i)
+ {
+ TranslateInstruction(psContext, psShader->psInst+i);
+ }
+
+ psContext->indent--;
+
+ bcatcstr(glsl, "}\n");
+}
+
+static void FreeSubOperands(Instruction* psInst, const uint32_t ui32NumInsts)
+{
+ uint32_t ui32Inst;
+ for(ui32Inst = 0; ui32Inst < ui32NumInsts; ++ui32Inst)
+ {
+ Instruction* psCurrentInst = &psInst[ui32Inst];
+ const uint32_t ui32NumOperands = psCurrentInst->ui32NumOperands;
+ uint32_t ui32Operand;
+
+ for(ui32Operand = 0; ui32Operand < ui32NumOperands; ++ui32Operand)
+ {
+ uint32_t ui32SubOperand;
+ for(ui32SubOperand = 0; ui32SubOperand < MAX_SUB_OPERANDS; ++ui32SubOperand)
+ {
+ if(psCurrentInst->asOperands[ui32Operand].psSubOperand[ui32SubOperand])
+ {
+ hlslcc_free(psCurrentInst->asOperands[ui32Operand].psSubOperand[ui32SubOperand]);
+ psCurrentInst->asOperands[ui32Operand].psSubOperand[ui32SubOperand] = NULL;
+ }
+ }
+ }
+ }
+}
+
+HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromMem(const char* shader,
+ unsigned int flags,
+ GLLang language,
+ const GlExtensions *extensions,
+ GLSLCrossDependencyData* dependencies,
+ GLSLShader* result)
+{
+ uint32_t* tokens;
+ Shader* psShader;
+ char* glslcstr = NULL;
+ int GLSLShaderType = GL_FRAGMENT_SHADER_ARB;
+ int success = 0;
+ uint32_t i;
+
+ tokens = (uint32_t*)shader;
+
+ psShader = DecodeDXBC(tokens);
+
+ if(psShader)
+ {
+ HLSLCrossCompilerContext sContext;
+
+ sContext.psShader = psShader;
+ sContext.flags = flags;
+ sContext.psDependencies = dependencies;
+
+ for(i=0; i<NUM_PHASES;++i)
+ {
+ sContext.havePostShaderCode[i] = 0;
+ }
+
+ TranslateToGLSL(&sContext, &language,extensions);
+
+ switch(psShader->eShaderType)
+ {
+ case VERTEX_SHADER:
+ {
+ GLSLShaderType = GL_VERTEX_SHADER_ARB;
+ break;
+ }
+ case GEOMETRY_SHADER:
+ {
+ GLSLShaderType = GL_GEOMETRY_SHADER;
+ break;
+ }
+ case DOMAIN_SHADER:
+ {
+ GLSLShaderType = GL_TESS_EVALUATION_SHADER;
+ break;
+ }
+ case HULL_SHADER:
+ {
+ GLSLShaderType = GL_TESS_CONTROL_SHADER;
+ break;
+ }
+ case COMPUTE_SHADER:
+ {
+ GLSLShaderType = GL_COMPUTE_SHADER;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ glslcstr = bstr2cstr(sContext.glsl, '\0');
+
+ bdestroy(sContext.glsl);
+ bdestroy(sContext.earlyMain);
+ for(i=0; i<NUM_PHASES; ++i)
+ {
+ bdestroy(sContext.postShaderCode[i]);
+ }
+
+ hlslcc_free(psShader->psHSControlPointPhaseDecl);
+ FreeSubOperands(psShader->psHSControlPointPhaseInstr, psShader->ui32HSControlPointInstrCount);
+ hlslcc_free(psShader->psHSControlPointPhaseInstr);
+
+ for(i=0; i < psShader->ui32ForkPhaseCount; ++i)
+ {
+ hlslcc_free(psShader->apsHSForkPhaseDecl[i]);
+ FreeSubOperands(psShader->apsHSForkPhaseInstr[i], psShader->aui32HSForkInstrCount[i]);
+ hlslcc_free(psShader->apsHSForkPhaseInstr[i]);
+ }
+ hlslcc_free(psShader->psHSJoinPhaseDecl);
+ FreeSubOperands(psShader->psHSJoinPhaseInstr, psShader->ui32HSJoinInstrCount);
+ hlslcc_free(psShader->psHSJoinPhaseInstr);
+
+ hlslcc_free(psShader->psDecl);
+ FreeSubOperands(psShader->psInst, psShader->ui32InstCount);
+ hlslcc_free(psShader->psInst);
+
+ memcpy(&result->reflection,&psShader->sInfo,sizeof(psShader->sInfo));
+
+
+ hlslcc_free(psShader);
+
+ success = 1;
+ }
+
+ shader = 0;
+ tokens = 0;
+
+ /* Fill in the result struct */
+
+ result->shaderType = GLSLShaderType;
+ result->sourceCode = glslcstr;
+ result->GLSLLanguage = language;
+
+ return success;
+}
+
+HLSLCC_API int HLSLCC_APIENTRY TranslateHLSLFromFile(const char* filename,
+ unsigned int flags,
+ GLLang language,
+ const GlExtensions *extensions,
+ GLSLCrossDependencyData* dependencies,
+ GLSLShader* result)
+{
+ FILE* shaderFile;
+ int length;
+ size_t readLength;
+ char* shader;
+ int success = 0;
+
+ shaderFile = fopen(filename, "rb");
+
+ if(!shaderFile)
+ {
+ return 0;
+ }
+
+ fseek(shaderFile, 0, SEEK_END);
+ length = ftell(shaderFile);
+ fseek(shaderFile, 0, SEEK_SET);
+
+ shader = (char*)hlslcc_malloc(length+1);
+
+ readLength = fread(shader, 1, length, shaderFile);
+
+ fclose(shaderFile);
+ shaderFile = 0;
+
+ shader[readLength] = '\0';
+
+ success = TranslateHLSLFromMem(shader, flags, language, extensions, dependencies, result);
+
+ hlslcc_free(shader);
+
+ return success;
+}
+
+HLSLCC_API void HLSLCC_APIENTRY FreeGLSLShader(GLSLShader* s)
+{
+ bcstrfree(s->sourceCode);
+ s->sourceCode = NULL;
+ FreeShaderInfo(&s->reflection);
+}
+