Skip to content

Commit

Permalink
Bring changes from upstream ( 281bc7d8cfdb )
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikko Strandborg committed Jun 10, 2018
1 parent 1d91e68 commit 467d0a1
Show file tree
Hide file tree
Showing 33 changed files with 3,465 additions and 1,328 deletions.
16 changes: 15 additions & 1 deletion include/ShaderInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <string>
#include "growing_array.h"
#include <stdint.h>

//Reflection
#define MAX_RESOURCE_BINDINGS 256

Expand Down Expand Up @@ -109,6 +110,14 @@ enum TESSELLATOR_OUTPUT_PRIMITIVE
TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4
};

typedef enum TESSELLATOR_DOMAIN
{
TESSELLATOR_DOMAIN_UNDEFINED = 0,
TESSELLATOR_DOMAIN_ISOLINE = 1,
TESSELLATOR_DOMAIN_TRI = 2,
TESSELLATOR_DOMAIN_QUAD = 3
} TESSELLATOR_DOMAIN;

enum SPECIAL_NAME
{
NAME_UNDEFINED = 0,
Expand Down Expand Up @@ -232,6 +241,7 @@ struct ResourceBinding
RESOURCE_RETURN_TYPE ui32ReturnType;
uint32_t ui32NumSamples;
REFLECT_RESOURCE_PRECISION ePrecision;
int m_SamplerMode; // (SB_SAMPLER_MODE) For samplers, this is the sampler mode this sampler is declared with

SHADER_VARIABLE_TYPE GetDataType() const
{
Expand Down Expand Up @@ -462,7 +472,7 @@ class ShaderInfo
int32_t* pi32Rebase,
uint32_t flags);

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

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

TESSELLATOR_PARTITIONING eTessPartitioning;
TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim;
uint32_t ui32TessInputControlPointCount;
uint32_t ui32TessOutputControlPointCount;
TESSELLATOR_DOMAIN eTessDomain;
bool bEarlyFragmentTests;
};

15 changes: 15 additions & 0 deletions include/UnityInstancingFlexibleArraySize.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

// In Unity, instancing array sizes should be able to be dynamically patched at runtime by defining the macro.

#include <string>
#define UNITY_RUNTIME_INSTANCING_ARRAY_SIZE_MACRO "UNITY_RUNTIME_INSTANCING_ARRAY_SIZE"

const unsigned int kArraySizeConstantID = 0;

// TODO: share with Runtime/GfxDevice/InstancingUtilities.h
inline bool IsUnityInstancingConstantBufferName(const char* cbName)
{
static const char kInstancedCbNamePrefix[] = "UnityInstancing";
return strncmp(cbName, kInstancedCbNamePrefix, sizeof(kInstancedCbNamePrefix) - 1) == 0;
}
127 changes: 125 additions & 2 deletions include/hlslcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <string>
#include <vector>
#include <map>
#include <algorithm>

#if defined (_WIN32) && defined(HLSLCC_DYNLIB)
#define HLSLCC_APIENTRY __stdcall
Expand Down Expand Up @@ -48,6 +49,7 @@ typedef struct GlExtensions {
} GlExtensions;

#include "ShaderInfo.h"
#include "UnityInstancingFlexibleArraySize.h"

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

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

typedef std::vector<std::pair<std::string, std::string>> MemberDefinitions;

// We store struct definition contents inside a vector of strings
struct StructDefinition
{
StructDefinition() : m_Members(), m_Dependencies(), m_IsPrinted(false) {}

MemberDefinitions m_Members; // A vector of strings with the struct members
std::vector<std::string> m_Dependencies; // A vector of struct names this struct depends on.
bool m_IsPrinted; // Has this struct been printed out yet?
};

typedef std::map<std::string, StructDefinition> StructDefinitions;

// Map of extra function definitions we need to add before the shader body but after the declarations.
typedef std::map<std::string, std::string> FunctionDefinitions;

// A helper class for allocating binding slots
// (because both UAVs and textures use the same slots in Metal, also constant buffers and other buffers etc)
class BindingSlotAllocator
{
typedef std::map<uint32_t, uint32_t> SlotMap;
SlotMap m_Allocations;
uint32_t m_ShaderStageAllocations;
public:
BindingSlotAllocator() : m_Allocations(), m_ShaderStageAllocations(0)
{
for(int i = MAX_RESOURCE_BINDINGS-1; i >= 0; i --)
m_FreeSlots.push_back(i);
}

enum BindType
{
ConstantBuffer = 0,
RWBuffer,
Texture,
UAV
};

uint32_t GetBindingSlot(uint32_t regNo, BindType type)
{
// The key is regNumber with the bindtype stored to highest 16 bits
uint32_t key = (m_ShaderStageAllocations + regNo) | (uint32_t(type) << 16);
SlotMap::iterator itr = m_Allocations.find(key);
if(itr == m_Allocations.end())
{
uint32_t slot = m_FreeSlots.back();
m_FreeSlots.pop_back();
m_Allocations.insert(std::make_pair(key, slot));
return slot;
}
return itr->second;
}

// Func for reserving binding slots with the original reg number.
// Used for fragment shader UAVs (SetRandomWriteTarget etc).
void ReserveBindingSlot(uint32_t regNo, BindType type)
{
uint32_t key = regNo | (uint32_t(type) << 16);
m_Allocations.insert(std::make_pair(key, regNo));

// Remove regNo from free slots
for (int i = m_FreeSlots.size() - 1; i >= 0; i--)
{
if (m_FreeSlots[i] == regNo)
{
m_FreeSlots.erase(m_FreeSlots.begin() + i);
return;
}
}
}

uint32_t SaveTotalShaderStageAllocationsCount()
{
m_ShaderStageAllocations = m_Allocations.size();
return m_ShaderStageAllocations;
}

private:
std::vector<uint32_t> m_FreeSlots;
};

//The shader stages (Vertex, Pixel et al) do not depend on each other
//in HLSL. GLSL is a different story. HLSLCrossCompiler requires
//that hull shaders must be compiled before domain shaders, and
Expand Down Expand Up @@ -207,6 +291,10 @@ class GLSLCrossDependencyData
GLSLCrossDependencyData()
: eTessPartitioning(),
eTessOutPrim(),
fMaxTessFactor(64.0),
numPatchesInThreadGroup(0),
hasControlPoint(false),
hasPatchConstant(false),
ui32ProgramStages(0),
m_ExtBlendModes(),
m_NextSpecID(0)
Expand Down Expand Up @@ -290,6 +378,10 @@ class GLSLCrossDependencyData
//can be saved when compiling hull and passed to domain compilation.
TESSELLATOR_PARTITIONING eTessPartitioning;
TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim;
float fMaxTessFactor;
int numPatchesInThreadGroup;
bool hasControlPoint;
bool hasPatchConstant;

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

struct CompareFirst
{
CompareFirst(std::string val) : m_Val (val) {}
bool operator()(const std::pair<std::string, std::string>& elem) const
{
return m_Val == elem.first;
}
private:
std::string m_Val;
};

inline bool IsMemberDeclared(const std::string &name)
{
if (std::find_if(m_SharedFunctionMembers.begin(), m_SharedFunctionMembers.end(), CompareFirst(name)) != m_SharedFunctionMembers.end())
return true;
return false;
}

MemberDefinitions m_SharedFunctionMembers;
BindingSlotAllocator m_SharedTextureSlots, m_SharedSamplerSlots;
BindingSlotAllocator m_SharedBufferSlots;

inline void ClearCrossDependencyData()
{
pixelInterpolation.clear();
Expand All @@ -321,8 +435,9 @@ class GLSLCrossDependencyData
varyingLocationsMap[i].clear();
nextAvailableVaryingLocation[i] = 0;
}
m_NextSpecID = 0;
m_NextSpecID = kArraySizeConstantID + 1;
m_SpecConstantMap.clear();
m_SharedFunctionMembers.clear();
}

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

virtual void OnConstantBufferBinding(const std::string &name, int bindIndex) {}
virtual void OnTextureBinding(const std::string &name, int bindIndex, int samplerIndex, HLSLCC_TEX_DIMENSION dim, bool isUAV) {}
virtual void OnTextureBinding(const std::string &name, int bindIndex, int samplerIndex, bool multisampled, HLSLCC_TEX_DIMENSION dim, bool isUAV) {}
virtual void OnBufferBinding(const std::string &name, int bindIndex, bool isUAV) {}
virtual void OnThreadGroupSize(unsigned int xSize, unsigned int ySize, unsigned int zSize) {}
virtual void OnTessellationInfo(uint32_t tessPartitionMode, uint32_t tessOutputWindingOrder, uint32_t tessMaxFactor, uint32_t tessNumPatchesInThreadGroup) {}
virtual void OnTessellationKernelInfo(uint32_t patchKernelBufferCount) {}
};


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

// Massage shader steps into Metal compute kernel from vertex/hull shaders + post-tessellation vertex shader from domain shader

This comment has been minimized.

Copy link
@Xottab-DUTY

Xottab-DUTY Dec 27, 2018

Massage?

static const unsigned int HLSLCC_FLAG_METAL_TESSELLATION = 0x2000000;

// Disable fastmath
static const unsigned int HLSLCC_FLAG_DISABLE_FASTMATH = 0x4000000;

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/ControlFlowGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ void BasicBlock::RVarUnion(ReachableVariables &a, const ReachableVariables &b)
#define UNITY_EXTERNAL_TOOL 1
#include "Testing.h" // From Runtime/Testing

UNIT_TEST_SUITE(HLSLccTests)
UNIT_TEST_SUITE(HLSLcc)
{
TEST(ControlFlowGraph_Build_Simple_Works)
{
Expand Down
31 changes: 22 additions & 9 deletions src/DataTypeAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,15 +451,23 @@ void HLSLcc::DataTypeAnalysis::SetDataTypes(HLSLCrossCompilerContext* psContext,
break;

case OPCODE_RESINFO:
{
if (psInst->eResInfoReturnType != RESINFO_INSTRUCTION_RETURN_UINT)
MarkAllOperandsAs(psInst, SVT_FLOAT, aeTempVecType);
break;
}
// Operand 0 depends on the return type declaration, op 1 is always uint
MarkOperandAs(&psInst->asOperands[1], SVT_UINT, aeTempVecType);
switch (psInst->eResInfoReturnType)
{
default:
case RESINFO_INSTRUCTION_RETURN_FLOAT:
case RESINFO_INSTRUCTION_RETURN_RCPFLOAT:
MarkOperandAs(&psInst->asOperands[0], SVT_FLOAT, aeTempVecType);
break;
case RESINFO_INSTRUCTION_RETURN_UINT:
MarkOperandAs(&psInst->asOperands[0], SVT_UINT, aeTempVecType);
break;
}

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

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

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

Expand Down Expand Up @@ -507,9 +516,13 @@ void HLSLcc::DataTypeAnalysis::SetDataTypes(HLSLCrossCompilerContext* psContext,
break;

case OPCODE_F32TOF16:
MarkOperandAs(&psInst->asOperands[0], SVT_UINT, aeTempVecType);
MarkOperandAs(&psInst->asOperands[1], SVT_FLOAT, aeTempVecType);
break;

case OPCODE_F16TOF32:
// TODO
ASSERT(0);
MarkOperandAs(&psInst->asOperands[0], SVT_FLOAT, aeTempVecType);
MarkOperandAs(&psInst->asOperands[1], SVT_UINT, aeTempVecType);
break;


Expand Down
Loading

1 comment on commit 467d0a1

@Xottab-DUTY
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you give us a brief changelog, please?

Please sign in to comment.