Merge pull request #890 from LoopDawg/mip-operator

HLSL: add .mips[][] operator for texture types
This commit is contained in:
John Kessenich 2017-05-15 09:39:15 -06:00 committed by GitHub
commit 1a010b8368
10 changed files with 446 additions and 11 deletions

View File

@ -0,0 +1,68 @@
hlsl.mip.negative.frag
ERROR: 0:5: '' : unterminated mips operator:
ERROR: 1 compilation errors. No code generated.
Shader version: 500
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
0:4 Function Definition: @main( ( temp 4-component vector of float)
0:4 Function Parameters:
0:? Sequence
0:? textureFetch ( temp 4-component vector of float)
0:5 'g_tTex2df4' ( uniform texture2D)
0:? Constant:
0:? 3 (const uint)
0:? 4 (const uint)
0:5 Constant:
0:5 2 (const int)
0:7 Branch: Return with expression
0:7 Constant:
0:7 0.000000
0:7 0.000000
0:7 0.000000
0:7 0.000000
0:4 Function Definition: main( ( temp void)
0:4 Function Parameters:
0:? Sequence
0:4 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:4 Function Call: @main( ( temp 4-component vector of float)
0:? Linker Objects
0:? 'g_tTex2df4' ( uniform texture2D)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
Linked fragment stage:
Shader version: 500
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
0:4 Function Definition: @main( ( temp 4-component vector of float)
0:4 Function Parameters:
0:? Sequence
0:? textureFetch ( temp 4-component vector of float)
0:5 'g_tTex2df4' ( uniform texture2D)
0:? Constant:
0:? 3 (const uint)
0:? 4 (const uint)
0:5 Constant:
0:5 2 (const int)
0:7 Branch: Return with expression
0:7 Constant:
0:7 0.000000
0:7 0.000000
0:7 0.000000
0:7 0.000000
0:4 Function Definition: main( ( temp void)
0:4 Function Parameters:
0:? Sequence
0:4 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:4 Function Call: @main( ( temp 4-component vector of float)
0:? Linker Objects
0:? 'g_tTex2df4' ( uniform texture2D)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
SPIR-V is not generated for failed compile or link

View File

@ -0,0 +1,74 @@
hlsl.mip.negative2.frag
ERROR: 0:5: 'r' : unexpected operator on texture type: uniform texture2D
ERROR: 1 compilation errors. No code generated.
Shader version: 500
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
0:4 Function Definition: @main( ( temp 4-component vector of float)
0:4 Function Parameters:
0:? Sequence
0:5 direct index ( temp float)
0:5 textureFetch ( temp 4-component vector of float)
0:5 'g_tTex2df4' ( uniform texture2D)
0:5 Constant:
0:5 2 (const int)
0:5 Constant:
0:5 0 (const int)
0:? Constant:
0:? 3 (const uint)
0:? 4 (const uint)
0:7 Branch: Return with expression
0:7 Constant:
0:7 0.000000
0:7 0.000000
0:7 0.000000
0:7 0.000000
0:4 Function Definition: main( ( temp void)
0:4 Function Parameters:
0:? Sequence
0:4 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:4 Function Call: @main( ( temp 4-component vector of float)
0:? Linker Objects
0:? 'g_tTex2df4' ( uniform texture2D)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
Linked fragment stage:
Shader version: 500
gl_FragCoord origin is upper left
ERROR: node is still EOpNull!
0:4 Function Definition: @main( ( temp 4-component vector of float)
0:4 Function Parameters:
0:? Sequence
0:5 direct index ( temp float)
0:5 textureFetch ( temp 4-component vector of float)
0:5 'g_tTex2df4' ( uniform texture2D)
0:5 Constant:
0:5 2 (const int)
0:5 Constant:
0:5 0 (const int)
0:? Constant:
0:? 3 (const uint)
0:? 4 (const uint)
0:7 Branch: Return with expression
0:7 Constant:
0:7 0.000000
0:7 0.000000
0:7 0.000000
0:7 0.000000
0:4 Function Definition: main( ( temp void)
0:4 Function Parameters:
0:? Sequence
0:4 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:4 Function Call: @main( ( temp 4-component vector of float)
0:? Linker Objects
0:? 'g_tTex2df4' ( uniform texture2D)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
SPIR-V is not generated for failed compile or link

View File

@ -0,0 +1,209 @@
hlsl.mip.operator.frag
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:5 Function Definition: @main( ( temp 4-component vector of float)
0:5 Function Parameters:
0:? Sequence
0:13 Branch: Return with expression
0:9 add ( temp 4-component vector of float)
0:6 add ( temp 4-component vector of float)
0:? textureFetch ( temp 4-component vector of float)
0:6 'g_tTex2df4' ( uniform texture2D)
0:? Constant:
0:? 3 (const uint)
0:? 4 (const uint)
0:6 Constant:
0:6 2 (const int)
0:? textureFetch ( temp 4-component vector of float)
0:9 'g_tTex2df4a' ( uniform texture2DArray)
0:? Constant:
0:? 6 (const uint)
0:? 7 (const uint)
0:? 8 (const uint)
0:9 Constant:
0:9 5 (const uint)
0:13 textureFetch ( temp 4-component vector of float)
0:13 'g_tTex2df4' ( uniform texture2D)
0:13 Convert float to uint ( temp 2-component vector of uint)
0:13 vector swizzle ( temp 2-component vector of float)
0:? textureFetch ( temp 4-component vector of float)
0:13 'g_tTex2df4' ( uniform texture2D)
0:? Constant:
0:? 14 (const uint)
0:? 15 (const uint)
0:13 Constant:
0:13 13 (const int)
0:13 Sequence
0:13 Constant:
0:13 0 (const int)
0:13 Constant:
0:13 1 (const int)
0:13 Convert float to uint ( temp uint)
0:13 direct index ( temp float)
0:? textureFetch ( temp 4-component vector of float)
0:13 'g_tTex2df4' ( uniform texture2D)
0:? Constant:
0:? 10 (const uint)
0:? 11 (const uint)
0:13 Constant:
0:13 9 (const int)
0:13 Constant:
0:13 0 (const int)
0:5 Function Definition: main( ( temp void)
0:5 Function Parameters:
0:? Sequence
0:5 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:5 Function Call: @main( ( temp 4-component vector of float)
0:? Linker Objects
0:? 'g_tTex2df4a' ( uniform texture2DArray)
0:? 'g_tTex2df4' ( uniform texture2D)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
Linked fragment stage:
Shader version: 500
gl_FragCoord origin is upper left
0:? Sequence
0:5 Function Definition: @main( ( temp 4-component vector of float)
0:5 Function Parameters:
0:? Sequence
0:13 Branch: Return with expression
0:9 add ( temp 4-component vector of float)
0:6 add ( temp 4-component vector of float)
0:? textureFetch ( temp 4-component vector of float)
0:6 'g_tTex2df4' ( uniform texture2D)
0:? Constant:
0:? 3 (const uint)
0:? 4 (const uint)
0:6 Constant:
0:6 2 (const int)
0:? textureFetch ( temp 4-component vector of float)
0:9 'g_tTex2df4a' ( uniform texture2DArray)
0:? Constant:
0:? 6 (const uint)
0:? 7 (const uint)
0:? 8 (const uint)
0:9 Constant:
0:9 5 (const uint)
0:13 textureFetch ( temp 4-component vector of float)
0:13 'g_tTex2df4' ( uniform texture2D)
0:13 Convert float to uint ( temp 2-component vector of uint)
0:13 vector swizzle ( temp 2-component vector of float)
0:? textureFetch ( temp 4-component vector of float)
0:13 'g_tTex2df4' ( uniform texture2D)
0:? Constant:
0:? 14 (const uint)
0:? 15 (const uint)
0:13 Constant:
0:13 13 (const int)
0:13 Sequence
0:13 Constant:
0:13 0 (const int)
0:13 Constant:
0:13 1 (const int)
0:13 Convert float to uint ( temp uint)
0:13 direct index ( temp float)
0:? textureFetch ( temp 4-component vector of float)
0:13 'g_tTex2df4' ( uniform texture2D)
0:? Constant:
0:? 10 (const uint)
0:? 11 (const uint)
0:13 Constant:
0:13 9 (const int)
0:13 Constant:
0:13 0 (const int)
0:5 Function Definition: main( ( temp void)
0:5 Function Parameters:
0:? Sequence
0:5 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
0:5 Function Call: @main( ( temp 4-component vector of float)
0:? Linker Objects
0:? 'g_tTex2df4a' ( uniform texture2DArray)
0:? 'g_tTex2df4' ( uniform texture2D)
0:? '@entryPointOutput' (layout( location=0) out 4-component vector of float)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 61
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 59
ExecutionMode 4 OriginUpperLeft
Source HLSL 500
Name 4 "main"
Name 9 "@main("
Name 13 "g_tTex2df4"
Name 25 "g_tTex2df4a"
Name 59 "@entryPointOutput"
Decorate 13(g_tTex2df4) DescriptorSet 0
Decorate 25(g_tTex2df4a) DescriptorSet 0
Decorate 59(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypeFunction 7(fvec4)
11: TypeImage 6(float) 2D sampled format:Unknown
12: TypePointer UniformConstant 11
13(g_tTex2df4): 12(ptr) Variable UniformConstant
15: TypeInt 32 0
16: TypeVector 15(int) 2
17: 15(int) Constant 3
18: 15(int) Constant 4
19: 16(ivec2) ConstantComposite 17 18
20: TypeInt 32 1
21: 20(int) Constant 2
23: TypeImage 6(float) 2D array sampled format:Unknown
24: TypePointer UniformConstant 23
25(g_tTex2df4a): 24(ptr) Variable UniformConstant
27: TypeVector 15(int) 3
28: 15(int) Constant 6
29: 15(int) Constant 7
30: 15(int) Constant 8
31: 27(ivec3) ConstantComposite 28 29 30
32: 15(int) Constant 5
37: 15(int) Constant 14
38: 15(int) Constant 15
39: 16(ivec2) ConstantComposite 37 38
40: 20(int) Constant 13
42: TypeVector 6(float) 2
46: 15(int) Constant 10
47: 15(int) Constant 11
48: 16(ivec2) ConstantComposite 46 47
49: 20(int) Constant 9
51: 15(int) Constant 0
58: TypePointer Output 7(fvec4)
59(@entryPointOutput): 58(ptr) Variable Output
4(main): 2 Function None 3
5: Label
60: 7(fvec4) FunctionCall 9(@main()
Store 59(@entryPointOutput) 60
Return
FunctionEnd
9(@main(): 7(fvec4) Function None 8
10: Label
14: 11 Load 13(g_tTex2df4)
22: 7(fvec4) ImageFetch 14 19 Lod 21
26: 23 Load 25(g_tTex2df4a)
33: 7(fvec4) ImageFetch 26 31 Lod 32
34: 7(fvec4) FAdd 22 33
35: 11 Load 13(g_tTex2df4)
36: 11 Load 13(g_tTex2df4)
41: 7(fvec4) ImageFetch 36 39 Lod 40
43: 42(fvec2) VectorShuffle 41 41 0 1
44: 16(ivec2) ConvertFToU 43
45: 11 Load 13(g_tTex2df4)
50: 7(fvec4) ImageFetch 45 48 Lod 49
52: 6(float) CompositeExtract 50 0
53: 15(int) ConvertFToU 52
54: 7(fvec4) ImageFetch 35 44 Lod 53
55: 7(fvec4) FAdd 34 54
ReturnValue 55
FunctionEnd

View File

@ -0,0 +1,9 @@
Texture2D g_tTex2df4;
float4 main() : SV_Target0
{
g_tTex2df4.mips.mips[2][uint2(3, 4)]; // error to chain like this
return 0;
}

View File

@ -0,0 +1,9 @@
Texture2D g_tTex2df4;
float4 main() : SV_Target0
{
g_tTex2df4.r[2][uint2(3, 4)]; // '.r' not valid on texture object
return 0;
}

View File

@ -0,0 +1,14 @@
Texture2DArray g_tTex2df4a;
Texture2D g_tTex2df4;
float4 main() : SV_Target0
{
return g_tTex2df4.mips[2][uint2(3, 4)] +
// test float->uint cast on the mip arg
g_tTex2df4a.mips[5.2][uint3(6, 7, 8)] +
// Test nesting involving .mips operators:
// ....outer operator mip level...... .....outer operator coordinate....
g_tTex2df4.mips[ g_tTex2df4.mips[9][uint2(10,11)][0] ][ g_tTex2df4.mips[13][uint2(14,15)].xy ];
}

View File

@ -0,0 +1,7 @@
#version 450
layout (local_size_x_id = 0, local_size_y_id = 1, local_size_z_id = 2) in;
shared int foo[gl_WorkGroupSize.x + gl_WorkGroupSize.y * gl_WorkGroupSize.z];
void main () {}

View File

@ -177,6 +177,9 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.logicalConvert.frag", "main"},
{"hlsl.logical.unary.frag", "main"},
{"hlsl.loopattr.frag", "main"},
{"hlsl.mip.operator.frag", "main"},
{"hlsl.mip.negative.frag", "main"},
{"hlsl.mip.negative2.frag", "main"},
{"hlsl.namespace.frag", "main"},
{"hlsl.nonint-index.frag", "main"},
{"hlsl.matNx1.frag", "main"},

View File

@ -677,19 +677,30 @@ TIntermTyped* HlslParseContext::handleBracketOperator(const TSourceLoc& loc, TIn
if (base->getType().getBasicType() == EbtSampler && !base->isArray()) {
const TSampler& sampler = base->getType().getSampler();
if (sampler.isImage() || sampler.isTexture()) {
TIntermAggregate* load = new TIntermAggregate(sampler.isImage() ? EOpImageLoad : EOpTextureFetch);
if (! mipsOperatorMipArg.empty() && mipsOperatorMipArg.back().mipLevel == nullptr) {
// The first operator[] to a .mips[] sequence is the mip level. We'll remember it.
mipsOperatorMipArg.back().mipLevel = index;
return base; // next [] index is to the same base.
} else {
TIntermAggregate* load = new TIntermAggregate(sampler.isImage() ? EOpImageLoad : EOpTextureFetch);
load->setType(TType(sampler.type, EvqTemporary, sampler.vectorSize));
load->setLoc(loc);
load->getSequence().push_back(base);
load->getSequence().push_back(index);
load->setType(TType(sampler.type, EvqTemporary, sampler.vectorSize));
load->setLoc(loc);
load->getSequence().push_back(base);
load->getSequence().push_back(index);
// Textures need a MIP. First indirection is always to mip 0. If there's another, we'll add it
// later.
if (sampler.isTexture())
load->getSequence().push_back(intermediate.addConstantUnion(0, loc, true));
// Textures need a MIP. If we saw one go by, use it. Otherwise, use zero.
if (sampler.isTexture()) {
if (! mipsOperatorMipArg.empty()) {
load->getSequence().push_back(mipsOperatorMipArg.back().mipLevel);
mipsOperatorMipArg.pop_back();
} else {
load->getSequence().push_back(intermediate.addConstantUnion(0, loc, true));
}
}
return load;
return load;
}
}
}
@ -874,7 +885,21 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
}
TIntermTyped* result = base;
if (base->isVector() || base->isScalar()) {
if (base->getType().getBasicType() == EbtSampler) {
// Handle .mips[mipid][pos] operation on textures
const TSampler& sampler = base->getType().getSampler();
if (sampler.isTexture() && field == "mips") {
// Push a null to signify that we expect a mip level under operator[] next.
mipsOperatorMipArg.push_back(tMipsOperatorData(loc, nullptr));
// Keep 'result' pointing to 'base', since we expect an operator[] to go by next.
} else {
if (field == "mips")
error(loc, "unexpected texture type for .mips[][] operator:", base->getType().getCompleteString().c_str(), "");
else
error(loc, "unexpected operator on texture type:", field.c_str(), base->getType().getCompleteString().c_str());
}
} else if (base->isVector() || base->isScalar()) {
TSwizzleSelectors<TVectorSelector> selectors;
parseSwizzleSelector(loc, field, base->getVectorSize(), selectors);
@ -8426,6 +8451,12 @@ void HlslParseContext::removeUnusedStructBufferCounters()
// post-processing
void HlslParseContext::finish()
{
// Error check: There was a dangling .mips operator. These are not nested constructs in the grammar, so
// cannot be detected there. This is not strictly needed in a non-validating parser; it's just helpful.
if (! mipsOperatorMipArg.empty()) {
error(mipsOperatorMipArg.back().loc, "unterminated mips operator:", "", "");
}
removeUnusedStructBufferCounters();
addPatchConstantInvocation();
addInterstageIoToLinkage();

View File

@ -429,6 +429,17 @@ protected:
TVector<TVariable*> implicitThisStack; // currently active 'this' variables for nested structures
TVariable* gsStreamOutput; // geometry shader stream outputs, for emit (Append method)
// This tracks the first (mip level) argument to the .mips[][] operator. Since this can be nested as
// in tx.mips[tx.mips[0][1].x][2], we need a stack. We also track the TSourceLoc for error reporting
// purposes.
struct tMipsOperatorData {
tMipsOperatorData(TSourceLoc l, TIntermTyped* m) : loc(l), mipLevel(m) { }
TSourceLoc loc;
TIntermTyped* mipLevel;
};
TVector<tMipsOperatorData> mipsOperatorMipArg;
};
// This is the prefix we use for builtin methods to avoid namespace collisions with