Commit 89f8d1e6 by John Kessenich

HLSL: Fix #942: Map SV_TargetN to SPV Location N.

parent 4f54c0c4
hlsl.target.frag
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:7 Function Definition: @main(struct-PSInput-f1-u11;vf4;vf4; ( temp void)
0:7 Function Parameters:
0:7 'input' ( in structure{ temp float interp, temp uint no_interp})
0:7 'out1' ( out 4-component vector of float)
0:7 'out2' ( out 4-component vector of float)
0:? Sequence
0:8 move second child to first child ( temp 4-component vector of float)
0:8 'out1' ( out 4-component vector of float)
0:8 Constant:
0:8 1.000000
0:8 1.000000
0:8 1.000000
0:8 1.000000
0:9 move second child to first child ( temp 4-component vector of float)
0:9 'out2' ( out 4-component vector of float)
0:9 Constant:
0:9 0.000000
0:9 0.000000
0:9 0.000000
0:9 0.000000
0:7 Function Definition: main( ( temp void)
0:7 Function Parameters:
0:? Sequence
0:7 move second child to first child ( temp structure{ temp float interp, temp uint no_interp})
0:? 'input' ( temp structure{ temp float interp, temp uint no_interp})
0:? 'input' (layout( location=0) in structure{ temp float interp, flat temp uint no_interp})
0:7 Function Call: @main(struct-PSInput-f1-u11;vf4;vf4; ( temp void)
0:? 'input' ( temp structure{ temp float interp, temp uint no_interp})
0:? 'out1' ( temp 4-component vector of float)
0:? 'out2' ( temp 4-component vector of float)
0:7 move second child to first child ( temp 4-component vector of float)
0:? 'out1' (layout( location=1) out 4-component vector of float)
0:? 'out1' ( temp 4-component vector of float)
0:7 move second child to first child ( temp 4-component vector of float)
0:? 'out2' (layout( location=3) out 4-component vector of float)
0:? 'out2' ( temp 4-component vector of float)
0:? Linker Objects
0:? 'input' (layout( location=0) in structure{ temp float interp, flat temp uint no_interp})
0:? 'out1' (layout( location=1) out 4-component vector of float)
0:? 'out2' (layout( location=3) out 4-component vector of float)
Linked fragment stage:
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:7 Function Definition: @main(struct-PSInput-f1-u11;vf4;vf4; ( temp void)
0:7 Function Parameters:
0:7 'input' ( in structure{ temp float interp, temp uint no_interp})
0:7 'out1' ( out 4-component vector of float)
0:7 'out2' ( out 4-component vector of float)
0:? Sequence
0:8 move second child to first child ( temp 4-component vector of float)
0:8 'out1' ( out 4-component vector of float)
0:8 Constant:
0:8 1.000000
0:8 1.000000
0:8 1.000000
0:8 1.000000
0:9 move second child to first child ( temp 4-component vector of float)
0:9 'out2' ( out 4-component vector of float)
0:9 Constant:
0:9 0.000000
0:9 0.000000
0:9 0.000000
0:9 0.000000
0:7 Function Definition: main( ( temp void)
0:7 Function Parameters:
0:? Sequence
0:7 move second child to first child ( temp structure{ temp float interp, temp uint no_interp})
0:? 'input' ( temp structure{ temp float interp, temp uint no_interp})
0:? 'input' (layout( location=0) in structure{ temp float interp, flat temp uint no_interp})
0:7 Function Call: @main(struct-PSInput-f1-u11;vf4;vf4; ( temp void)
0:? 'input' ( temp structure{ temp float interp, temp uint no_interp})
0:? 'out1' ( temp 4-component vector of float)
0:? 'out2' ( temp 4-component vector of float)
0:7 move second child to first child ( temp 4-component vector of float)
0:? 'out1' (layout( location=1) out 4-component vector of float)
0:? 'out1' ( temp 4-component vector of float)
0:7 move second child to first child ( temp 4-component vector of float)
0:? 'out2' (layout( location=3) out 4-component vector of float)
0:? 'out2' ( temp 4-component vector of float)
0:? Linker Objects
0:? 'input' (layout( location=0) in structure{ temp float interp, flat temp uint no_interp})
0:? 'out1' (layout( location=1) out 4-component vector of float)
0:? 'out2' (layout( location=3) out 4-component vector of float)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 50
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 25 46 48
ExecutionMode 4 OriginUpperLeft
Source HLSL 500
Name 4 "main"
Name 8 "PSInput"
MemberName 8(PSInput) 0 "interp"
MemberName 8(PSInput) 1 "no_interp"
Name 16 "@main(struct-PSInput-f1-u11;vf4;vf4;"
Name 13 "input"
Name 14 "out1"
Name 15 "out2"
Name 22 "input"
Name 23 "PSInput"
MemberName 23(PSInput) 0 "interp"
MemberName 23(PSInput) 1 "no_interp"
Name 25 "input"
Name 36 "out1"
Name 37 "out2"
Name 38 "param"
Name 40 "param"
Name 41 "param"
Name 46 "out1"
Name 48 "out2"
MemberDecorate 23(PSInput) 1 Flat
Decorate 25(input) Location 0
Decorate 46(out1) Location 1
Decorate 48(out2) Location 3
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeInt 32 0
8(PSInput): TypeStruct 6(float) 7(int)
9: TypePointer Function 8(PSInput)
10: TypeVector 6(float) 4
11: TypePointer Function 10(fvec4)
12: TypeFunction 2 9(ptr) 11(ptr) 11(ptr)
18: 6(float) Constant 1065353216
19: 10(fvec4) ConstantComposite 18 18 18 18
20: 6(float) Constant 0
21: 10(fvec4) ConstantComposite 20 20 20 20
23(PSInput): TypeStruct 6(float) 7(int)
24: TypePointer Input 23(PSInput)
25(input): 24(ptr) Variable Input
28: TypeInt 32 1
29: 28(int) Constant 0
30: TypePointer Function 6(float)
33: 28(int) Constant 1
34: TypePointer Function 7(int)
45: TypePointer Output 10(fvec4)
46(out1): 45(ptr) Variable Output
48(out2): 45(ptr) Variable Output
4(main): 2 Function None 3
5: Label
22(input): 9(ptr) Variable Function
36(out1): 11(ptr) Variable Function
37(out2): 11(ptr) Variable Function
38(param): 9(ptr) Variable Function
40(param): 11(ptr) Variable Function
41(param): 11(ptr) Variable Function
26: 23(PSInput) Load 25(input)
27: 6(float) CompositeExtract 26 0
31: 30(ptr) AccessChain 22(input) 29
Store 31 27
32: 7(int) CompositeExtract 26 1
35: 34(ptr) AccessChain 22(input) 33
Store 35 32
39: 8(PSInput) Load 22(input)
Store 38(param) 39
42: 2 FunctionCall 16(@main(struct-PSInput-f1-u11;vf4;vf4;) 38(param) 40(param) 41(param)
43: 10(fvec4) Load 40(param)
Store 36(out1) 43
44: 10(fvec4) Load 41(param)
Store 37(out2) 44
47: 10(fvec4) Load 36(out1)
Store 46(out1) 47
49: 10(fvec4) Load 37(out2)
Store 48(out2) 49
Return
FunctionEnd
16(@main(struct-PSInput-f1-u11;vf4;vf4;): 2 Function None 12
13(input): 9(ptr) FunctionParameter
14(out1): 11(ptr) FunctionParameter
15(out2): 11(ptr) FunctionParameter
17: Label
Store 14(out1) 19
Store 15(out2) 21
Return
FunctionEnd
struct PSInput {
float interp;
uint no_interp;
};
void main(PSInput input : INPUT, out float4 out1 : SV_TARGET1, out float4 out2 : SV_TARGET3)
{
out1 = 1;
out2 = 0;
}
\ No newline at end of file
struct PSInput {
float interp;
uint no_interp;
};
struct PSOutput {
float4 o1 : SV_TARGET2;
float4 o2 : SV_TARGET1;
};
PSOutput main(PSInput input : INPUT, out float4 po : SV_TARGET0)
{
PSOutput pso;
pso.o1 = float4(float(input.no_interp), input.interp, 0, 1);
pso.o2 = 1;
po = 0;
return pso;
}
\ No newline at end of file
struct PSInput {
float interp;
uint no_interp;
};
struct PSOutput {
float4 o1 : SV_TARGET1;
float4 o2 : SV_TARGET0;
};
PSOutput main(PSInput input : INPUT, out float4 po : SV_TARGET0) : SV_TARGET2
{
PSOutput pso;
pso.o1 = float4(float(input.no_interp), input.interp, 0, 1);
pso.o2 = 1;
po = 0;
return pso;
}
\ No newline at end of file
......@@ -300,6 +300,9 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.struct.frag", "PixelShaderFunction"},
{"hlsl.switch.frag", "PixelShaderFunction"},
{"hlsl.swizzle.frag", "PixelShaderFunction"},
{"hlsl.target.frag", "main"},
{"hlsl.targetStruct1.frag", "main"},
{"hlsl.targetStruct2.frag", "main"},
{"hlsl.templatetypes.frag", "PixelShaderFunction"},
{"hlsl.tx.bracket.frag", "main"},
{"hlsl.tx.overload.frag", "main"},
......
......@@ -1174,7 +1174,8 @@ void HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable)
const TType& type = variable.getType();
auto entry = flattenMap.insert(std::make_pair(variable.getUniqueId(),
TFlattenData(type.getQualifier().layoutBinding)));
TFlattenData(type.getQualifier().layoutBinding,
type.getQualifier().layoutLocation)));
// the item is a map pair, so first->second is the TFlattenData itself.
flatten(loc, variable, type, entry.first->second, "");
......@@ -1236,6 +1237,19 @@ int HlslParseContext::addFlattenedMember(const TSourceLoc& loc,
if (flattenData.nextBinding != TQualifier::layoutBindingEnd)
memberVariable->getWritableType().getQualifier().layoutBinding = flattenData.nextBinding++;
if (memberVariable->getType().getQualifier().builtIn == EbvNone) {
// inherited locations must be auto bumped, not replicated
if (flattenData.nextLocation != TQualifier::layoutLocationEnd &&
memberVariable->getType().getQualifier().builtIn == EbvNone) {
memberVariable->getWritableType().getQualifier().layoutLocation = flattenData.nextLocation;
flattenData.nextLocation += intermediate.computeTypeLocationSize(memberVariable->getType());
nextOutLocation = std::max(nextOutLocation, flattenData.nextLocation);
}
} else {
// inherited locations are nonsensical for built-ins
memberVariable->getWritableType().getQualifier().layoutLocation = TQualifier::layoutLocationEnd;
}
flattenData.offsets.push_back(static_cast<int>(flattenData.members.size()));
flattenData.members.push_back(memberVariable);
......@@ -1551,7 +1565,7 @@ void HlslParseContext::assignToInterface(TVariable& variable)
TType& type = variable.getWritableType();
TQualifier& qualifier = type.getQualifier();
if (qualifier.storage == EvqVaryingIn || qualifier.storage == EvqVaryingOut) {
if (qualifier.builtIn == EbvNone) {
if (qualifier.builtIn == EbvNone && !qualifier.hasLocation()) {
// Strip off the outer array dimension for those having an extra one.
int size;
if (type.isArray() && qualifier.isArrayedIo(language)) {
......@@ -1991,7 +2005,7 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
assignToInterface(variable);
};
if (entryPointOutput)
if (entryPointOutput != nullptr)
makeVariableInOut(*entryPointOutput);
for (auto it = inputs.begin(); it != inputs.end(); ++it)
if (!isDsPcfInput((*it)->getType())) // skip domain shader PCF input (see comment below)
......@@ -5211,12 +5225,27 @@ TFunction* HlslParseContext::makeConstructorCall(const TSourceLoc& loc, const TT
// Handle seeing a "COLON semantic" at the end of a type declaration,
// by updating the type according to the semantic.
//
void HlslParseContext::handleSemantic(TSourceLoc loc, TQualifier& qualifier, TBuiltInVariable builtIn, const TString& upperCase)
void HlslParseContext::handleSemantic(TSourceLoc loc, TQualifier& qualifier, TBuiltInVariable builtIn,
const TString& upperCase)
{
// adjust for stage in/out
const auto getSemanticNumber = [](const TString& semantic) -> unsigned int {
size_t pos = semantic.find_last_not_of("0123456789");
if (pos == std::string::npos)
return 0u;
return (unsigned int)atoi(semantic.c_str() + pos + 1);
};
switch(builtIn) {
case EbvNone:
// Get location numbers from fragment outputs, instead of
// auto-assigning them.
if (language == EShLangFragment && upperCase.compare(0, 9, "SV_TARGET") == 0) {
qualifier.layoutLocation = getSemanticNumber(upperCase);
nextOutLocation = std::max(nextOutLocation, qualifier.layoutLocation + 1u);
}
break;
case EbvPosition:
// adjust for stage in/out
if (language == EShLangFragment)
builtIn = EbvFragCoord;
break;
......
......@@ -213,12 +213,14 @@ public:
protected:
struct TFlattenData {
TFlattenData() : nextBinding(TQualifier::layoutBindingEnd) { }
TFlattenData(int nb) : nextBinding(nb) { }
TFlattenData() : nextBinding(TQualifier::layoutBindingEnd),
nextLocation(TQualifier::layoutLocationEnd) { }
TFlattenData(int nb, int nl) : nextBinding(nb), nextLocation(nl) { }
TVector<TVariable*> members; // individual flattened variables
TVector<int> offsets; // offset to next tree level
int nextBinding; // next binding to use.
TVector<int> offsets; // offset to next tree level
unsigned int nextBinding; // next binding to use.
unsigned int nextLocation; // next location to use
};
void fixConstInit(const TSourceLoc&, const TString& identifier, TType& type, TIntermTyped*& initializer);
......
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