Skip to content

Commit 467d0a1

Browse files
author
Mikko Strandborg
committed
Bring changes from upstream ( 281bc7d8cfdb )
1 parent 1d91e68 commit 467d0a1

33 files changed

+3465
-1328
lines changed

include/ShaderInfo.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <string>
77
#include "growing_array.h"
88
#include <stdint.h>
9+
910
//Reflection
1011
#define MAX_RESOURCE_BINDINGS 256
1112

@@ -109,6 +110,14 @@ enum TESSELLATOR_OUTPUT_PRIMITIVE
109110
TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4
110111
};
111112

113+
typedef enum TESSELLATOR_DOMAIN
114+
{
115+
TESSELLATOR_DOMAIN_UNDEFINED = 0,
116+
TESSELLATOR_DOMAIN_ISOLINE = 1,
117+
TESSELLATOR_DOMAIN_TRI = 2,
118+
TESSELLATOR_DOMAIN_QUAD = 3
119+
} TESSELLATOR_DOMAIN;
120+
112121
enum SPECIAL_NAME
113122
{
114123
NAME_UNDEFINED = 0,
@@ -232,6 +241,7 @@ struct ResourceBinding
232241
RESOURCE_RETURN_TYPE ui32ReturnType;
233242
uint32_t ui32NumSamples;
234243
REFLECT_RESOURCE_PRECISION ePrecision;
244+
int m_SamplerMode; // (SB_SAMPLER_MODE) For samplers, this is the sampler mode this sampler is declared with
235245

236246
SHADER_VARIABLE_TYPE GetDataType() const
237247
{
@@ -462,7 +472,7 @@ class ShaderInfo
462472
int32_t* pi32Rebase,
463473
uint32_t flags);
464474

465-
static std::string GetShaderVarIndexedFullName(const ShaderVarType* psShaderVar, std::vector<uint32_t> &indices, const std::string dynamicIndex, bool revertDynamicIndexCalc, bool matrixAsVectors);
475+
static std::string GetShaderVarIndexedFullName(const ShaderVarType* psShaderVar, const std::vector<uint32_t>& indices, const std::string& dynamicIndex, bool revertDynamicIndexCalc, bool matrixAsVectors);
466476

467477
// Apply shader precision information to resource bindings
468478
void AddSamplerPrecisions(HLSLccSamplerPrecisionInfo &info);
@@ -491,5 +501,9 @@ class ShaderInfo
491501

492502
TESSELLATOR_PARTITIONING eTessPartitioning;
493503
TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim;
504+
uint32_t ui32TessInputControlPointCount;
505+
uint32_t ui32TessOutputControlPointCount;
506+
TESSELLATOR_DOMAIN eTessDomain;
507+
bool bEarlyFragmentTests;
494508
};
495509

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
// In Unity, instancing array sizes should be able to be dynamically patched at runtime by defining the macro.
4+
5+
#include <string>
6+
#define UNITY_RUNTIME_INSTANCING_ARRAY_SIZE_MACRO "UNITY_RUNTIME_INSTANCING_ARRAY_SIZE"
7+
8+
const unsigned int kArraySizeConstantID = 0;
9+
10+
// TODO: share with Runtime/GfxDevice/InstancingUtilities.h
11+
inline bool IsUnityInstancingConstantBufferName(const char* cbName)
12+
{
13+
static const char kInstancedCbNamePrefix[] = "UnityInstancing";
14+
return strncmp(cbName, kInstancedCbNamePrefix, sizeof(kInstancedCbNamePrefix) - 1) == 0;
15+
}

include/hlslcc.h

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <string>
55
#include <vector>
66
#include <map>
7+
#include <algorithm>
78

89
#if defined (_WIN32) && defined(HLSLCC_DYNLIB)
910
#define HLSLCC_APIENTRY __stdcall
@@ -48,6 +49,7 @@ typedef struct GlExtensions {
4849
} GlExtensions;
4950

5051
#include "ShaderInfo.h"
52+
#include "UnityInstancingFlexibleArraySize.h"
5153

5254
typedef std::vector<std::string> TextureSamplerPairs;
5355

@@ -123,6 +125,88 @@ typedef enum
123125
// Using a texture or uniform name like this will cause conflicts
124126
#define HLSLCC_TEMP_PREFIX "u_xlat"
125127

128+
typedef std::vector<std::pair<std::string, std::string>> MemberDefinitions;
129+
130+
// We store struct definition contents inside a vector of strings
131+
struct StructDefinition
132+
{
133+
StructDefinition() : m_Members(), m_Dependencies(), m_IsPrinted(false) {}
134+
135+
MemberDefinitions m_Members; // A vector of strings with the struct members
136+
std::vector<std::string> m_Dependencies; // A vector of struct names this struct depends on.
137+
bool m_IsPrinted; // Has this struct been printed out yet?
138+
};
139+
140+
typedef std::map<std::string, StructDefinition> StructDefinitions;
141+
142+
// Map of extra function definitions we need to add before the shader body but after the declarations.
143+
typedef std::map<std::string, std::string> FunctionDefinitions;
144+
145+
// A helper class for allocating binding slots
146+
// (because both UAVs and textures use the same slots in Metal, also constant buffers and other buffers etc)
147+
class BindingSlotAllocator
148+
{
149+
typedef std::map<uint32_t, uint32_t> SlotMap;
150+
SlotMap m_Allocations;
151+
uint32_t m_ShaderStageAllocations;
152+
public:
153+
BindingSlotAllocator() : m_Allocations(), m_ShaderStageAllocations(0)
154+
{
155+
for(int i = MAX_RESOURCE_BINDINGS-1; i >= 0; i --)
156+
m_FreeSlots.push_back(i);
157+
}
158+
159+
enum BindType
160+
{
161+
ConstantBuffer = 0,
162+
RWBuffer,
163+
Texture,
164+
UAV
165+
};
166+
167+
uint32_t GetBindingSlot(uint32_t regNo, BindType type)
168+
{
169+
// The key is regNumber with the bindtype stored to highest 16 bits
170+
uint32_t key = (m_ShaderStageAllocations + regNo) | (uint32_t(type) << 16);
171+
SlotMap::iterator itr = m_Allocations.find(key);
172+
if(itr == m_Allocations.end())
173+
{
174+
uint32_t slot = m_FreeSlots.back();
175+
m_FreeSlots.pop_back();
176+
m_Allocations.insert(std::make_pair(key, slot));
177+
return slot;
178+
}
179+
return itr->second;
180+
}
181+
182+
// Func for reserving binding slots with the original reg number.
183+
// Used for fragment shader UAVs (SetRandomWriteTarget etc).
184+
void ReserveBindingSlot(uint32_t regNo, BindType type)
185+
{
186+
uint32_t key = regNo | (uint32_t(type) << 16);
187+
m_Allocations.insert(std::make_pair(key, regNo));
188+
189+
// Remove regNo from free slots
190+
for (int i = m_FreeSlots.size() - 1; i >= 0; i--)
191+
{
192+
if (m_FreeSlots[i] == regNo)
193+
{
194+
m_FreeSlots.erase(m_FreeSlots.begin() + i);
195+
return;
196+
}
197+
}
198+
}
199+
200+
uint32_t SaveTotalShaderStageAllocationsCount()
201+
{
202+
m_ShaderStageAllocations = m_Allocations.size();
203+
return m_ShaderStageAllocations;
204+
}
205+
206+
private:
207+
std::vector<uint32_t> m_FreeSlots;
208+
};
209+
126210
//The shader stages (Vertex, Pixel et al) do not depend on each other
127211
//in HLSL. GLSL is a different story. HLSLCrossCompiler requires
128212
//that hull shaders must be compiled before domain shaders, and
@@ -207,6 +291,10 @@ class GLSLCrossDependencyData
207291
GLSLCrossDependencyData()
208292
: eTessPartitioning(),
209293
eTessOutPrim(),
294+
fMaxTessFactor(64.0),
295+
numPatchesInThreadGroup(0),
296+
hasControlPoint(false),
297+
hasPatchConstant(false),
210298
ui32ProgramStages(0),
211299
m_ExtBlendModes(),
212300
m_NextSpecID(0)
@@ -290,6 +378,10 @@ class GLSLCrossDependencyData
290378
//can be saved when compiling hull and passed to domain compilation.
291379
TESSELLATOR_PARTITIONING eTessPartitioning;
292380
TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim;
381+
float fMaxTessFactor;
382+
int numPatchesInThreadGroup;
383+
bool hasControlPoint;
384+
bool hasPatchConstant;
293385

294386
// Bitfield for the shader stages this program is going to include (see PS_FLAG_*).
295387
// Needed so we can construct proper shader input and output names
@@ -313,6 +405,28 @@ class GLSLCrossDependencyData
313405
pixelInterpolation[regNo] = mode;
314406
}
315407

408+
struct CompareFirst
409+
{
410+
CompareFirst(std::string val) : m_Val (val) {}
411+
bool operator()(const std::pair<std::string, std::string>& elem) const
412+
{
413+
return m_Val == elem.first;
414+
}
415+
private:
416+
std::string m_Val;
417+
};
418+
419+
inline bool IsMemberDeclared(const std::string &name)
420+
{
421+
if (std::find_if(m_SharedFunctionMembers.begin(), m_SharedFunctionMembers.end(), CompareFirst(name)) != m_SharedFunctionMembers.end())
422+
return true;
423+
return false;
424+
}
425+
426+
MemberDefinitions m_SharedFunctionMembers;
427+
BindingSlotAllocator m_SharedTextureSlots, m_SharedSamplerSlots;
428+
BindingSlotAllocator m_SharedBufferSlots;
429+
316430
inline void ClearCrossDependencyData()
317431
{
318432
pixelInterpolation.clear();
@@ -321,8 +435,9 @@ class GLSLCrossDependencyData
321435
varyingLocationsMap[i].clear();
322436
nextAvailableVaryingLocation[i] = 0;
323437
}
324-
m_NextSpecID = 0;
438+
m_NextSpecID = kArraySizeConstantID + 1;
325439
m_SpecConstantMap.clear();
440+
m_SharedFunctionMembers.clear();
326441
}
327442

328443
// Retrieve or allocate a layout slot for Vulkan specialization constant
@@ -368,9 +483,11 @@ class HLSLccReflection
368483
virtual bool OnConstant(const std::string &name, int bindIndex, SHADER_VARIABLE_TYPE cType, int rows, int cols, bool isMatrix, int arraySize) { return true; }
369484

370485
virtual void OnConstantBufferBinding(const std::string &name, int bindIndex) {}
371-
virtual void OnTextureBinding(const std::string &name, int bindIndex, int samplerIndex, HLSLCC_TEX_DIMENSION dim, bool isUAV) {}
486+
virtual void OnTextureBinding(const std::string &name, int bindIndex, int samplerIndex, bool multisampled, HLSLCC_TEX_DIMENSION dim, bool isUAV) {}
372487
virtual void OnBufferBinding(const std::string &name, int bindIndex, bool isUAV) {}
373488
virtual void OnThreadGroupSize(unsigned int xSize, unsigned int ySize, unsigned int zSize) {}
489+
virtual void OnTessellationInfo(uint32_t tessPartitionMode, uint32_t tessOutputWindingOrder, uint32_t tessMaxFactor, uint32_t tessNumPatchesInThreadGroup) {}
490+
virtual void OnTessellationKernelInfo(uint32_t patchKernelBufferCount) {}
374491
};
375492

376493

@@ -460,6 +577,12 @@ static const unsigned int HLSLCC_FLAG_NVN_TARGET = 0x800000;
460577
// as long as they are part of the same final linked program. Uniform buffer instance names solve this cross-shader symbol conflict issue.
461578
static const unsigned int HLSLCC_FLAG_UNIFORM_BUFFER_OBJECT_WITH_INSTANCE_NAME = 0x1000000;
462579

580+
// Massage shader steps into Metal compute kernel from vertex/hull shaders + post-tessellation vertex shader from domain shader
581+
static const unsigned int HLSLCC_FLAG_METAL_TESSELLATION = 0x2000000;
582+
583+
// Disable fastmath
584+
static const unsigned int HLSLCC_FLAG_DISABLE_FASTMATH = 0x4000000;
585+
463586
#ifdef __cplusplus
464587
extern "C" {
465588
#endif

src/ControlFlowGraph.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ void BasicBlock::RVarUnion(ReachableVariables &a, const ReachableVariables &b)
341341
#define UNITY_EXTERNAL_TOOL 1
342342
#include "Testing.h" // From Runtime/Testing
343343

344-
UNIT_TEST_SUITE(HLSLccTests)
344+
UNIT_TEST_SUITE(HLSLcc)
345345
{
346346
TEST(ControlFlowGraph_Build_Simple_Works)
347347
{

src/DataTypeAnalysis.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -451,15 +451,23 @@ void HLSLcc::DataTypeAnalysis::SetDataTypes(HLSLCrossCompilerContext* psContext,
451451
break;
452452

453453
case OPCODE_RESINFO:
454-
{
455-
if (psInst->eResInfoReturnType != RESINFO_INSTRUCTION_RETURN_UINT)
456-
MarkAllOperandsAs(psInst, SVT_FLOAT, aeTempVecType);
457-
break;
458-
}
454+
// Operand 0 depends on the return type declaration, op 1 is always uint
455+
MarkOperandAs(&psInst->asOperands[1], SVT_UINT, aeTempVecType);
456+
switch (psInst->eResInfoReturnType)
457+
{
458+
default:
459+
case RESINFO_INSTRUCTION_RETURN_FLOAT:
460+
case RESINFO_INSTRUCTION_RETURN_RCPFLOAT:
461+
MarkOperandAs(&psInst->asOperands[0], SVT_FLOAT, aeTempVecType);
462+
break;
463+
case RESINFO_INSTRUCTION_RETURN_UINT:
464+
MarkOperandAs(&psInst->asOperands[0], SVT_UINT, aeTempVecType);
465+
break;
466+
}
459467

460468
case OPCODE_SAMPLE_INFO:
461-
// TODO decode the _uint flag
462-
MarkOperandAs(&psInst->asOperands[0], SVT_FLOAT, aeTempVecType);
469+
// Sample_info uses the same RESINFO_RETURN_TYPE for storage. 0 = float, 1 = uint.
470+
MarkOperandAs(&psInst->asOperands[0], psInst->eResInfoReturnType == RESINFO_INSTRUCTION_RETURN_FLOAT ? SVT_FLOAT : SVT_UINT, aeTempVecType);
463471
break;
464472

465473
case OPCODE_SAMPLE_POS:
@@ -469,6 +477,7 @@ void HLSLcc::DataTypeAnalysis::SetDataTypes(HLSLCrossCompilerContext* psContext,
469477

470478
case OPCODE_LD_UAV_TYPED:
471479
// translates to gvec4 loadImage(gimage i, ivec p).
480+
MarkOperandAs(&psInst->asOperands[0], SVT_INT, aeTempVecType);
472481
MarkOperandAs(&psInst->asOperands[1], SVT_INT, aeTempVecType); // ivec p
473482
break;
474483

@@ -507,9 +516,13 @@ void HLSLcc::DataTypeAnalysis::SetDataTypes(HLSLCrossCompilerContext* psContext,
507516
break;
508517

509518
case OPCODE_F32TOF16:
519+
MarkOperandAs(&psInst->asOperands[0], SVT_UINT, aeTempVecType);
520+
MarkOperandAs(&psInst->asOperands[1], SVT_FLOAT, aeTempVecType);
521+
break;
522+
510523
case OPCODE_F16TOF32:
511-
// TODO
512-
ASSERT(0);
524+
MarkOperandAs(&psInst->asOperands[0], SVT_FLOAT, aeTempVecType);
525+
MarkOperandAs(&psInst->asOperands[1], SVT_UINT, aeTempVecType);
513526
break;
514527

515528

0 commit comments

Comments
 (0)