Commit 750c2d07 by John Kessenich

SPV: When passing structs of opaque types, flatten and pass the members instead.

This avoids either A) needing uniformConstant struct, or B) initializing a struct with opaque members, as writing them is not allowed.
parent d66c5b12
struct os {
sampler2D s2D;
};
struct os2 {
sampler2D s2D;
Texture2D tex;
};
Texture2D tex;
os s;
os2 s2;
float4 osCall1(os s)
{
return tex.Sample(s.s2D, float2(0.2, 0.3));
}
float4 osCall2(os s, float2 f2)
{
return tex.Sample(s.s2D, f2);
}
float4 os2Call1(os2 s)
{
return s.tex.Sample(s.s2D, float2(0.2, 0.3));
}
float4 os2Call2(os2 s, float2 f2)
{
return s.tex.Sample(s.s2D, f2);
}
float4 main() : SV_TARGET0
{
return osCall1(s) +
osCall2(s, float2(0.2, 0.3)) +
os2Call1(s2) +
os2Call2(s2, float2(0.2, 0.3));
}
...@@ -114,6 +114,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -114,6 +114,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.float1.frag", "PixelShaderFunction"}, {"hlsl.float1.frag", "PixelShaderFunction"},
{"hlsl.float4.frag", "PixelShaderFunction"}, {"hlsl.float4.frag", "PixelShaderFunction"},
{"hlsl.flatten.return.frag", "main"}, {"hlsl.flatten.return.frag", "main"},
{"hlsl.flattenOpaque.frag", "main"},
{"hlsl.forLoop.frag", "PixelShaderFunction"}, {"hlsl.forLoop.frag", "PixelShaderFunction"},
{"hlsl.gather.array.dx10.frag", "main"}, {"hlsl.gather.array.dx10.frag", "main"},
{"hlsl.gather.basic.dx10.frag", "main"}, {"hlsl.gather.basic.dx10.frag", "main"},
......
...@@ -96,6 +96,7 @@ public: ...@@ -96,6 +96,7 @@ public:
void decomposeGeometryMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments); void decomposeGeometryMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void pushFrontArguments(TIntermTyped* front, TIntermTyped*& arguments); void pushFrontArguments(TIntermTyped* front, TIntermTyped*& arguments);
void addInputArgumentConversions(const TFunction&, TIntermTyped*&); void addInputArgumentConversions(const TFunction&, TIntermTyped*&);
void expandArguments(const TSourceLoc&, const TFunction&, TIntermTyped*&);
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&); TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermOperator&);
void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&); void builtInOpCheck(const TSourceLoc&, const TFunction&, TIntermOperator&);
TFunction* makeConstructorCall(const TSourceLoc&, const TType&); TFunction* makeConstructorCall(const TSourceLoc&, const TType&);
...@@ -236,13 +237,14 @@ protected: ...@@ -236,13 +237,14 @@ protected:
// Array and struct flattening // Array and struct flattening
TIntermTyped* flattenAccess(TIntermTyped* base, int member); TIntermTyped* flattenAccess(TIntermTyped* base, int member);
bool shouldFlattenUniform(const TType&) const; TIntermTyped* flattenAccess(int uniqueId, int member, const TType&);
bool shouldFlatten(const TType&) const;
bool wasFlattened(const TIntermTyped* node) const; bool wasFlattened(const TIntermTyped* node) const;
bool wasFlattened(int id) const { return flattenMap.find(id) != flattenMap.end(); } bool wasFlattened(int id) const { return flattenMap.find(id) != flattenMap.end(); }
int addFlattenedMember(const TSourceLoc& loc, const TVariable&, const TType&, TFlattenData&, const TString& name, bool track); int addFlattenedMember(const TSourceLoc& loc, const TVariable&, const TType&, TFlattenData&, const TString& name, bool track);
bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); } bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); }
// Structure splitting (splits interstage builtin types into its own struct) // Structure splitting (splits interstage built-in types into its own struct)
TIntermTyped* splitAccessStruct(const TSourceLoc& loc, TIntermTyped*& base, int& member); TIntermTyped* splitAccessStruct(const TSourceLoc& loc, TIntermTyped*& base, int& member);
void splitAccessArray(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index); void splitAccessArray(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index);
TType& split(TType& type, TString name, const TType* outerStructType = nullptr); TType& split(TType& type, TString name, const TType* outerStructType = nullptr);
......
...@@ -502,7 +502,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c ...@@ -502,7 +502,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
static const EShLanguageMask EShLangAll = EShLanguageMask(EShLangCount - 1); static const EShLanguageMask EShLangAll = EShLanguageMask(EShLangCount - 1);
// These are the actual stage masks defined in the documentation, in case they are // These are the actual stage masks defined in the documentation, in case they are
// needed for furture validation. For now, they are commented out, and set below // needed for future validation. For now, they are commented out, and set below
// to EShLangAll, to allow any intrinsic to be used in any shader, which is legal // to EShLangAll, to allow any intrinsic to be used in any shader, which is legal
// if it is not called. // if it is not called.
// //
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment