Merge pull request #71 from amdrexu/mywork

SPIRV: Add image instruction support and atomic counter support.
This commit is contained in:
John Kessenich 2015-09-16 10:51:33 -06:00
commit f6890c3798
17 changed files with 915 additions and 160 deletions

View File

@ -99,16 +99,16 @@ protected:
void makeGlobalInitializers(const glslang::TIntermSequence&); void makeGlobalInitializers(const glslang::TIntermSequence&);
void visitFunctions(const glslang::TIntermSequence&); void visitFunctions(const glslang::TIntermSequence&);
void handleFunctionEntry(const glslang::TIntermAggregate* node); void handleFunctionEntry(const glslang::TIntermAggregate* node);
void translateArguments(const glslang::TIntermSequence& glslangArguments, std::vector<spv::Id>& arguments); void translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments);
void translateArguments(glslang::TIntermUnary& node, std::vector<spv::Id>& arguments); void translateArguments(glslang::TIntermUnary& node, std::vector<spv::Id>& arguments);
spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node); spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node);
spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*); spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*);
spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true); spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true);
spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, bool isFloat); spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destTypeId, spv::Id operand); spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destTypeId, spv::Id operand);
spv::Id makeSmearedConstant(spv::Id constant, int vectorSize); spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands); spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy); spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id createNoArgOperation(glslang::TOperator op); spv::Id createNoArgOperation(glslang::TOperator op);
spv::Id getSymbolId(const glslang::TIntermSymbol* node); spv::Id getSymbolId(const glslang::TIntermSymbol* node);
@ -181,6 +181,8 @@ spv::StorageClass TranslateStorageClass(const glslang::TType& type)
else if (type.getQualifier().isUniformOrBuffer()) { else if (type.getQualifier().isUniformOrBuffer()) {
if (type.getBasicType() == glslang::EbtBlock) if (type.getBasicType() == glslang::EbtBlock)
return spv::StorageClassUniform; return spv::StorageClassUniform;
else if (type.getBasicType() == glslang::EbtAtomicUint)
return spv::StorageClassAtomicCounter;
else else
return spv::StorageClassUniformConstant; return spv::StorageClassUniformConstant;
// TODO: how are we distuingishing between default and non-default non-writable uniforms? Do default uniforms even exist? // TODO: how are we distuingishing between default and non-default non-writable uniforms? Do default uniforms even exist?
@ -347,6 +349,56 @@ spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn)
} }
} }
// Translate glslang image layout format to SPIR-V image format.
spv::ImageFormat TranslateImageFormat(const glslang::TType& type)
{
assert(type.getBasicType() == glslang::EbtSampler);
switch (type.getQualifier().layoutFormat) {
case glslang::ElfNone: return spv::ImageFormatUnknown;
case glslang::ElfRgba32f: return spv::ImageFormatRgba32f;
case glslang::ElfRgba16f: return spv::ImageFormatRgba16f;
case glslang::ElfR32f: return spv::ImageFormatR32f;
case glslang::ElfRgba8: return spv::ImageFormatRgba8;
case glslang::ElfRgba8Snorm: return spv::ImageFormatRgba8Snorm;
case glslang::ElfRg32f: return spv::ImageFormatRg32f;
case glslang::ElfRg16f: return spv::ImageFormatRg16f;
case glslang::ElfR11fG11fB10f: return spv::ImageFormatR11fG11fB10f;
case glslang::ElfR16f: return spv::ImageFormatR16f;
case glslang::ElfRgba16: return spv::ImageFormatRgba16;
case glslang::ElfRgb10A2: return spv::ImageFormatRgb10A2;
case glslang::ElfRg16: return spv::ImageFormatRg16;
case glslang::ElfRg8: return spv::ImageFormatRg8;
case glslang::ElfR16: return spv::ImageFormatR16;
case glslang::ElfR8: return spv::ImageFormatR8;
case glslang::ElfRgba16Snorm: return spv::ImageFormatRgba16Snorm;
case glslang::ElfRg16Snorm: return spv::ImageFormatRg16Snorm;
case glslang::ElfRg8Snorm: return spv::ImageFormatRg8Snorm;
case glslang::ElfR16Snorm: return spv::ImageFormatR16Snorm;
case glslang::ElfR8Snorm: return spv::ImageFormatR8Snorm;
case glslang::ElfRgba32i: return spv::ImageFormatRgba32i;
case glslang::ElfRgba16i: return spv::ImageFormatRgba16i;
case glslang::ElfRgba8i: return spv::ImageFormatRgba8i;
case glslang::ElfR32i: return spv::ImageFormatR32i;
case glslang::ElfRg32i: return spv::ImageFormatRg32i;
case glslang::ElfRg16i: return spv::ImageFormatRg16i;
case glslang::ElfRg8i: return spv::ImageFormatRg8i;
case glslang::ElfR16i: return spv::ImageFormatR16i;
case glslang::ElfR8i: return spv::ImageFormatR8i;
case glslang::ElfRgba32ui: return spv::ImageFormatRgba32ui;
case glslang::ElfRgba16ui: return spv::ImageFormatRgba16ui;
case glslang::ElfRgba8ui: return spv::ImageFormatRgba8ui;
case glslang::ElfR32ui: return spv::ImageFormatR32ui;
case glslang::ElfRg32ui: return spv::ImageFormatRg32ui;
case glslang::ElfRg16ui: return spv::ImageFormatRg16ui;
case glslang::ElfRgb10a2ui: return spv::ImageFormatRgb10a2ui;
case glslang::ElfRg8ui: return spv::ImageFormatRg8ui;
case glslang::ElfR16ui: return spv::ImageFormatR16ui;
case glslang::ElfR8ui: return spv::ImageFormatR8ui;
default: return (spv::ImageFormat)spv::BadValue;
}
}
// //
// Implement the TGlslangToSpvTraverser class. // Implement the TGlslangToSpvTraverser class.
// //
@ -702,7 +754,15 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
builder.clearAccessChain(); builder.clearAccessChain();
node->getOperand()->traverse(this); node->getOperand()->traverse(this);
spv::Id operand = builder.accessChainLoad(convertGlslangToSpvType(node->getOperand()->getType()));
spv::Id operand = spv::NoResult;
if (node->getOp() == glslang::EOpAtomicCounterIncrement ||
node->getOp() == glslang::EOpAtomicCounterDecrement ||
node->getOp() == glslang::EOpAtomicCounter)
operand = builder.accessChainGetLValue(); // Special case l-value operands
else
operand = builder.accessChainLoad(convertGlslangToSpvType(node->getOperand()->getType()));
spv::Decoration precision = TranslatePrecisionDecoration(node->getType()); spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
@ -712,8 +772,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
// if not, then possibly an operation // if not, then possibly an operation
if (! result) if (! result)
result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand, result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand, node->getBasicType());
node->getBasicType() == glslang::EbtFloat || node->getBasicType() == glslang::EbtDouble);
if (result) { if (result) {
builder.clearAccessChain(); builder.clearAccessChain();
@ -786,6 +845,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
return false; return false;
} }
else if (node->getOp() == glslang::EOpImageStore)
{
// "imageStore" is a special case, which has no result
return false;
}
glslang::TOperator binOp = glslang::EOpNull; glslang::TOperator binOp = glslang::EOpNull;
bool reduceComparison = true; bool reduceComparison = true;
@ -923,7 +987,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
case glslang::EOpConstructStruct: case glslang::EOpConstructStruct:
{ {
std::vector<spv::Id> arguments; std::vector<spv::Id> arguments;
translateArguments(node->getSequence(), arguments); translateArguments(*node, arguments);
spv::Id resultTypeId = convertGlslangToSpvType(node->getType()); spv::Id resultTypeId = convertGlslangToSpvType(node->getType());
spv::Id constructed; spv::Id constructed;
if (node->getOp() == glslang::EOpConstructStruct || node->getType().isArray()) { if (node->getOp() == glslang::EOpConstructStruct || node->getType().isArray()) {
@ -1075,6 +1139,17 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
if (arg == 1) if (arg == 1)
lvalue = true; lvalue = true;
break; break;
case glslang::EOpAtomicAdd:
case glslang::EOpAtomicMin:
case glslang::EOpAtomicMax:
case glslang::EOpAtomicAnd:
case glslang::EOpAtomicOr:
case glslang::EOpAtomicXor:
case glslang::EOpAtomicExchange:
case glslang::EOpAtomicCompSwap:
if (arg == 0)
lvalue = true;
break;
//case glslang::EOpUAddCarry: //case glslang::EOpUAddCarry:
//case glslang::EOpUSubBorrow: //case glslang::EOpUSubBorrow:
//case glslang::EOpUMulExtended: //case glslang::EOpUMulExtended:
@ -1089,7 +1164,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
if (atomic) { if (atomic) {
// Handle all atomics // Handle all atomics
result = createAtomicOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands); result = createAtomicOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands, node->getBasicType());
} else { } else {
// Pass through to generic operations. // Pass through to generic operations.
switch (glslangOperands.size()) { switch (glslangOperands.size()) {
@ -1097,7 +1172,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
result = createNoArgOperation(node->getOp()); result = createNoArgOperation(node->getOp());
break; break;
case 1: case 1:
result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands.front(), node->getType().getBasicType() == glslang::EbtFloat || node->getType().getBasicType() == glslang::EbtDouble); result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands.front(), node->getType().getBasicType());
break; break;
default: default:
result = createMiscOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands, node->getBasicType()); result = createMiscOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands, node->getBasicType());
@ -1367,7 +1442,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
{ {
const glslang::TSampler& sampler = type.getSampler(); const glslang::TSampler& sampler = type.getSampler();
spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.shadow, sampler.arrayed, sampler.ms, spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.shadow, sampler.arrayed, sampler.ms,
sampler.image ? 2 : 1, spv::ImageFormatUnknown); // TODO: translate format, needed for GLSL image ops sampler.image ? 2 : 1, TranslateImageFormat(type));
// OpenGL "textures" need to be combined with a sampler // OpenGL "textures" need to be combined with a sampler
if (! sampler.image) if (! sampler.image)
spvType = builder.makeSampledImageType(spvType); spvType = builder.makeSampledImageType(spvType);
@ -1657,12 +1732,35 @@ void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate
builder.setBuildPoint(functionBlock); builder.setBuildPoint(functionBlock);
} }
void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermSequence& glslangArguments, std::vector<spv::Id>& arguments) void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments)
{ {
const glslang::TIntermSequence& glslangArguments = node.getSequence();
for (int i = 0; i < (int)glslangArguments.size(); ++i) { for (int i = 0; i < (int)glslangArguments.size(); ++i) {
builder.clearAccessChain(); builder.clearAccessChain();
glslangArguments[i]->traverse(this); glslangArguments[i]->traverse(this);
arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType())));
// Special case l-value operands
bool lvalue = false;
switch (node.getOp()) {
case glslang::EOpImageAtomicAdd:
case glslang::EOpImageAtomicMin:
case glslang::EOpImageAtomicMax:
case glslang::EOpImageAtomicAnd:
case glslang::EOpImageAtomicOr:
case glslang::EOpImageAtomicXor:
case glslang::EOpImageAtomicExchange:
case glslang::EOpImageAtomicCompSwap:
if (i == 0)
lvalue = true;
break;
default:
break;
}
if (lvalue)
arguments.push_back(builder.accessChainGetLValue());
else
arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType())));
} }
} }
@ -1675,23 +1773,16 @@ void TGlslangToSpvTraverser::translateArguments(glslang::TIntermUnary& node, std
spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node) spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node)
{ {
if (node->isImage()) { if (! node->isImage() && ! node->isTexture()) {
spv::MissingFunctionality("GLSL image function");
return spv::NoResult;
} else if (! node->isTexture()) {
return spv::NoResult; return spv::NoResult;
} }
// Process a GLSL texturing op (will be SPV image) // Process a GLSL texturing op (will be SPV image)
glslang::TCrackedTextureOp cracked;
node->crackTexture(cracked);
const glslang::TSampler sampler = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType().getSampler() const glslang::TSampler sampler = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType().getSampler()
: node->getAsUnaryNode()->getOperand()->getAsTyped()->getType().getSampler(); : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType().getSampler();
std::vector<spv::Id> arguments; std::vector<spv::Id> arguments;
if (node->getAsAggregate()) if (node->getAsAggregate())
translateArguments(node->getAsAggregate()->getSequence(), arguments); translateArguments(*node->getAsAggregate(), arguments);
else else
translateArguments(*node->getAsUnaryNode(), arguments); translateArguments(*node->getAsUnaryNode(), arguments);
spv::Decoration precision = TranslatePrecisionDecoration(node->getType()); spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
@ -1699,6 +1790,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
spv::Builder::TextureParameters params = { }; spv::Builder::TextureParameters params = { };
params.sampler = arguments[0]; params.sampler = arguments[0];
glslang::TCrackedTextureOp cracked;
node->crackTexture(sampler, cracked);
// Check for queries // Check for queries
if (cracked.query) { if (cracked.query) {
switch (node->getOp()) { switch (node->getOp()) {
@ -1723,8 +1817,58 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
} }
} }
// This is no longer a query.... // Check for image functions other than queries
if (node->isImage()) {
// Process image load/store
if (node->getOp() == glslang::EOpImageLoad ||
node->getOp() == glslang::EOpImageStore) {
std::vector<spv::Id> operands;
auto opIt = arguments.begin();
operands.push_back(*(opIt++));
operands.push_back(*(opIt++));
if (sampler.ms) {
// For MS, image operand mask has to be added to indicate the presence of "sample" operand.
spv::Id sample = *(opIt++);
for (; opIt != arguments.end(); ++opIt)
operands.push_back(*opIt);
operands.push_back(spv::ImageOperandsSampleMask);
operands.push_back(sample);
} else {
for (; opIt != arguments.end(); ++opIt)
operands.push_back(*opIt);
}
if (node->getOp() == glslang::EOpImageLoad)
return builder.createOp(spv::OpImageRead, convertGlslangToSpvType(node->getType()), operands);
else {
builder.createNoResultOp(spv::OpImageWrite, operands);
return spv::NoResult;
}
} else {
// Process image atomic operations
// GLSL "IMAGE_PARAMS" will involve in constructing an image texel pointer and this pointer,
// as the first source operand, is required by SPIR-V atomic operations.
std::vector<spv::Id> imageParams;
auto opIt = arguments.begin();
imageParams.push_back(*(opIt++));
imageParams.push_back(*(opIt++));
imageParams.push_back(sampler.ms ? *(opIt++) : 0); // For non-MS, the value should be 0
spv::Id resultTypeId = builder.makePointer(spv::StorageClassImage, convertGlslangToSpvType(node->getType()));
spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, imageParams);
std::vector<spv::Id> operands;
operands.push_back(pointer);
for (; opIt != arguments.end(); ++opIt)
operands.push_back(*opIt);
return createAtomicOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands, node->getBasicType());
}
}
// Check for texture functions other than queries
if (cracked.gather) if (cracked.gather)
spv::MissingFunctionality("texture gather"); spv::MissingFunctionality("texture gather");
@ -1761,6 +1905,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
if (cracked.lod) { if (cracked.lod) {
params.lod = arguments[2]; params.lod = arguments[2];
++extraArgs; ++extraArgs;
} else if (sampler.ms) {
params.sample = arguments[2]; // For MS, "sample" should be specified
++extraArgs;
} }
if (cracked.grad) { if (cracked.grad) {
params.gradX = arguments[2 + extraArgs]; params.gradX = arguments[2 + extraArgs];
@ -2115,10 +2262,11 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
return 0; return 0;
} }
spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, bool isFloat) spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id operand, glslang::TBasicType typeProxy)
{ {
spv::Op unaryOp = spv::OpNop; spv::Op unaryOp = spv::OpNop;
int libCall = -1; int libCall = -1;
bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
switch (op) { switch (op) {
case glslang::EOpNegative: case glslang::EOpNegative:
@ -2334,7 +2482,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
// Handle all of the atomics in one place, in createAtomicOperation() // Handle all of the atomics in one place, in createAtomicOperation()
std::vector<spv::Id> operands; std::vector<spv::Id> operands;
operands.push_back(operand); operands.push_back(operand);
return createAtomicOperation(op, precision, typeId, operands); return createAtomicOperation(op, precision, typeId, operands, typeProxy);
} }
case glslang::EOpImageLoad: case glslang::EOpImageLoad:
@ -2480,33 +2628,41 @@ spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vector
} }
// For glslang ops that map to SPV atomic opCodes // For glslang ops that map to SPV atomic opCodes
spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands) spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
{ {
spv::Op opCode = spv::OpNop; spv::Op opCode = spv::OpNop;
switch (op) { switch (op) {
case glslang::EOpAtomicAdd: case glslang::EOpAtomicAdd:
case glslang::EOpImageAtomicAdd:
opCode = spv::OpAtomicIAdd; opCode = spv::OpAtomicIAdd;
break; break;
case glslang::EOpAtomicMin: case glslang::EOpAtomicMin:
opCode = spv::OpAtomicSMin; case glslang::EOpImageAtomicMin:
opCode = typeProxy == glslang::EbtUint ? spv::OpAtomicUMin : spv::OpAtomicSMin;
break; break;
case glslang::EOpAtomicMax: case glslang::EOpAtomicMax:
opCode = spv::OpAtomicSMax; case glslang::EOpImageAtomicMax:
opCode = typeProxy == glslang::EbtUint ? spv::OpAtomicUMax : spv::OpAtomicSMax;
break; break;
case glslang::EOpAtomicAnd: case glslang::EOpAtomicAnd:
case glslang::EOpImageAtomicAnd:
opCode = spv::OpAtomicAnd; opCode = spv::OpAtomicAnd;
break; break;
case glslang::EOpAtomicOr: case glslang::EOpAtomicOr:
case glslang::EOpImageAtomicOr:
opCode = spv::OpAtomicOr; opCode = spv::OpAtomicOr;
break; break;
case glslang::EOpAtomicXor: case glslang::EOpAtomicXor:
case glslang::EOpImageAtomicXor:
opCode = spv::OpAtomicXor; opCode = spv::OpAtomicXor;
break; break;
case glslang::EOpAtomicExchange: case glslang::EOpAtomicExchange:
case glslang::EOpImageAtomicExchange:
opCode = spv::OpAtomicExchange; opCode = spv::OpAtomicExchange;
break; break;
case glslang::EOpAtomicCompSwap: case glslang::EOpAtomicCompSwap:
case glslang::EOpImageAtomicCompSwap:
opCode = spv::OpAtomicCompareExchange; opCode = spv::OpAtomicCompareExchange;
break; break;
case glslang::EOpAtomicCounterIncrement: case glslang::EOpAtomicCounterIncrement:
@ -2534,7 +2690,9 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
spvAtomicOperands.push_back(builder.makeUintConstant(spv::ScopeDevice)); // TBD: what is the correct scope? spvAtomicOperands.push_back(builder.makeUintConstant(spv::ScopeDevice)); // TBD: what is the correct scope?
spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics? spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics?
if (opCode == spv::OpAtomicCompareExchange) { if (opCode == spv::OpAtomicCompareExchange) {
spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics? // There are 2 memory semantics for compare-exchange. And the operand order of "comparator" and "new value" in GLSL
// differs from that in SPIR-V. Hence, special processing is required.
spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone));
spvAtomicOperands.push_back(*(opIt + 1)); spvAtomicOperands.push_back(*(opIt + 1));
spvAtomicOperands.push_back(*opIt); spvAtomicOperands.push_back(*opIt);
opIt += 2; opIt += 2;

View File

@ -812,6 +812,7 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
case StorageClassWorkgroupLocal: case StorageClassWorkgroupLocal:
case StorageClassPrivateGlobal: case StorageClassPrivateGlobal:
case StorageClassWorkgroupGlobal: case StorageClassWorkgroupGlobal:
case StorageClassAtomicCounter:
constantsTypesGlobals.push_back(inst); constantsTypesGlobals.push_back(inst);
module.mapInstruction(inst); module.mapInstruction(inst);
break; break;
@ -965,6 +966,15 @@ void Builder::createNoResultOp(Op opCode, Id operand)
buildPoint->addInstruction(op); buildPoint->addInstruction(op);
} }
// An opcode that has one operand, no result id, and no type
void Builder::createNoResultOp(Op opCode, const std::vector<Id>& operands)
{
Instruction* op = new Instruction(opCode);
for (auto operand : operands)
op->addIdOperand(operand);
buildPoint->addInstruction(op);
}
void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics) void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics)
{ {
Instruction* op = new Instruction(OpControlBarrier); Instruction* op = new Instruction(OpControlBarrier);

View File

@ -159,8 +159,9 @@ public:
} }
Id getImageType(Id resultId) const Id getImageType(Id resultId) const
{ {
assert(isSampledImageType(getTypeId(resultId))); Id typeId = getTypeId(resultId);
return module.getInstruction(getTypeId(resultId))->getIdOperand(0); assert(isImageType(typeId) || isSampledImageType(typeId));
return isSampledImageType(typeId) ? module.getInstruction(typeId)->getIdOperand(0) : typeId;
} }
bool isArrayedImageType(Id typeId) const bool isArrayedImageType(Id typeId) const
{ {
@ -235,6 +236,7 @@ public:
void createNoResultOp(Op); void createNoResultOp(Op);
void createNoResultOp(Op, Id operand); void createNoResultOp(Op, Id operand);
void createNoResultOp(Op, const std::vector<Id>& operands);
void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask); void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics); void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
Id createUnaryOp(Op, Id typeId, Id operand); Id createUnaryOp(Op, Id typeId, Id operand);

View File

@ -1635,10 +1635,12 @@ void Parameterize()
InstructionDesc[OpImageRead].operands.push(OperandId, "'Image'"); InstructionDesc[OpImageRead].operands.push(OperandId, "'Image'");
InstructionDesc[OpImageRead].operands.push(OperandId, "'Coordinate'"); InstructionDesc[OpImageRead].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageRead].operands.push(OperandOptionalImage, "");
InstructionDesc[OpImageWrite].operands.push(OperandId, "'Image'"); InstructionDesc[OpImageWrite].operands.push(OperandId, "'Image'");
InstructionDesc[OpImageWrite].operands.push(OperandId, "'Coordinate'"); InstructionDesc[OpImageWrite].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageWrite].operands.push(OperandId, "'Texel'"); InstructionDesc[OpImageWrite].operands.push(OperandId, "'Texel'");
InstructionDesc[OpImageWrite].operands.push(OperandOptionalImage, "");
InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Sampled Image'"); InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Coordinate'"); InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Coordinate'");

View File

@ -8,7 +8,7 @@ Linked compute stage:
TBD functionality: Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class? TBD functionality: Is atomic_uint an opaque handle in the uniform storage class, or an addresses in the atomic storage class?
// Module Version 99 // Module Version 99
// Generated by (magic number): 51a00bb // Generated by (magic number): 51a00bb
// Id's are bound by 74 // Id's are bound by 64
Source ESSL 310 Source ESSL 310
Capability Shader Capability Shader
@ -19,108 +19,98 @@ TBD functionality: Is atomic_uint an opaque handle in the uniform storage class,
Name 10 "func(au1;" Name 10 "func(au1;"
Name 9 "c" Name 9 "c"
Name 12 "atoms(" Name 12 "atoms("
Name 21 "counter" Name 20 "counter"
Name 22 "param" Name 21 "param"
Name 25 "val" Name 24 "val"
Name 29 "countArr" Name 28 "countArr"
Name 38 "origi" Name 35 "origi"
Name 40 "atomi" Name 37 "atomi"
Name 44 "origu" Name 40 "origu"
Name 46 "atomu" Name 42 "atomu"
Name 48 "value" Name 44 "value"
Name 71 "arrX" Name 61 "arrX"
Name 72 "arrY" Name 62 "arrY"
Name 73 "arrZ" Name 63 "arrZ"
Decorate 21(counter) Binding 0 Decorate 20(counter) Binding 0
Decorate 29(countArr) Binding 0 Decorate 28(countArr) Binding 0
Decorate 71(arrX) NoStaticUse Decorate 61(arrX) NoStaticUse
Decorate 72(arrY) NoStaticUse Decorate 62(arrY) NoStaticUse
Decorate 73(arrZ) NoStaticUse Decorate 63(arrZ) NoStaticUse
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 0 6: TypeInt 32 0
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
8: TypeFunction 6(int) 7(ptr) 8: TypeFunction 6(int) 7(ptr)
15: 6(int) Constant 1 14: 6(int) Constant 1
16: 6(int) Constant 0 15: 6(int) Constant 0
19: 6(int) Constant 256 18: 6(int) Constant 256
20: TypePointer UniformConstant 6(int) 19: TypePointer AtomicCounter 6(int)
21(counter): 20(ptr) Variable UniformConstant 20(counter): 19(ptr) Variable AtomicCounter
26: 6(int) Constant 4 25: 6(int) Constant 4
27: TypeArray 6(int) 26 26: TypeArray 6(int) 25
28: TypePointer UniformConstant 27 27: TypePointer AtomicCounter 26
29(countArr): 28(ptr) Variable UniformConstant 28(countArr): 27(ptr) Variable AtomicCounter
30: TypeInt 32 1 29: TypeInt 32 1
31: 30(int) Constant 2 30: 29(int) Constant 2
37: TypePointer Function 30(int) 34: TypePointer Function 29(int)
39: TypePointer WorkgroupLocal 30(int) 36: TypePointer WorkgroupLocal 29(int)
40(atomi): 39(ptr) Variable WorkgroupLocal 37(atomi): 36(ptr) Variable WorkgroupLocal
42: 30(int) Constant 3 38: 29(int) Constant 3
45: TypePointer WorkgroupLocal 6(int) 41: TypePointer WorkgroupLocal 6(int)
46(atomu): 45(ptr) Variable WorkgroupLocal 42(atomu): 41(ptr) Variable WorkgroupLocal
48(value): 20(ptr) Variable UniformConstant 43: TypePointer UniformConstant 6(int)
52: 6(int) Constant 7 44(value): 43(ptr) Variable UniformConstant
60: 30(int) Constant 7 47: 6(int) Constant 7
66: 6(int) Constant 10 52: 29(int) Constant 7
69: TypeArray 30(int) 15 56: 6(int) Constant 10
70: TypePointer PrivateGlobal 69 59: TypeArray 29(int) 14
71(arrX): 70(ptr) Variable PrivateGlobal 60: TypePointer PrivateGlobal 59
72(arrY): 70(ptr) Variable PrivateGlobal 61(arrX): 60(ptr) Variable PrivateGlobal
73(arrZ): 70(ptr) Variable PrivateGlobal 62(arrY): 60(ptr) Variable PrivateGlobal
63(arrZ): 60(ptr) Variable PrivateGlobal
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
22(param): 7(ptr) Variable Function 21(param): 7(ptr) Variable Function
25(val): 7(ptr) Variable Function 24(val): 7(ptr) Variable Function
MemoryBarrier 15 19 MemoryBarrier 14 18
23: 6(int) Load 21(counter) 22: 6(int) Load 20(counter)
Store 22(param) 23 Store 21(param) 22
24: 6(int) FunctionCall 10(func(au1;) 22(param) 23: 6(int) FunctionCall 10(func(au1;) 21(param)
32: 20(ptr) AccessChain 29(countArr) 31 31: 19(ptr) AccessChain 28(countArr) 30
33: 6(int) Load 32 32: 6(int) AtomicLoad 31 14 15
34: 6(int) AtomicLoad 33 15 16 Store 24(val) 32
Store 25(val) 34 33: 6(int) AtomicIDecrement 20(counter) 14 15
35: 6(int) Load 21(counter)
36: 6(int) AtomicIDecrement 35 15 16
Return Return
FunctionEnd FunctionEnd
10(func(au1;): 6(int) Function None 8 10(func(au1;): 6(int) Function None 8
9(c): 7(ptr) FunctionParameter 9(c): 7(ptr) FunctionParameter
11: Label 11: Label
14: 6(int) Load 9(c) 16: 6(int) AtomicIIncrement 9(c) 14 15
17: 6(int) AtomicIIncrement 14 15 16 ReturnValue 16
ReturnValue 17
FunctionEnd FunctionEnd
12(atoms(): 2 Function None 3 12(atoms(): 2 Function None 3
13: Label 13: Label
38(origi): 37(ptr) Variable Function 35(origi): 34(ptr) Variable Function
44(origu): 7(ptr) Variable Function 40(origu): 7(ptr) Variable Function
41: 30(int) Load 40(atomi) 39: 29(int) AtomicIAdd 37(atomi) 14 15 38
43: 30(int) AtomicIAdd 41 15 16 42 Store 35(origi) 39
Store 38(origi) 43 45: 6(int) Load 44(value)
47: 6(int) Load 46(atomu) 46: 6(int) AtomicAnd 42(atomu) 14 15 45
49: 6(int) Load 48(value) Store 40(origu) 46
50: 6(int) AtomicAnd 47 15 16 49 48: 6(int) AtomicOr 42(atomu) 14 15 47
Store 44(origu) 50 Store 40(origu) 48
51: 6(int) Load 46(atomu) 49: 6(int) AtomicXor 42(atomu) 14 15 47
53: 6(int) AtomicOr 51 15 16 52 Store 40(origu) 49
Store 44(origu) 53 50: 6(int) Load 44(value)
54: 6(int) Load 46(atomu) 51: 6(int) AtomicUMin 42(atomu) 14 15 50
55: 6(int) AtomicXor 54 15 16 52 Store 40(origu) 51
Store 44(origu) 55 53: 29(int) AtomicSMax 37(atomi) 14 15 52
56: 6(int) Load 46(atomu) Store 35(origi) 53
57: 6(int) Load 48(value) 54: 29(int) Load 35(origi)
58: 6(int) AtomicSMin 56 15 16 57 55: 29(int) AtomicExchange 37(atomi) 14 15 54
Store 44(origu) 58 Store 35(origi) 55
59: 30(int) Load 40(atomi) 57: 6(int) Load 44(value)
61: 30(int) AtomicSMax 59 15 16 60 58: 6(int) AtomicCompareExchange 42(atomu) 14 15 15 57 56
Store 38(origi) 61 Store 40(origu) 58
62: 30(int) Load 40(atomi)
63: 30(int) Load 38(origi)
64: 30(int) AtomicExchange 62 15 16 63
Store 38(origi) 64
65: 6(int) Load 46(atomu)
67: 6(int) Load 48(value)
68: 6(int) AtomicCompareExchange 65 15 16 16 67 66
Store 44(origu) 68
Return Return
FunctionEnd FunctionEnd

View File

@ -25,11 +25,11 @@ Linked vertex stage:
6: TypeInt 32 1 6: TypeInt 32 1
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
9: 6(int) Constant 0 9: 6(int) Constant 0
14: TypeBool 13: TypeBool
15: 14(bool) ConstantTrue 15: 13(bool) ConstantTrue
19: 6(int) Constant 10 19: 6(int) Constant 10
23: 6(int) Constant 1 23: 6(int) Constant 1
25: 14(bool) ConstantFalse 25: 13(bool) ConstantFalse
26: TypePointer Input 6(int) 26: TypePointer Input 6(int)
27(gl_VertexID): 26(ptr) Variable Input 27(gl_VertexID): 26(ptr) Variable Input
28(gl_InstanceID): 26(ptr) Variable Input 28(gl_InstanceID): 26(ptr) Variable Input
@ -39,15 +39,15 @@ Linked vertex stage:
Store 8(i) 9 Store 8(i) 9
Branch 10 Branch 10
10: Label 10: Label
13: 14(bool) Phi 15 5 25 12 14: 13(bool) Phi 15 5 25 12
LoopMerge 11 None LoopMerge 11 None
Branch 16 Branch 16
16: Label 16: Label
SelectionMerge 12 None SelectionMerge 12 None
BranchConditional 13 12 17 BranchConditional 14 12 17
17: Label 17: Label
18: 6(int) Load 8(i) 18: 6(int) Load 8(i)
20: 14(bool) SLessThan 18 19 20: 13(bool) SLessThan 18 19
SelectionMerge 21 None SelectionMerge 21 None
BranchConditional 20 21 11 BranchConditional 20 21 11
21: Label 21: Label

View File

@ -32,12 +32,12 @@ Linked vertex stage:
6: TypeInt 32 1 6: TypeInt 32 1
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
9: 6(int) Constant 0 9: 6(int) Constant 0
14: TypeBool 13: TypeBool
15: 14(bool) ConstantTrue 15: 13(bool) ConstantTrue
19: 6(int) Constant 1 19: 6(int) Constant 1
21: 6(int) Constant 19 21: 6(int) Constant 19
26: 6(int) Constant 2 26: 6(int) Constant 2
31: 14(bool) ConstantFalse 31: 13(bool) ConstantFalse
35: 6(int) Constant 5 35: 6(int) Constant 5
40: 6(int) Constant 3 40: 6(int) Constant 3
43: 6(int) Constant 42 43: 6(int) Constant 42
@ -59,17 +59,17 @@ Linked vertex stage:
Store 8(i) 9 Store 8(i) 9
Branch 10 Branch 10
10: Label 10: Label
13: 14(bool) Phi 15 5 31 28 31 38 14: 13(bool) Phi 15 5 31 28 31 38
LoopMerge 11 None LoopMerge 11 None
Branch 16 Branch 16
16: Label 16: Label
SelectionMerge 12 None SelectionMerge 12 None
BranchConditional 13 12 17 BranchConditional 14 12 17
17: Label 17: Label
18: 6(int) Load 8(i) 18: 6(int) Load 8(i)
20: 6(int) IAdd 18 19 20: 6(int) IAdd 18 19
Store 8(i) 20 Store 8(i) 20
22: 14(bool) SLessThan 20 21 22: 13(bool) SLessThan 20 21
SelectionMerge 23 None SelectionMerge 23 None
BranchConditional 22 23 11 BranchConditional 22 23 11
23: Label 23: Label
@ -77,7 +77,7 @@ Linked vertex stage:
12: Label 12: Label
Store 24(A) 9 Store 24(A) 9
25: 6(int) Load 8(i) 25: 6(int) Load 8(i)
27: 14(bool) IEqual 25 26 27: 13(bool) IEqual 25 26
SelectionMerge 29 None SelectionMerge 29 None
BranchConditional 27 28 29 BranchConditional 27 28 29
28: Label 28: Label
@ -88,7 +88,7 @@ Linked vertex stage:
Branch 29 Branch 29
29: Label 29: Label
34: 6(int) Load 8(i) 34: 6(int) Load 8(i)
36: 14(bool) IEqual 34 35 36: 13(bool) IEqual 34 35
SelectionMerge 38 None SelectionMerge 38 None
BranchConditional 36 37 38 BranchConditional 36 37 38
37: Label 37: Label

View File

@ -28,13 +28,13 @@ Linked fragment stage:
8: TypePointer Function 7(fvec4) 8: TypePointer Function 7(fvec4)
10: TypePointer Input 7(fvec4) 10: TypePointer Input 7(fvec4)
11(BaseColor): 10(ptr) Variable Input 11(BaseColor): 10(ptr) Variable Input
17: TypeBool 16: TypeBool
18: 17(bool) ConstantTrue 18: 16(bool) ConstantTrue
23: TypePointer UniformConstant 6(float) 23: TypePointer UniformConstant 6(float)
24(d): 23(ptr) Variable UniformConstant 24(d): 23(ptr) Variable UniformConstant
28: TypePointer UniformConstant 7(fvec4) 28: TypePointer UniformConstant 7(fvec4)
29(bigColor): 28(ptr) Variable UniformConstant 29(bigColor): 28(ptr) Variable UniformConstant
33: 17(bool) ConstantFalse 33: 16(bool) ConstantFalse
34: TypePointer Output 7(fvec4) 34: TypePointer Output 7(fvec4)
35(gl_FragColor): 34(ptr) Variable Output 35(gl_FragColor): 34(ptr) Variable Output
4(main): 2 Function None 3 4(main): 2 Function None 3
@ -44,17 +44,17 @@ Linked fragment stage:
Store 9(color) 12 Store 9(color) 12
Branch 13 Branch 13
13: Label 13: Label
16: 17(bool) Phi 18 5 33 15 17: 16(bool) Phi 18 5 33 15
LoopMerge 14 None LoopMerge 14 None
Branch 19 Branch 19
19: Label 19: Label
SelectionMerge 15 None SelectionMerge 15 None
BranchConditional 16 15 20 BranchConditional 17 15 20
20: Label 20: Label
21: 7(fvec4) Load 9(color) 21: 7(fvec4) Load 9(color)
22: 6(float) CompositeExtract 21 0 22: 6(float) CompositeExtract 21 0
25: 6(float) Load 24(d) 25: 6(float) Load 24(d)
26: 17(bool) FOrdLessThan 22 25 26: 16(bool) FOrdLessThan 22 25
SelectionMerge 27 None SelectionMerge 27 None
BranchConditional 26 27 14 BranchConditional 26 27 14
27: Label 27: Label

View File

@ -0,0 +1,497 @@
spv.image.frag
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
Linked fragment stage:
// Module Version 99
// Generated by (magic number): 51a00bb
// Id's are bound by 383
Source GLSL 450
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginLowerLeft
Name 4 "main"
Name 9 "iv"
Name 15 "i1D"
Name 25 "i2D"
Name 36 "i3D"
Name 43 "iCube"
Name 53 "iCubeArray"
Name 60 "i2DRect"
Name 70 "i1DArray"
Name 80 "i2DArray"
Name 87 "iBuffer"
Name 97 "i2DMS"
Name 107 "i2DMSArray"
Name 128 "v"
Name 133 "ic1D"
Name 143 "ic2D"
Name 153 "ic3D"
Name 172 "ic4D"
Name 234 "ui"
Name 238 "ii1D"
Name 252 "ui2D"
Name 255 "value"
Name 370 "fragData"
Decorate 15(i1D) Binding 0
Decorate 25(i2D) Binding 1
Decorate 36(i3D) Binding 2
Decorate 43(iCube) Binding 3
Decorate 53(iCubeArray) Binding 4
Decorate 60(i2DRect) Binding 5
Decorate 70(i1DArray) Binding 6
Decorate 80(i2DArray) Binding 7
Decorate 87(iBuffer) Binding 8
Decorate 97(i2DMS) Binding 9
Decorate 107(i2DMSArray) Binding 10
Decorate 238(ii1D) Binding 11
Decorate 252(ui2D) Binding 12
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7: TypeVector 6(int) 3
8: TypePointer Function 7(ivec3)
10: 6(int) Constant 0
11: 7(ivec3) ConstantComposite 10 10 10
12: TypeFloat 32
13: TypeImage 12(float) 1D nonsampled format:Rgba32f
14: TypePointer UniformConstant 13
15(i1D): 14(ptr) Variable UniformConstant
23: TypeImage 12(float) 2D nonsampled format:Rgba32f
24: TypePointer UniformConstant 23
25(i2D): 24(ptr) Variable UniformConstant
27: TypeVector 6(int) 2
34: TypeImage 12(float) 3D nonsampled format:Rgba32f
35: TypePointer UniformConstant 34
36(i3D): 35(ptr) Variable UniformConstant
41: TypeImage 12(float) Cube nonsampled format:Rgba32f
42: TypePointer UniformConstant 41
43(iCube): 42(ptr) Variable UniformConstant
51: TypeImage 12(float) Cube array nonsampled format:Rgba32f
52: TypePointer UniformConstant 51
53(iCubeArray): 52(ptr) Variable UniformConstant
58: TypeImage 12(float) Rect nonsampled format:Rgba32f
59: TypePointer UniformConstant 58
60(i2DRect): 59(ptr) Variable UniformConstant
68: TypeImage 12(float) 1D array nonsampled format:Rgba32f
69: TypePointer UniformConstant 68
70(i1DArray): 69(ptr) Variable UniformConstant
78: TypeImage 12(float) 2D array nonsampled format:Rgba32f
79: TypePointer UniformConstant 78
80(i2DArray): 79(ptr) Variable UniformConstant
85: TypeImage 12(float) Buffer nonsampled format:Rgba32f
86: TypePointer UniformConstant 85
87(iBuffer): 86(ptr) Variable UniformConstant
95: TypeImage 12(float) 2D multi-sampled nonsampled format:Rgba32f
96: TypePointer UniformConstant 95
97(i2DMS): 96(ptr) Variable UniformConstant
105: TypeImage 12(float) 2D array multi-sampled nonsampled format:Rgba32f
106: TypePointer UniformConstant 105
107(i2DMSArray): 106(ptr) Variable UniformConstant
126: TypeVector 12(float) 4
127: TypePointer Function 126(fvec4)
129: 12(float) Constant 0
130: 126(fvec4) ConstantComposite 129 129 129 129
132: TypePointer UniformConstant 6(int)
133(ic1D): 132(ptr) Variable UniformConstant
142: TypePointer UniformConstant 27(ivec2)
143(ic2D): 142(ptr) Variable UniformConstant
152: TypePointer UniformConstant 7(ivec3)
153(ic3D): 152(ptr) Variable UniformConstant
170: TypeVector 6(int) 4
171: TypePointer UniformConstant 170(ivec4)
172(ic4D): 171(ptr) Variable UniformConstant
214: 6(int) Constant 1
220: 6(int) Constant 2
224: 6(int) Constant 3
230: 6(int) Constant 4
232: TypeInt 32 0
233: TypePointer Function 232(int)
235: 232(int) Constant 0
236: TypeImage 6(int) 1D nonsampled format:R32i
237: TypePointer UniformConstant 236
238(ii1D): 237(ptr) Variable UniformConstant
240: 6(int) Constant 10
241: TypePointer Image 6(int)
243: 232(int) Constant 1
250: TypeImage 232(int) 2D nonsampled format:R32ui
251: TypePointer UniformConstant 250
252(ui2D): 251(ptr) Variable UniformConstant
254: TypePointer UniformConstant 232(int)
255(value): 254(ptr) Variable UniformConstant
257: TypePointer Image 232(int)
263: 6(int) Constant 11
278: 6(int) Constant 12
293: 6(int) Constant 13
308: 6(int) Constant 14
323: 6(int) Constant 15
338: 6(int) Constant 16
353: 6(int) Constant 18
354: 6(int) Constant 17
363: 232(int) Constant 19
369: TypePointer Output 126(fvec4)
370(fragData): 369(ptr) Variable Output
376: TypeBool
4(main): 2 Function None 3
5: Label
9(iv): 8(ptr) Variable Function
128(v): 127(ptr) Variable Function
234(ui): 233(ptr) Variable Function
371: 127(ptr) Variable Function
Store 9(iv) 11
16: 13 Load 15(i1D)
17: 6(int) ImageQuerySize 16
18: 7(ivec3) Load 9(iv)
19: 6(int) CompositeExtract 18 0
20: 6(int) IAdd 19 17
21: 7(ivec3) Load 9(iv)
22: 7(ivec3) CompositeInsert 20 21 0
Store 9(iv) 22
26: 23 Load 25(i2D)
28: 27(ivec2) ImageQuerySize 26
29: 7(ivec3) Load 9(iv)
30: 27(ivec2) VectorShuffle 29 29 0 1
31: 27(ivec2) IAdd 30 28
32: 7(ivec3) Load 9(iv)
33: 7(ivec3) VectorShuffle 32 31 3 4 2
Store 9(iv) 33
37: 34 Load 36(i3D)
38: 7(ivec3) ImageQuerySize 37
39: 7(ivec3) Load 9(iv)
40: 7(ivec3) IAdd 39 38
Store 9(iv) 40
44: 41 Load 43(iCube)
45: 27(ivec2) ImageQuerySize 44
46: 7(ivec3) Load 9(iv)
47: 27(ivec2) VectorShuffle 46 46 0 1
48: 27(ivec2) IAdd 47 45
49: 7(ivec3) Load 9(iv)
50: 7(ivec3) VectorShuffle 49 48 3 4 2
Store 9(iv) 50
54: 51 Load 53(iCubeArray)
55: 7(ivec3) ImageQuerySize 54
56: 7(ivec3) Load 9(iv)
57: 7(ivec3) IAdd 56 55
Store 9(iv) 57
61: 58 Load 60(i2DRect)
62: 27(ivec2) ImageQuerySize 61
63: 7(ivec3) Load 9(iv)
64: 27(ivec2) VectorShuffle 63 63 0 1
65: 27(ivec2) IAdd 64 62
66: 7(ivec3) Load 9(iv)
67: 7(ivec3) VectorShuffle 66 65 3 4 2
Store 9(iv) 67
71: 68 Load 70(i1DArray)
72: 27(ivec2) ImageQuerySize 71
73: 7(ivec3) Load 9(iv)
74: 27(ivec2) VectorShuffle 73 73 0 1
75: 27(ivec2) IAdd 74 72
76: 7(ivec3) Load 9(iv)
77: 7(ivec3) VectorShuffle 76 75 3 4 2
Store 9(iv) 77
81: 78 Load 80(i2DArray)
82: 7(ivec3) ImageQuerySize 81
83: 7(ivec3) Load 9(iv)
84: 7(ivec3) IAdd 83 82
Store 9(iv) 84
88: 85 Load 87(iBuffer)
89: 6(int) ImageQuerySize 88
90: 7(ivec3) Load 9(iv)
91: 6(int) CompositeExtract 90 0
92: 6(int) IAdd 91 89
93: 7(ivec3) Load 9(iv)
94: 7(ivec3) CompositeInsert 92 93 0
Store 9(iv) 94
98: 95 Load 97(i2DMS)
99: 27(ivec2) ImageQuerySize 98
100: 7(ivec3) Load 9(iv)
101: 27(ivec2) VectorShuffle 100 100 0 1
102: 27(ivec2) IAdd 101 99
103: 7(ivec3) Load 9(iv)
104: 7(ivec3) VectorShuffle 103 102 3 4 2
Store 9(iv) 104
108: 105 Load 107(i2DMSArray)
109: 7(ivec3) ImageQuerySize 108
110: 7(ivec3) Load 9(iv)
111: 7(ivec3) IAdd 110 109
Store 9(iv) 111
112: 95 Load 97(i2DMS)
113: 6(int) ImageQuerySamples 112
114: 7(ivec3) Load 9(iv)
115: 6(int) CompositeExtract 114 0
116: 6(int) IAdd 115 113
117: 7(ivec3) Load 9(iv)
118: 7(ivec3) CompositeInsert 116 117 0
Store 9(iv) 118
119: 105 Load 107(i2DMSArray)
120: 6(int) ImageQuerySamples 119
121: 7(ivec3) Load 9(iv)
122: 6(int) CompositeExtract 121 0
123: 6(int) IAdd 122 120
124: 7(ivec3) Load 9(iv)
125: 7(ivec3) CompositeInsert 123 124 0
Store 9(iv) 125
Store 128(v) 130
131: 13 Load 15(i1D)
134: 6(int) Load 133(ic1D)
135: 126(fvec4) ImageRead 131 134
136: 126(fvec4) Load 128(v)
137: 126(fvec4) FAdd 136 135
Store 128(v) 137
138: 13 Load 15(i1D)
139: 6(int) Load 133(ic1D)
140: 126(fvec4) Load 128(v)
ImageWrite 138 139 140
141: 23 Load 25(i2D)
144: 27(ivec2) Load 143(ic2D)
145: 126(fvec4) ImageRead 141 144
146: 126(fvec4) Load 128(v)
147: 126(fvec4) FAdd 146 145
Store 128(v) 147
148: 23 Load 25(i2D)
149: 27(ivec2) Load 143(ic2D)
150: 126(fvec4) Load 128(v)
ImageWrite 148 149 150
151: 34 Load 36(i3D)
154: 7(ivec3) Load 153(ic3D)
155: 126(fvec4) ImageRead 151 154
156: 126(fvec4) Load 128(v)
157: 126(fvec4) FAdd 156 155
Store 128(v) 157
158: 34 Load 36(i3D)
159: 7(ivec3) Load 153(ic3D)
160: 126(fvec4) Load 128(v)
ImageWrite 158 159 160
161: 41 Load 43(iCube)
162: 7(ivec3) Load 153(ic3D)
163: 126(fvec4) ImageRead 161 162
164: 126(fvec4) Load 128(v)
165: 126(fvec4) FAdd 164 163
Store 128(v) 165
166: 41 Load 43(iCube)
167: 7(ivec3) Load 153(ic3D)
168: 126(fvec4) Load 128(v)
ImageWrite 166 167 168
169: 51 Load 53(iCubeArray)
173: 170(ivec4) Load 172(ic4D)
174: 126(fvec4) ImageRead 169 173
175: 126(fvec4) Load 128(v)
176: 126(fvec4) FAdd 175 174
Store 128(v) 176
177: 51 Load 53(iCubeArray)
178: 170(ivec4) Load 172(ic4D)
179: 126(fvec4) Load 128(v)
ImageWrite 177 178 179
180: 58 Load 60(i2DRect)
181: 27(ivec2) Load 143(ic2D)
182: 126(fvec4) ImageRead 180 181
183: 126(fvec4) Load 128(v)
184: 126(fvec4) FAdd 183 182
Store 128(v) 184
185: 58 Load 60(i2DRect)
186: 27(ivec2) Load 143(ic2D)
187: 126(fvec4) Load 128(v)
ImageWrite 185 186 187
188: 68 Load 70(i1DArray)
189: 27(ivec2) Load 143(ic2D)
190: 126(fvec4) ImageRead 188 189
191: 126(fvec4) Load 128(v)
192: 126(fvec4) FAdd 191 190
Store 128(v) 192
193: 68 Load 70(i1DArray)
194: 27(ivec2) Load 143(ic2D)
195: 126(fvec4) Load 128(v)
ImageWrite 193 194 195
196: 78 Load 80(i2DArray)
197: 7(ivec3) Load 153(ic3D)
198: 126(fvec4) ImageRead 196 197
199: 126(fvec4) Load 128(v)
200: 126(fvec4) FAdd 199 198
Store 128(v) 200
201: 78 Load 80(i2DArray)
202: 7(ivec3) Load 153(ic3D)
203: 126(fvec4) Load 128(v)
ImageWrite 201 202 203
204: 85 Load 87(iBuffer)
205: 6(int) Load 133(ic1D)
206: 126(fvec4) ImageRead 204 205
207: 126(fvec4) Load 128(v)
208: 126(fvec4) FAdd 207 206
Store 128(v) 208
209: 85 Load 87(iBuffer)
210: 6(int) Load 133(ic1D)
211: 126(fvec4) Load 128(v)
ImageWrite 209 210 211
212: 95 Load 97(i2DMS)
213: 27(ivec2) Load 143(ic2D)
215: 126(fvec4) ImageRead 212 213 214
216: 126(fvec4) Load 128(v)
217: 126(fvec4) FAdd 216 215
Store 128(v) 217
218: 95 Load 97(i2DMS)
219: 27(ivec2) Load 143(ic2D)
221: 126(fvec4) Load 128(v)
ImageWrite 218 219 221 220
222: 105 Load 107(i2DMSArray)
223: 7(ivec3) Load 153(ic3D)
225: 126(fvec4) ImageRead 222 223 224
226: 126(fvec4) Load 128(v)
227: 126(fvec4) FAdd 226 225
Store 128(v) 227
228: 105 Load 107(i2DMSArray)
229: 7(ivec3) Load 153(ic3D)
231: 126(fvec4) Load 128(v)
ImageWrite 228 229 231 230
Store 234(ui) 235
239: 6(int) Load 133(ic1D)
242: 241(ptr) ImageTexelPointer 238(ii1D) 239 0
244: 6(int) AtomicIAdd 242 243 235 240
245: 7(ivec3) Load 9(iv)
246: 6(int) CompositeExtract 245 0
247: 6(int) IAdd 246 244
248: 7(ivec3) Load 9(iv)
249: 7(ivec3) CompositeInsert 247 248 0
Store 9(iv) 249
253: 27(ivec2) Load 143(ic2D)
256: 232(int) Load 255(value)
258: 257(ptr) ImageTexelPointer 252(ui2D) 253 0
259: 232(int) AtomicIAdd 258 243 235 256
260: 232(int) Load 234(ui)
261: 232(int) IAdd 260 259
Store 234(ui) 261
262: 6(int) Load 133(ic1D)
264: 241(ptr) ImageTexelPointer 238(ii1D) 262 0
265: 6(int) AtomicSMin 264 243 235 263
266: 7(ivec3) Load 9(iv)
267: 6(int) CompositeExtract 266 0
268: 6(int) IAdd 267 265
269: 7(ivec3) Load 9(iv)
270: 7(ivec3) CompositeInsert 268 269 0
Store 9(iv) 270
271: 27(ivec2) Load 143(ic2D)
272: 232(int) Load 255(value)
273: 257(ptr) ImageTexelPointer 252(ui2D) 271 0
274: 232(int) AtomicUMin 273 243 235 272
275: 232(int) Load 234(ui)
276: 232(int) IAdd 275 274
Store 234(ui) 276
277: 6(int) Load 133(ic1D)
279: 241(ptr) ImageTexelPointer 238(ii1D) 277 0
280: 6(int) AtomicSMax 279 243 235 278
281: 7(ivec3) Load 9(iv)
282: 6(int) CompositeExtract 281 0
283: 6(int) IAdd 282 280
284: 7(ivec3) Load 9(iv)
285: 7(ivec3) CompositeInsert 283 284 0
Store 9(iv) 285
286: 27(ivec2) Load 143(ic2D)
287: 232(int) Load 255(value)
288: 257(ptr) ImageTexelPointer 252(ui2D) 286 0
289: 232(int) AtomicUMax 288 243 235 287
290: 232(int) Load 234(ui)
291: 232(int) IAdd 290 289
Store 234(ui) 291
292: 6(int) Load 133(ic1D)
294: 241(ptr) ImageTexelPointer 238(ii1D) 292 0
295: 6(int) AtomicAnd 294 243 235 293
296: 7(ivec3) Load 9(iv)
297: 6(int) CompositeExtract 296 0
298: 6(int) IAdd 297 295
299: 7(ivec3) Load 9(iv)
300: 7(ivec3) CompositeInsert 298 299 0
Store 9(iv) 300
301: 27(ivec2) Load 143(ic2D)
302: 232(int) Load 255(value)
303: 257(ptr) ImageTexelPointer 252(ui2D) 301 0
304: 232(int) AtomicAnd 303 243 235 302
305: 232(int) Load 234(ui)
306: 232(int) IAdd 305 304
Store 234(ui) 306
307: 6(int) Load 133(ic1D)
309: 241(ptr) ImageTexelPointer 238(ii1D) 307 0
310: 6(int) AtomicOr 309 243 235 308
311: 7(ivec3) Load 9(iv)
312: 6(int) CompositeExtract 311 0
313: 6(int) IAdd 312 310
314: 7(ivec3) Load 9(iv)
315: 7(ivec3) CompositeInsert 313 314 0
Store 9(iv) 315
316: 27(ivec2) Load 143(ic2D)
317: 232(int) Load 255(value)
318: 257(ptr) ImageTexelPointer 252(ui2D) 316 0
319: 232(int) AtomicOr 318 243 235 317
320: 232(int) Load 234(ui)
321: 232(int) IAdd 320 319
Store 234(ui) 321
322: 6(int) Load 133(ic1D)
324: 241(ptr) ImageTexelPointer 238(ii1D) 322 0
325: 6(int) AtomicXor 324 243 235 323
326: 7(ivec3) Load 9(iv)
327: 6(int) CompositeExtract 326 0
328: 6(int) IAdd 327 325
329: 7(ivec3) Load 9(iv)
330: 7(ivec3) CompositeInsert 328 329 0
Store 9(iv) 330
331: 27(ivec2) Load 143(ic2D)
332: 232(int) Load 255(value)
333: 257(ptr) ImageTexelPointer 252(ui2D) 331 0
334: 232(int) AtomicXor 333 243 235 332
335: 232(int) Load 234(ui)
336: 232(int) IAdd 335 334
Store 234(ui) 336
337: 6(int) Load 133(ic1D)
339: 241(ptr) ImageTexelPointer 238(ii1D) 337 0
340: 6(int) AtomicExchange 339 243 235 338
341: 7(ivec3) Load 9(iv)
342: 6(int) CompositeExtract 341 0
343: 6(int) IAdd 342 340
344: 7(ivec3) Load 9(iv)
345: 7(ivec3) CompositeInsert 343 344 0
Store 9(iv) 345
346: 27(ivec2) Load 143(ic2D)
347: 232(int) Load 255(value)
348: 257(ptr) ImageTexelPointer 252(ui2D) 346 0
349: 232(int) AtomicExchange 348 243 235 347
350: 232(int) Load 234(ui)
351: 232(int) IAdd 350 349
Store 234(ui) 351
352: 6(int) Load 133(ic1D)
355: 241(ptr) ImageTexelPointer 238(ii1D) 352 0
356: 6(int) AtomicCompareExchange 355 243 235 235 354 353
357: 7(ivec3) Load 9(iv)
358: 6(int) CompositeExtract 357 0
359: 6(int) IAdd 358 356
360: 7(ivec3) Load 9(iv)
361: 7(ivec3) CompositeInsert 359 360 0
Store 9(iv) 361
362: 27(ivec2) Load 143(ic2D)
364: 232(int) Load 255(value)
365: 257(ptr) ImageTexelPointer 252(ui2D) 362 0
366: 232(int) AtomicCompareExchange 365 243 235 235 364 363
367: 232(int) Load 234(ui)
368: 232(int) IAdd 367 366
Store 234(ui) 368
372: 232(int) Load 234(ui)
373: 7(ivec3) Load 9(iv)
374: 6(int) CompositeExtract 373 1
375: 232(int) Bitcast 374
377: 376(bool) INotEqual 372 375
SelectionMerge 379 None
BranchConditional 377 378 381
378: Label
380: 126(fvec4) Load 128(v)
Store 371 380
Branch 379
381: Label
Store 371 130
Branch 379
379: Label
382: 126(fvec4) Load 371
Store 370(fragData) 382
Return
FunctionEnd

View File

@ -117,15 +117,15 @@ Linked fragment stage:
8: TypePointer Function 7(fvec4) 8: TypePointer Function 7(fvec4)
10: TypePointer Input 7(fvec4) 10: TypePointer Input 7(fvec4)
11(BaseColor): 10(ptr) Variable Input 11(BaseColor): 10(ptr) Variable Input
17: TypeBool 16: TypeBool
18: 17(bool) ConstantTrue 18: 16(bool) ConstantTrue
23: TypePointer UniformConstant 6(float) 23: TypePointer UniformConstant 6(float)
24(d4): 23(ptr) Variable UniformConstant 24(d4): 23(ptr) Variable UniformConstant
28: TypePointer UniformConstant 7(fvec4) 28: TypePointer UniformConstant 7(fvec4)
29(bigColor4): 28(ptr) Variable UniformConstant 29(bigColor4): 28(ptr) Variable UniformConstant
39: 6(float) Constant 1073741824 39: 6(float) Constant 1073741824
53: 6(float) Constant 1065353216 53: 6(float) Constant 1065353216
57: 17(bool) ConstantFalse 57: 16(bool) ConstantFalse
83(d13): 23(ptr) Variable UniformConstant 83(d13): 23(ptr) Variable UniformConstant
147: TypePointer Output 7(fvec4) 147: TypePointer Output 7(fvec4)
148(gl_FragColor): 147(ptr) Variable Output 148(gl_FragColor): 147(ptr) Variable Output
@ -181,17 +181,17 @@ Linked fragment stage:
Store 9(color) 12 Store 9(color) 12
Branch 13 Branch 13
13: Label 13: Label
16: 17(bool) Phi 18 5 57 49 57 64 17: 16(bool) Phi 18 5 57 49 57 64
LoopMerge 14 None LoopMerge 14 None
Branch 19 Branch 19
19: Label 19: Label
SelectionMerge 15 None SelectionMerge 15 None
BranchConditional 16 15 20 BranchConditional 17 15 20
20: Label 20: Label
21: 7(fvec4) Load 9(color) 21: 7(fvec4) Load 9(color)
22: 6(float) CompositeExtract 21 2 22: 6(float) CompositeExtract 21 2
25: 6(float) Load 24(d4) 25: 6(float) Load 24(d4)
26: 17(bool) FOrdLessThan 22 25 26: 16(bool) FOrdLessThan 22 25
SelectionMerge 27 None SelectionMerge 27 None
BranchConditional 26 27 14 BranchConditional 26 27 14
27: Label 27: Label
@ -204,7 +204,7 @@ Linked fragment stage:
33: 7(fvec4) Load 9(color) 33: 7(fvec4) Load 9(color)
34: 6(float) CompositeExtract 33 0 34: 6(float) CompositeExtract 33 0
35: 6(float) Load 24(d4) 35: 6(float) Load 24(d4)
36: 17(bool) FOrdLessThan 34 35 36: 16(bool) FOrdLessThan 34 35
SelectionMerge 38 None SelectionMerge 38 None
BranchConditional 36 37 38 BranchConditional 36 37 38
37: Label 37: Label
@ -217,7 +217,7 @@ Linked fragment stage:
45: 7(fvec4) Load 9(color) 45: 7(fvec4) Load 9(color)
46: 6(float) CompositeExtract 45 2 46: 6(float) CompositeExtract 45 2
47: 6(float) Load 24(d4) 47: 6(float) Load 24(d4)
48: 17(bool) FOrdLessThan 46 47 48: 16(bool) FOrdLessThan 46 47
SelectionMerge 50 None SelectionMerge 50 None
BranchConditional 48 49 50 BranchConditional 48 49 50
49: Label 49: Label
@ -234,7 +234,7 @@ Linked fragment stage:
59: 7(fvec4) Load 9(color) 59: 7(fvec4) Load 9(color)
60: 6(float) CompositeExtract 59 1 60: 6(float) CompositeExtract 59 1
61: 6(float) Load 24(d4) 61: 6(float) Load 24(d4)
62: 17(bool) FOrdLessThan 60 61 62: 16(bool) FOrdLessThan 60 61
SelectionMerge 64 None SelectionMerge 64 None
BranchConditional 62 63 71 BranchConditional 62 63 71
63: Label 63: Label
@ -263,14 +263,14 @@ Linked fragment stage:
81: 7(fvec4) Load 9(color) 81: 7(fvec4) Load 9(color)
82: 6(float) CompositeExtract 81 3 82: 6(float) CompositeExtract 81 3
84: 6(float) Load 83(d13) 84: 6(float) Load 83(d13)
85: 17(bool) FOrdLessThan 82 84 85: 16(bool) FOrdLessThan 82 84
LoopMerge 79 None LoopMerge 79 None
BranchConditional 85 80 79 BranchConditional 85 80 79
80: Label 80: Label
86: 7(fvec4) Load 9(color) 86: 7(fvec4) Load 9(color)
87: 6(float) CompositeExtract 86 2 87: 6(float) CompositeExtract 86 2
88: 6(float) Load 83(d13) 88: 6(float) Load 83(d13)
89: 17(bool) FOrdLessThan 87 88 89: 16(bool) FOrdLessThan 87 88
SelectionMerge 91 None SelectionMerge 91 None
BranchConditional 89 90 95 BranchConditional 89 90 95
90: Label 90: Label
@ -293,7 +293,7 @@ Linked fragment stage:
102: 7(fvec4) Load 9(color) 102: 7(fvec4) Load 9(color)
103: 6(float) CompositeExtract 102 0 103: 6(float) CompositeExtract 102 0
104: 6(float) Load 24(d4) 104: 6(float) Load 24(d4)
105: 17(bool) FOrdLessThan 103 104 105: 16(bool) FOrdLessThan 103 104
SelectionMerge 107 None SelectionMerge 107 None
BranchConditional 105 106 107 BranchConditional 105 106 107
106: Label 106: Label
@ -306,7 +306,7 @@ Linked fragment stage:
113: 7(fvec4) Load 9(color) 113: 7(fvec4) Load 9(color)
114: 6(float) CompositeExtract 113 2 114: 6(float) CompositeExtract 113 2
115: 6(float) Load 24(d4) 115: 6(float) Load 24(d4)
116: 17(bool) FOrdLessThan 114 115 116: 16(bool) FOrdLessThan 114 115
SelectionMerge 118 None SelectionMerge 118 None
BranchConditional 116 117 118 BranchConditional 116 117 118
117: Label 117: Label
@ -323,7 +323,7 @@ Linked fragment stage:
125: 7(fvec4) Load 9(color) 125: 7(fvec4) Load 9(color)
126: 6(float) CompositeExtract 125 1 126: 6(float) CompositeExtract 125 1
127: 6(float) Load 24(d4) 127: 6(float) Load 24(d4)
128: 17(bool) FOrdLessThan 126 127 128: 16(bool) FOrdLessThan 126 127
SelectionMerge 130 None SelectionMerge 130 None
BranchConditional 128 129 137 BranchConditional 128 129 137
129: Label 129: Label

View File

@ -196,13 +196,13 @@ Linked fragment stage:
64: 21 Load 23(s3D) 64: 21 Load 23(s3D)
68: 65(ivec3) Load 67(ic3D) 68: 65(ivec3) Load 67(ic3D)
71: 50(int) Load 70(ic1D) 71: 50(int) Load 70(ic1D)
72: 7(fvec4) ImageFetch 64 68 72: 7(fvec4) ImageFetch 64 68 71
73: 7(fvec4) Load 9(v) 73: 7(fvec4) Load 9(v)
74: 7(fvec4) FAdd 73 72 74: 7(fvec4) FAdd 73 72
Store 9(v) 74 Store 9(v) 74
75: 11 Load 13(s2D) 75: 11 Load 13(s2D)
78: 51(ivec2) Load 77(ic2D) 78: 51(ivec2) Load 77(ic2D)
80: 7(fvec4) ImageFetch 75 78 79 80: 7(fvec4) ImageFetch 75 78 79 53
81: 7(fvec4) Load 9(v) 81: 7(fvec4) Load 9(v)
82: 7(fvec4) FAdd 81 80 82: 7(fvec4) FAdd 81 80
Store 9(v) 82 Store 9(v) 82
@ -321,7 +321,7 @@ Linked fragment stage:
205: 202 Load 204(is2DArray) 205: 202 Load 204(is2DArray)
206: 65(ivec3) Load 67(ic3D) 206: 65(ivec3) Load 67(ic3D)
207: 50(int) Load 70(ic1D) 207: 50(int) Load 70(ic1D)
208: 139(ivec4) ImageFetch 205 206 208: 139(ivec4) ImageFetch 205 206 207
Store 141(iv) 208 Store 141(iv) 208
209: 139(ivec4) Load 141(iv) 209: 139(ivec4) Load 141(iv)
210: 7(fvec4) ConvertSToF 209 210: 7(fvec4) ConvertSToF 209

View File

@ -310,7 +310,7 @@ Linked fragment stage:
214: 70 Load 72(texSampler2D) 214: 70 Load 72(texSampler2D)
215: 205(ivec2) Load 207(iCoords2D) 215: 205(ivec2) Load 207(iCoords2D)
216: 204(int) Load 212(iLod) 216: 204(int) Load 212(iLod)
217: 22(fvec4) ImageFetch 214 215 217: 22(fvec4) ImageFetch 214 215 216
218: 22(fvec4) Load 26(color) 218: 22(fvec4) Load 26(color)
219: 22(fvec4) FAdd 218 217 219: 22(fvec4) FAdd 218 217
Store 26(color) 219 Store 26(color) 219

89
Test/spv.image.frag Normal file
View File

@ -0,0 +1,89 @@
#version 450
layout(rgba32f, binding = 0) uniform image1D i1D;
layout(rgba32f, binding = 1) uniform image2D i2D;
layout(rgba32f, binding = 2) uniform image3D i3D;
layout(rgba32f, binding = 3) uniform imageCube iCube;
layout(rgba32f, binding = 4) uniform imageCubeArray iCubeArray;
layout(rgba32f, binding = 5) uniform image2DRect i2DRect;
layout(rgba32f, binding = 6) uniform image1DArray i1DArray;
layout(rgba32f, binding = 7) uniform image2DArray i2DArray;
layout(rgba32f, binding = 8) uniform imageBuffer iBuffer;
layout(rgba32f, binding = 9) uniform image2DMS i2DMS;
layout(rgba32f, binding = 10) uniform image2DMSArray i2DMSArray;
layout(r32i, binding = 11) uniform iimage1D ii1D;
layout(r32ui, binding = 12) uniform uimage2D ui2D;
uniform int ic1D;
uniform ivec2 ic2D;
uniform ivec3 ic3D;
uniform ivec4 ic4D;
uniform uint value;
out vec4 fragData;
void main()
{
ivec3 iv = ivec3(0);
iv.x += imageSize(i1D);
iv.xy += imageSize(i2D);
iv.xyz += imageSize(i3D);
iv.xy += imageSize(iCube);
iv.xyz += imageSize(iCubeArray);
iv.xy += imageSize(i2DRect);
iv.xy += imageSize(i1DArray);
iv.xyz += imageSize(i2DArray);
iv.x += imageSize(iBuffer);
iv.xy += imageSize(i2DMS);
iv.xyz += imageSize(i2DMSArray);
iv.x += imageSamples(i2DMS);
iv.x += imageSamples(i2DMSArray);
vec4 v = vec4(0.0);
v += imageLoad(i1D, ic1D);
imageStore(i1D, ic1D, v);
v += imageLoad(i2D, ic2D);
imageStore(i2D, ic2D, v);
v += imageLoad(i3D, ic3D);
imageStore(i3D, ic3D, v);
v += imageLoad(iCube, ic3D);
imageStore(iCube, ic3D, v);
v += imageLoad(iCubeArray, ic4D);
imageStore(iCubeArray, ic4D, v);
v += imageLoad(i2DRect, ic2D);
imageStore(i2DRect, ic2D, v);
v += imageLoad(i1DArray, ic2D);
imageStore(i1DArray, ic2D, v);
v += imageLoad(i2DArray, ic3D);
imageStore(i2DArray, ic3D, v);
v += imageLoad(iBuffer, ic1D);
imageStore(iBuffer, ic1D, v);
v += imageLoad(i2DMS, ic2D, 1);
imageStore(i2DMS, ic2D, 2, v);
v += imageLoad(i2DMSArray, ic3D, 3);
imageStore(i2DMSArray, ic3D, 4, v);
uint ui = 0;
iv.x += imageAtomicAdd(ii1D, ic1D, 10);
ui += imageAtomicAdd(ui2D, ic2D, value);
iv.x += imageAtomicMin(ii1D, ic1D, 11);
ui += imageAtomicMin(ui2D, ic2D, value);
iv.x += imageAtomicMax(ii1D, ic1D, 12);
ui += imageAtomicMax(ui2D, ic2D, value);
iv.x += imageAtomicAnd(ii1D, ic1D, 13);
ui += imageAtomicAnd(ui2D, ic2D, value);
iv.x += imageAtomicOr(ii1D, ic1D, 14);
ui += imageAtomicOr(ui2D, ic2D, value);
iv.x += imageAtomicXor(ii1D, ic1D, 15);
ui += imageAtomicXor(ui2D, ic2D, value);
iv.x += imageAtomicExchange(ii1D, ic1D, 16);
ui += imageAtomicExchange(ui2D, ic2D, value);
iv.x += imageAtomicCompSwap(ii1D, ic1D, 18, 17);
ui += imageAtomicCompSwap(ui2D, ic2D, 19u, value);
fragData = ui != iv.y ? v : vec4(0.0);
}

View File

@ -70,6 +70,7 @@ spv.test.frag
spv.test.vert spv.test.vert
spv.texture.frag spv.texture.frag
spv.texture.vert spv.texture.vert
spv.image.frag
spv.types.frag spv.types.frag
spv.uint.frag spv.uint.frag
spv.uniformArray.frag spv.uniformArray.frag

View File

@ -639,7 +639,7 @@ public:
bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; } bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
// Crack the op into the individual dimensions of texturing operation. // Crack the op into the individual dimensions of texturing operation.
void crackTexture(TCrackedTextureOp& cracked) const void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
{ {
cracked.query = false; cracked.query = false;
cracked.proj = false; cracked.proj = false;
@ -651,6 +651,8 @@ public:
cracked.grad = false; cracked.grad = false;
switch (op) { switch (op) {
case EOpImageQuerySize:
case EOpImageQuerySamples:
case EOpTextureQuerySize: case EOpTextureQuerySize:
case EOpTextureQueryLod: case EOpTextureQueryLod:
case EOpTextureQueryLevels: case EOpTextureQueryLevels:
@ -670,10 +672,14 @@ public:
break; break;
case EOpTextureFetch: case EOpTextureFetch:
cracked.fetch = true; cracked.fetch = true;
if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
cracked.lod = true;
break; break;
case EOpTextureFetchOffset: case EOpTextureFetchOffset:
cracked.fetch = true; cracked.fetch = true;
cracked.offset = true; cracked.offset = true;
if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
cracked.lod = true;
break; break;
case EOpTextureProjOffset: case EOpTextureProjOffset:
cracked.offset = true; cracked.offset = true;

View File

@ -768,7 +768,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
} }
break; break;
case EOpReflect: case EOpReflect:
// I 2 * dot(N, I) * N: Arguments are (I, N). // I - 2 * dot(N, I) * N: Arguments are (I, N).
dot = childConstUnions[0].dot(childConstUnions[1]); dot = childConstUnions[0].dot(childConstUnions[1]);
dot *= 2.0; dot *= 2.0;
for (int comp = 0; comp < numComps; ++comp) for (int comp = 0; comp < numComps; ++comp)

View File

@ -4090,7 +4090,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
// "If the binding point for any uniform or shader storage block instance is less than zero, or greater than or // "If the binding point for any uniform or shader storage block instance is less than zero, or greater than or
// equal to the implementation-dependent maximum number of uniform buffer bindings, a compile-time // equal to the implementation-dependent maximum number of uniform buffer bindings, a compile-time
// error will occur. When the binding identifier is used with a uniform or shader storage block instanced as // error will occur. When the binding identifier is used with a uniform or shader storage block instanced as
// an array of size N, all elements of the array from binding through binding + N 1 must be within this // an array of size N, all elements of the array from binding through binding + N - 1 must be within this
// range." // range."
// //
if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock && type.getBasicType() != EbtAtomicUint) if (type.getBasicType() != EbtSampler && type.getBasicType() != EbtBlock && type.getBasicType() != EbtAtomicUint)