HLSL: Broaden solution for #940, editing integer input for 'flat'.

This commit is contained in:
John Kessenich 2017-06-21 01:35:57 -06:00
parent f0bc598dd7
commit 4329d555ad
6 changed files with 249 additions and 46 deletions

View File

@ -35,22 +35,22 @@ gl_FragCoord origin is upper left
0:? Sequence
0:5 move second child to first child ( temp double)
0:? 'inDV1a' ( temp double)
0:? 'inDV1a' (layout( location=0) in double)
0:? 'inDV1a' (layout( location=0) flat in double)
0:5 move second child to first child ( temp double)
0:? 'inDV1b' ( temp double)
0:? 'inDV1b' (layout( location=1) in double)
0:? 'inDV1b' (layout( location=1) flat in double)
0:5 move second child to first child ( temp double)
0:? 'inDV1c' ( temp double)
0:? 'inDV1c' (layout( location=2) in double)
0:? 'inDV1c' (layout( location=2) flat in double)
0:5 move second child to first child ( temp 2-component vector of double)
0:? 'inDV2' ( temp 2-component vector of double)
0:? 'inDV2' (layout( location=3) in 2-component vector of double)
0:? 'inDV2' (layout( location=3) flat in 2-component vector of double)
0:5 move second child to first child ( temp 3-component vector of double)
0:? 'inDV3' ( temp 3-component vector of double)
0:? 'inDV3' (layout( location=4) in 3-component vector of double)
0:? 'inDV3' (layout( location=4) flat in 3-component vector of double)
0:5 move second child to first child ( temp 4-component vector of double)
0:? 'inDV4' ( temp 4-component vector of double)
0:? 'inDV4' (layout( location=6) in 4-component vector of double)
0:? 'inDV4' (layout( location=6) flat in 4-component vector of double)
0:5 move second child to first child ( temp uint)
0:? 'inU1a' ( temp uint)
0:? 'inU1a' (layout( location=8) flat in uint)
@ -70,12 +70,12 @@ gl_FragCoord origin is upper left
0:? 'inU1b' ( temp uint)
0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out float)
0:? 'inDV1a' (layout( location=0) in double)
0:? 'inDV1b' (layout( location=1) in double)
0:? 'inDV1c' (layout( location=2) in double)
0:? 'inDV2' (layout( location=3) in 2-component vector of double)
0:? 'inDV3' (layout( location=4) in 3-component vector of double)
0:? 'inDV4' (layout( location=6) in 4-component vector of double)
0:? 'inDV1a' (layout( location=0) flat in double)
0:? 'inDV1b' (layout( location=1) flat in double)
0:? 'inDV1c' (layout( location=2) flat in double)
0:? 'inDV2' (layout( location=3) flat in 2-component vector of double)
0:? 'inDV3' (layout( location=4) flat in 3-component vector of double)
0:? 'inDV4' (layout( location=6) flat in 4-component vector of double)
0:? 'inU1a' (layout( location=8) flat in uint)
0:? 'inU1b' (layout( location=9) flat in uint)
@ -119,22 +119,22 @@ gl_FragCoord origin is upper left
0:? Sequence
0:5 move second child to first child ( temp double)
0:? 'inDV1a' ( temp double)
0:? 'inDV1a' (layout( location=0) in double)
0:? 'inDV1a' (layout( location=0) flat in double)
0:5 move second child to first child ( temp double)
0:? 'inDV1b' ( temp double)
0:? 'inDV1b' (layout( location=1) in double)
0:? 'inDV1b' (layout( location=1) flat in double)
0:5 move second child to first child ( temp double)
0:? 'inDV1c' ( temp double)
0:? 'inDV1c' (layout( location=2) in double)
0:? 'inDV1c' (layout( location=2) flat in double)
0:5 move second child to first child ( temp 2-component vector of double)
0:? 'inDV2' ( temp 2-component vector of double)
0:? 'inDV2' (layout( location=3) in 2-component vector of double)
0:? 'inDV2' (layout( location=3) flat in 2-component vector of double)
0:5 move second child to first child ( temp 3-component vector of double)
0:? 'inDV3' ( temp 3-component vector of double)
0:? 'inDV3' (layout( location=4) in 3-component vector of double)
0:? 'inDV3' (layout( location=4) flat in 3-component vector of double)
0:5 move second child to first child ( temp 4-component vector of double)
0:? 'inDV4' ( temp 4-component vector of double)
0:? 'inDV4' (layout( location=6) in 4-component vector of double)
0:? 'inDV4' (layout( location=6) flat in 4-component vector of double)
0:5 move second child to first child ( temp uint)
0:? 'inU1a' ( temp uint)
0:? 'inU1a' (layout( location=8) flat in uint)
@ -154,12 +154,12 @@ gl_FragCoord origin is upper left
0:? 'inU1b' ( temp uint)
0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out float)
0:? 'inDV1a' (layout( location=0) in double)
0:? 'inDV1b' (layout( location=1) in double)
0:? 'inDV1c' (layout( location=2) in double)
0:? 'inDV2' (layout( location=3) in 2-component vector of double)
0:? 'inDV3' (layout( location=4) in 3-component vector of double)
0:? 'inDV4' (layout( location=6) in 4-component vector of double)
0:? 'inDV1a' (layout( location=0) flat in double)
0:? 'inDV1b' (layout( location=1) flat in double)
0:? 'inDV1c' (layout( location=2) flat in double)
0:? 'inDV2' (layout( location=3) flat in 2-component vector of double)
0:? 'inDV3' (layout( location=4) flat in 3-component vector of double)
0:? 'inDV4' (layout( location=6) flat in 4-component vector of double)
0:? 'inU1a' (layout( location=8) flat in uint)
0:? 'inU1b' (layout( location=9) flat in uint)
@ -211,11 +211,17 @@ gl_FragCoord origin is upper left
Name 83 "param"
Name 85 "param"
Name 87 "param"
Decorate 44(inDV1a) Flat
Decorate 44(inDV1a) Location 0
Decorate 47(inDV1b) Flat
Decorate 47(inDV1b) Location 1
Decorate 50(inDV1c) Flat
Decorate 50(inDV1c) Location 2
Decorate 54(inDV2) Flat
Decorate 54(inDV2) Location 3
Decorate 58(inDV3) Flat
Decorate 58(inDV3) Location 4
Decorate 62(inDV4) Flat
Decorate 62(inDV4) Location 6
Decorate 66(inU1a) Flat
Decorate 66(inU1a) Location 8

View File

@ -79,7 +79,7 @@ gl_FragCoord origin is upper left
0:? 's' ( temp structure{ temp 4-component vector of float a, temp bool b, temp 1-component vector of float c, temp 2-component vector of float d, temp bool ff1, temp bool ff2, temp bool ff3, temp 4-component vector of float ff4})
0:40 Constant:
0:40 4 (const int)
0:? 's_ff1' ( in bool Face)
0:? 's_ff1' ( flat in bool Face)
0:40 move second child to first child ( temp bool)
0:40 ff2: direct index for structure ( temp bool)
0:? 's' ( temp structure{ temp 4-component vector of float a, temp bool b, temp 1-component vector of float c, temp 2-component vector of float d, temp bool ff1, temp bool ff2, temp bool ff3, temp 4-component vector of float ff4})
@ -118,7 +118,7 @@ gl_FragCoord origin is upper left
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:? 'input' (layout( location=0) in 4-component vector of float)
0:? 's' (layout( location=1) in structure{ smooth temp 4-component vector of float a, flat temp bool b, centroid noperspective temp 1-component vector of float c, centroid sample temp 2-component vector of float d, flat temp bool ff2, flat temp bool ff3, temp 4-component vector of float ff4})
0:? 's_ff1' ( in bool Face)
0:? 's_ff1' ( flat in bool Face)
Linked fragment stage:
@ -200,7 +200,7 @@ gl_FragCoord origin is upper left
0:? 's' ( temp structure{ temp 4-component vector of float a, temp bool b, temp 1-component vector of float c, temp 2-component vector of float d, temp bool ff1, temp bool ff2, temp bool ff3, temp 4-component vector of float ff4})
0:40 Constant:
0:40 4 (const int)
0:? 's_ff1' ( in bool Face)
0:? 's_ff1' ( flat in bool Face)
0:40 move second child to first child ( temp bool)
0:40 ff2: direct index for structure ( temp bool)
0:? 's' ( temp structure{ temp 4-component vector of float a, temp bool b, temp 1-component vector of float c, temp 2-component vector of float d, temp bool ff1, temp bool ff2, temp bool ff3, temp 4-component vector of float ff4})
@ -239,7 +239,7 @@ gl_FragCoord origin is upper left
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:? 'input' (layout( location=0) in 4-component vector of float)
0:? 's' (layout( location=1) in structure{ smooth temp 4-component vector of float a, flat temp bool b, centroid noperspective temp 1-component vector of float c, centroid sample temp 2-component vector of float d, flat temp bool ff2, flat temp bool ff3, temp 4-component vector of float ff4})
0:? 's_ff1' ( in bool Face)
0:? 's_ff1' ( flat in bool Face)
// Module Version 10000
// Generated by (magic number): 80001
@ -309,6 +309,7 @@ gl_FragCoord origin is upper left
MemberDecorate 54(IN_S) 4 Flat
MemberDecorate 54(IN_S) 5 Flat
Decorate 56(s) Location 1
Decorate 79(s_ff1) Flat
Decorate 79(s_ff1) BuiltIn FrontFacing
Decorate 94(@entryPointOutput) Location 0
MemberDecorate 101(myS) 0 Offset 0

View File

@ -0,0 +1,151 @@
hlsl.synthesizeInput.frag
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:7 Function Definition: @main(struct-PSInput-f1-u11; ( temp 4-component vector of float)
0:7 Function Parameters:
0:7 'input' ( in structure{ temp float interp, temp uint no_interp})
0:? Sequence
0:8 Branch: Return with expression
0:? Construct vec4 ( temp 4-component vector of float)
0:8 Convert uint to float ( temp float)
0:8 no_interp: direct index for structure ( temp uint)
0:8 'input' ( in structure{ temp float interp, temp uint no_interp})
0:8 Constant:
0:8 1 (const int)
0:8 interp: direct index for structure ( temp float)
0:8 'input' ( in structure{ temp float interp, temp uint no_interp})
0:8 Constant:
0:8 0 (const int)
0:8 Constant:
0:8 0.000000
0:8 Constant:
0:8 1.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 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:7 Function Call: @main(struct-PSInput-f1-u11; ( temp 4-component vector of float)
0:? 'input' ( temp structure{ temp float interp, temp uint no_interp})
0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:? 'input' (layout( location=0) in structure{ temp float interp, flat temp uint no_interp})
Linked fragment stage:
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:7 Function Definition: @main(struct-PSInput-f1-u11; ( temp 4-component vector of float)
0:7 Function Parameters:
0:7 'input' ( in structure{ temp float interp, temp uint no_interp})
0:? Sequence
0:8 Branch: Return with expression
0:? Construct vec4 ( temp 4-component vector of float)
0:8 Convert uint to float ( temp float)
0:8 no_interp: direct index for structure ( temp uint)
0:8 'input' ( in structure{ temp float interp, temp uint no_interp})
0:8 Constant:
0:8 1 (const int)
0:8 interp: direct index for structure ( temp float)
0:8 'input' ( in structure{ temp float interp, temp uint no_interp})
0:8 Constant:
0:8 0 (const int)
0:8 Constant:
0:8 0.000000
0:8 Constant:
0:8 1.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 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:7 Function Call: @main(struct-PSInput-f1-u11; ( temp 4-component vector of float)
0:? 'input' ( temp structure{ temp float interp, temp uint no_interp})
0:? Linker Objects
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:? 'input' (layout( location=0) in structure{ temp float interp, flat temp uint no_interp})
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 44
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 33 40
ExecutionMode 4 OriginUpperLeft
Source HLSL 500
Name 4 "main"
Name 8 "PSInput"
MemberName 8(PSInput) 0 "interp"
MemberName 8(PSInput) 1 "no_interp"
Name 13 "@main(struct-PSInput-f1-u11;"
Name 12 "input"
Name 30 "input"
Name 31 "PSInput"
MemberName 31(PSInput) 0 "interp"
MemberName 31(PSInput) 1 "no_interp"
Name 33 "input"
Name 40 "@entryPointOutput"
Name 41 "param"
MemberDecorate 31(PSInput) 1 Flat
Decorate 33(input) Location 0
Decorate 40(@entryPointOutput) Location 0
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: TypeFunction 10(fvec4) 9(ptr)
15: TypeInt 32 1
16: 15(int) Constant 1
17: TypePointer Function 7(int)
21: 15(int) Constant 0
22: TypePointer Function 6(float)
25: 6(float) Constant 0
26: 6(float) Constant 1065353216
31(PSInput): TypeStruct 6(float) 7(int)
32: TypePointer Input 31(PSInput)
33(input): 32(ptr) Variable Input
39: TypePointer Output 10(fvec4)
40(@entryPointOutput): 39(ptr) Variable Output
4(main): 2 Function None 3
5: Label
30(input): 9(ptr) Variable Function
41(param): 9(ptr) Variable Function
34: 31(PSInput) Load 33(input)
35: 6(float) CompositeExtract 34 0
36: 22(ptr) AccessChain 30(input) 21
Store 36 35
37: 7(int) CompositeExtract 34 1
38: 17(ptr) AccessChain 30(input) 16
Store 38 37
42: 8(PSInput) Load 30(input)
Store 41(param) 42
43: 10(fvec4) FunctionCall 13(@main(struct-PSInput-f1-u11;) 41(param)
Store 40(@entryPointOutput) 43
Return
FunctionEnd
13(@main(struct-PSInput-f1-u11;): 10(fvec4) Function None 11
12(input): 9(ptr) FunctionParameter
14: Label
18: 17(ptr) AccessChain 12(input) 16
19: 7(int) Load 18
20: 6(float) ConvertUToF 19
23: 22(ptr) AccessChain 12(input) 21
24: 6(float) Load 23
27: 10(fvec4) CompositeConstruct 20 24 25 26
ReturnValue 27
FunctionEnd

View File

@ -0,0 +1,9 @@
struct PSInput {
float interp;
uint no_interp;
};
float4 main(PSInput input : INPUT) : SV_TARGET
{
return float4(float(input.no_interp), input.interp, 0, 1);
}

View File

@ -275,6 +275,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.structin.vert", "main"},
{"hlsl.structIoFourWay.frag", "main"},
{"hlsl.structStructName.frag", "main"},
{"hlsl.synthesizeInput.frag", "main"},
{"hlsl.texture.subvec4.frag", "main"},
{"hlsl.this.frag", "main"},
{"hlsl.intrinsics.vert", "VertexShaderFunction"},

View File

@ -1527,8 +1527,6 @@ void HlslParseContext::fixBuiltInIoType(TType& type)
// Variables that correspond to the user-interface in and out of a stage
// (not the built-in interface) are
// - assigned locations
// - corrected for interpolation
// * non-floating point values must be nointerpolation
// - registered as a linkage node (part of the stage's external interface).
// Assumes it is called in the order in which locations should be assigned.
void HlslParseContext::assignToInterface(TVariable& variable)
@ -1554,21 +1552,6 @@ void HlslParseContext::assignToInterface(TVariable& variable)
nextOutLocation += size;
}
}
if (qualifier.storage == EvqVaryingIn && language == EShLangFragment) {
// Going into the fragment stage, integer-based stuff must be flat/nointerpolation
const auto fixQualifier = [](TType& type) {
if (type.getQualifier().builtIn == EbvNone &&
(type.isIntegerDomain() || type.getBasicType() == EbtBool)) {
type.getQualifier().clearInterpolation();
type.getQualifier().flat = true;
}
};
if (type.isStruct())
for (auto mem = (*type.getStruct()).begin(); mem != (*type.getStruct()).end(); ++mem)
fixQualifier(*mem->type);
else
fixQualifier(type);
}
trackLinkage(variable);
}
};
@ -2134,12 +2117,63 @@ void HlslParseContext::handleFunctionBody(const TSourceLoc& loc, TFunction& func
void HlslParseContext::remapEntryPointIO(TFunction& function, TVariable*& returnValue,
TVector<TVariable*>& inputs, TVector<TVariable*>& outputs)
{
// We might have in input structure type with no decorations that caused it
// to look like an input type, yet it has (e.g.) interpolation types that
// must be modified that turn it into an input type.
// Hence, a missing ioTypeMap for 'input' might need to be synthesized.
const auto synthesizeEditedInput = [this](TType& type) {
// True if a type needs to be 'flat'
const auto needsFlat = [](const TType& type) {
return type.containsBasicType(EbtInt) ||
type.containsBasicType(EbtUint) ||
type.containsBasicType(EbtInt64) ||
type.containsBasicType(EbtUint64) ||
type.containsBasicType(EbtBool) ||
type.containsBasicType(EbtDouble);
};
if (language == EShLangFragment && needsFlat(type)) {
if (type.isStruct()) {
TTypeList* finalList = nullptr;
auto it = ioTypeMap.find(type.getStruct());
if (it == ioTypeMap.end() || it->second.input == nullptr) {
// Getting here means we have no input struct, but we need one.
auto list = new TTypeList;
for (auto member = type.getStruct()->begin(); member != type.getStruct()->end(); ++member) {
TType* newType = new TType;
newType->shallowCopy(*member->type);
TTypeLoc typeLoc = { newType, member->loc };
list->push_back(typeLoc);
}
// install the new input type
if (it == ioTypeMap.end()) {
tIoKinds newLists = { list, nullptr, nullptr };
ioTypeMap[type.getStruct()] = newLists;
} else
it->second.input = list;
finalList = list;
} else
finalList = it->second.input;
// edit for 'flat'
for (auto member = finalList->begin(); member != finalList->end(); ++member) {
if (needsFlat(*member->type)) {
member->type->getQualifier().clearInterpolation();
member->type->getQualifier().flat = true;
}
}
} else {
type.getQualifier().clearInterpolation();
type.getQualifier().flat = true;
}
}
};
// Do the actual work to make a type be a shader input or output variable,
// and clear the original to be non-IO (for use as a normal function parameter/return).
const auto makeIoVariable = [this](const char* name, TType& type, TStorageQualifier storage) -> TVariable* {
TVariable* ioVariable = makeInternalVariable(name, type);
clearUniformInputOutput(type.getQualifier());
if (type.getStruct() != nullptr) {
if (type.isStruct()) {
auto newLists = ioTypeMap.find(ioVariable->getType().getStruct());
if (newLists != ioTypeMap.end()) {
if (storage == EvqVaryingIn && newLists->second.input)
@ -2192,6 +2226,7 @@ void HlslParseContext::remapEntryPointIO(TFunction& function, TVariable*& return
for (int i = 0; i < function.getParamCount(); i++) {
TType& paramType = *function[i].type;
if (paramType.getQualifier().isParamInput()) {
synthesizeEditedInput(paramType);
TVariable* argAsGlobal = makeIoVariable(function[i].name->c_str(), paramType, EvqVaryingIn);
inputs.push_back(argAsGlobal);