Commit f97f2ce6 by John Kessenich

HLSL: Support the constructor idiom "(struct type)0".

This highly leverages the previous commit to handle partial initializers.
parent 98ad4853
...@@ -8,15 +8,22 @@ struct outs { ...@@ -8,15 +8,22 @@ struct outs {
static float4 gv = {0,0,1}; static float4 gv = {0,0,1};
static float gfa[3] = {0,0}; static float gfa[3] = {0,0};
struct Nest {
float4x3 m;
outs os;
bool b;
};
outs PixelShaderFunction(float4 input) : COLOR0 outs PixelShaderFunction(float4 input) : COLOR0
{ {
outs o2 = { 3 }; outs o2 = { 3 };
outs o4; outs o4;
o4.v = gv * gfa[2]; o4.v = gv * gfa[2];
outs o1 = { }; outs o1 = { };
// outs o3 = (outs)0; outs o3 = (outs)0;
// o4 = (outs)0; o4 = (outs)0;
o4.c = o1.c; o4.c = o1.c;
Nest nest = (Nest)0;
return o4; return o4;
} }
\ No newline at end of file
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits. // For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run). // For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "Overload400-PrecQual.1665" #define GLSLANG_REVISION "Overload400-PrecQual.1666"
#define GLSLANG_DATE "27-Nov-2016" #define GLSLANG_DATE "27-Nov-2016"
...@@ -3285,7 +3285,7 @@ bool HlslParseContext::builtInName(const TString& /*identifier*/) ...@@ -3285,7 +3285,7 @@ bool HlslParseContext::builtInName(const TString& /*identifier*/)
// //
// Returns true if there was an error in construction. // Returns true if there was an error in construction.
// //
bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* /*node*/, TFunction& function, bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, TFunction& function,
TOperator op, TType& type) TOperator op, TType& type)
{ {
type.shallowCopy(function.getType()); type.shallowCopy(function.getType());
...@@ -3411,6 +3411,9 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* /*no ...@@ -3411,6 +3411,9 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* /*no
return true; return true;
} }
if (op == EOpConstructStruct && ! type.isArray() && isZeroConstructor(node))
return false;
if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) { if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) {
error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", ""); error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
return true; return true;
...@@ -3422,11 +3425,15 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* /*no ...@@ -3422,11 +3425,15 @@ bool HlslParseContext::constructorError(const TSourceLoc& loc, TIntermNode* /*no
return true; return true;
} }
// TIntermTyped* typed = node->getAsTyped();
return false; return false;
} }
bool HlslParseContext::isZeroConstructor(const TIntermNode* node)
{
return node->getAsTyped()->isScalar() && node->getAsConstantUnion() &&
node->getAsConstantUnion()->getConstArray()[0].getIConst() == 0;
}
// Verify all the correct semantics for constructing a combined texture/sampler. // Verify all the correct semantics for constructing a combined texture/sampler.
// Return true if the semantics are incorrect. // Return true if the semantics are incorrect.
bool HlslParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const TFunction& function) bool HlslParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const TFunction& function)
...@@ -4672,6 +4679,11 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm ...@@ -4672,6 +4679,11 @@ TIntermNode* HlslParseContext::executeInitializer(const TSourceLoc& loc, TInterm
// creating a constructor-style initializer, ensuring we get the // creating a constructor-style initializer, ensuring we get the
// same form. // same form.
// //
// Returns a node representing an expression for the initializer list expressed
// as the correct type.
//
// Returns nullptr if there is an error.
//
TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, const TType& type, TIntermTyped* initializer) TIntermTyped* HlslParseContext::convertInitializerList(const TSourceLoc& loc, const TType& type, TIntermTyped* initializer)
{ {
// Will operate recursively. Once a subtree is found that is constructor style, // Will operate recursively. Once a subtree is found that is constructor style,
...@@ -4808,6 +4820,10 @@ TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermNod ...@@ -4808,6 +4820,10 @@ TIntermTyped* HlslParseContext::addConstructor(const TSourceLoc& loc, TIntermNod
if (node == nullptr || node->getAsTyped() == nullptr) if (node == nullptr || node->getAsTyped() == nullptr)
return nullptr; return nullptr;
// Handle the idiom "(struct type)0"
if (type.isStruct() && isZeroConstructor(node))
return convertInitializerList(loc, type, intermediate.makeAggregate(loc));
TIntermAggregate* aggrNode = node->getAsAggregate(); TIntermAggregate* aggrNode = node->getAsAggregate();
TOperator op = intermediate.mapTypeToConstructorOp(type); TOperator op = intermediate.mapTypeToConstructorOp(type);
......
...@@ -172,6 +172,7 @@ protected: ...@@ -172,6 +172,7 @@ protected:
void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&, bool track); void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&, bool track);
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable); TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer); TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
bool HlslParseContext::isZeroConstructor(const TIntermNode*);
TOperator mapAtomicOp(const TSourceLoc& loc, TOperator op, bool isImage); TOperator mapAtomicOp(const TSourceLoc& loc, TOperator op, bool isImage);
// Return true if this node requires L-value conversion (e.g, to an imageStore). // Return true if this node requires L-value conversion (e.g, to an imageStore).
......
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