SPV 1.4: Lookup tables: Use variable initializer and NonWritable...
...when doing a variable lookup on an array of constants.
This commit is contained in:
parent
fbb6bdf046
commit
61a5ce190a
@ -1711,6 +1711,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
case glslang::EOpIndexDirect:
|
case glslang::EOpIndexDirect:
|
||||||
case glslang::EOpIndexDirectStruct:
|
case glslang::EOpIndexDirectStruct:
|
||||||
{
|
{
|
||||||
|
// Structure, array, matrix, or vector indirection with statically known index.
|
||||||
// Get the left part of the access chain.
|
// Get the left part of the access chain.
|
||||||
node->getLeft()->traverse(this);
|
node->getLeft()->traverse(this);
|
||||||
|
|
||||||
@ -1765,8 +1766,8 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
return false;
|
return false;
|
||||||
case glslang::EOpIndexIndirect:
|
case glslang::EOpIndexIndirect:
|
||||||
{
|
{
|
||||||
// Structure or array or vector indirection.
|
// Array, matrix, or vector indirection with variable index.
|
||||||
// Will use native SPIR-V access-chain for struct and array indirection;
|
// Will use native SPIR-V access-chain for and array indirection;
|
||||||
// matrices are arrays of vectors, so will also work for a matrix.
|
// matrices are arrays of vectors, so will also work for a matrix.
|
||||||
// Will use the access chain's 'component' for variable index into a vector.
|
// Will use the access chain's 'component' for variable index into a vector.
|
||||||
|
|
||||||
|
@ -1306,11 +1306,13 @@ void Builder::makeDiscard()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
|
Id Builder::createVariable(StorageClass storageClass, Id type, const char* name, Id initializer)
|
||||||
{
|
{
|
||||||
Id pointerType = makePointer(storageClass, type);
|
Id pointerType = makePointer(storageClass, type);
|
||||||
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
|
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
|
||||||
inst->addImmediateOperand(storageClass);
|
inst->addImmediateOperand(storageClass);
|
||||||
|
if (initializer != NoResult)
|
||||||
|
inst->addIdOperand(initializer);
|
||||||
|
|
||||||
switch (storageClass) {
|
switch (storageClass) {
|
||||||
case StorageClassFunction:
|
case StorageClassFunction:
|
||||||
@ -2649,12 +2651,19 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
|||||||
if (constant) {
|
if (constant) {
|
||||||
id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
|
id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
|
||||||
} else {
|
} else {
|
||||||
// make a new function variable for this r-value
|
Id lValue = NoResult;
|
||||||
Id lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
|
if (spvVersion >= Spv_1_4) {
|
||||||
|
// make a new function variable for this r-value, using an initializer,
|
||||||
|
// and mark it as NonWritable so that downstream it can be detected as a lookup
|
||||||
|
// table
|
||||||
|
lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable",
|
||||||
|
accessChain.base);
|
||||||
|
addDecoration(lValue, DecorationNonWritable);
|
||||||
|
} else {
|
||||||
|
lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
|
||||||
// store into it
|
// store into it
|
||||||
createStore(accessChain.base, lValue);
|
createStore(accessChain.base, lValue);
|
||||||
|
}
|
||||||
// move base to the new variable
|
// move base to the new variable
|
||||||
accessChain.base = lValue;
|
accessChain.base = lValue;
|
||||||
accessChain.isRValue = false;
|
accessChain.isRValue = false;
|
||||||
|
@ -61,6 +61,14 @@
|
|||||||
|
|
||||||
namespace spv {
|
namespace spv {
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
Spv_1_0 = (1 << 16),
|
||||||
|
Spv_1_1 = (1 << 16) | (1 << 8),
|
||||||
|
Spv_1_2 = (1 << 16) | (2 << 8),
|
||||||
|
Spv_1_3 = (1 << 16) | (3 << 8),
|
||||||
|
Spv_1_4 = (1 << 16) | (4 << 8),
|
||||||
|
} SpvVersion;
|
||||||
|
|
||||||
class Builder {
|
class Builder {
|
||||||
public:
|
public:
|
||||||
Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
|
Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
|
||||||
@ -300,7 +308,7 @@ public:
|
|||||||
void makeDiscard();
|
void makeDiscard();
|
||||||
|
|
||||||
// Create a global or function local or IO variable.
|
// Create a global or function local or IO variable.
|
||||||
Id createVariable(StorageClass, Id type, const char* name = 0);
|
Id createVariable(StorageClass, Id type, const char* name = 0, Id initializer = NoResult);
|
||||||
|
|
||||||
// Create an intermediate with an undefined value.
|
// Create an intermediate with an undefined value.
|
||||||
Id createUndefined(Id type);
|
Id createUndefined(Id type);
|
||||||
|
59
Test/baseResults/spv.1.4.NonWritable.frag.out
Executable file
59
Test/baseResults/spv.1.4.NonWritable.frag.out
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
spv.1.4.NonWritable.frag
|
||||||
|
Validation failed
|
||||||
|
// Module Version 10400
|
||||||
|
// Generated by (magic number): 80007
|
||||||
|
// Id's are bound by 38
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Fragment 4 "main" 8 31
|
||||||
|
ExecutionMode 4 OriginUpperLeft
|
||||||
|
Source GLSL 450
|
||||||
|
Name 4 "main"
|
||||||
|
Name 8 "color"
|
||||||
|
Name 31 "index"
|
||||||
|
Name 34 "indexable"
|
||||||
|
Decorate 8(color) Location 0
|
||||||
|
Decorate 31(index) Flat
|
||||||
|
Decorate 31(index) Location 0
|
||||||
|
Decorate 34(indexable) NonWritable
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeFloat 32
|
||||||
|
7: TypePointer Output 6(float)
|
||||||
|
8(color): 7(ptr) Variable Output
|
||||||
|
9: TypeInt 32 0
|
||||||
|
10: 9(int) Constant 16
|
||||||
|
11: TypeArray 6(float) 10
|
||||||
|
12: 6(float) Constant 1065353216
|
||||||
|
13: 6(float) Constant 1073741824
|
||||||
|
14: 6(float) Constant 1077936128
|
||||||
|
15: 6(float) Constant 1082130432
|
||||||
|
16: 6(float) Constant 1084227584
|
||||||
|
17: 6(float) Constant 1086324736
|
||||||
|
18: 6(float) Constant 1088421888
|
||||||
|
19: 6(float) Constant 1090519040
|
||||||
|
20: 6(float) Constant 1091567616
|
||||||
|
21: 6(float) Constant 1092616192
|
||||||
|
22: 6(float) Constant 1093664768
|
||||||
|
23: 6(float) Constant 1094713344
|
||||||
|
24: 6(float) Constant 1095761920
|
||||||
|
25: 6(float) Constant 1096810496
|
||||||
|
26: 6(float) Constant 1097859072
|
||||||
|
27: 6(float) Constant 1098907648
|
||||||
|
28: 11 ConstantComposite 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
||||||
|
29: TypeInt 32 1
|
||||||
|
30: TypePointer Input 29(int)
|
||||||
|
31(index): 30(ptr) Variable Input
|
||||||
|
33: TypePointer Function 11
|
||||||
|
35: TypePointer Function 6(float)
|
||||||
|
4(main): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
34(indexable): 33(ptr) Variable Function 28
|
||||||
|
32: 29(int) Load 31(index)
|
||||||
|
36: 35(ptr) AccessChain 34(indexable) 32
|
||||||
|
37: 6(float) Load 36
|
||||||
|
Store 8(color) 37
|
||||||
|
Return
|
||||||
|
FunctionEnd
|
13
Test/spv.1.4.NonWritable.frag
Executable file
13
Test/spv.1.4.NonWritable.frag
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#version 450
|
||||||
|
|
||||||
|
layout(location = 0) flat in int index;
|
||||||
|
|
||||||
|
layout(location = 0) out float color;
|
||||||
|
|
||||||
|
// lookup table
|
||||||
|
const float table[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
color = table[index];
|
||||||
|
}
|
@ -465,9 +465,10 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
INSTANTIATE_TEST_CASE_P(
|
INSTANTIATE_TEST_CASE_P(
|
||||||
Glsl, CompileToSpirv14Test,
|
Glsl, CompileToSpirv14Test,
|
||||||
::testing::ValuesIn(std::vector<std::string>({
|
::testing::ValuesIn(std::vector<std::string>({
|
||||||
|
"spv.1.4.LoopControl.frag",
|
||||||
|
"spv.1.4.NonWritable.frag",
|
||||||
"spv.1.4.OpEntryPoint.frag",
|
"spv.1.4.OpEntryPoint.frag",
|
||||||
"spv.1.4.OpSelect.frag",
|
"spv.1.4.OpSelect.frag",
|
||||||
"spv.1.4.LoopControl.frag",
|
|
||||||
"spv.1.4.OpCopyLogical.comp",
|
"spv.1.4.OpCopyLogical.comp",
|
||||||
"spv.1.4.OpCopyLogicalBool.comp",
|
"spv.1.4.OpCopyLogicalBool.comp",
|
||||||
"spv.1.4.OpCopyLogical.funcall.frag",
|
"spv.1.4.OpCopyLogical.funcall.frag",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user