Revision: 1084
Author:
jo...@lunarg.com
Date: Mon May 25 23:01:59 2015 UTC
Log: Full stack: Images operations: Add intrinsics and support for
imageLoad, imageStore, and imageOp (for the image atomics). Add 38 image
layout formats, modifying metadata EMdSampler. (Atomics not yet
tested/turned-on. Memory qualifiers not yet represented. Image queries
not yet completed.)
https://code.google.com/p/lunarglass/source/detail?r=1084
Modified:
/trunk/Backends/GLSL/BottomToGLSL.cpp
/trunk/Core/LLVM/llvm-3.4/include/llvm/IR/IntrinsicsLunarGLASSTop.td
/trunk/Core/LunarGLASSTopIR.h
/trunk/Core/TopBuilder.cpp
/trunk/Core/TopBuilder.h
/trunk/Core/metadata.h
/trunk/Frontends/glslang/GlslangToTopVisitor.cpp
/trunk/test/310.comp
/trunk/test/baseResults/310.comp.out
=======================================
--- /trunk/Backends/GLSL/BottomToGLSL.cpp Sat May 23 02:49:49 2015 UTC
+++ /trunk/Backends/GLSL/BottomToGLSL.cpp Mon May 25 23:01:59 2015 UTC
@@ -1046,6 +1046,67 @@
return "";
}
}
+
+const char* MapGlaToImageQualifierString(MetaType metaType)
+{
+ if (metaType.mdSampler == 0)
+ return "";
+
+ // get the texture/image enum
+ const llvm::ConstantInt* constInt =
llvm::dyn_cast<llvm::ConstantInt>(metaType.mdSampler->getOperand(0));
+ if (constInt == 0)
+ return "";
+ EMdSampler image = (EMdSampler)constInt->getSExtValue();
+ if (image == EMsTexture || image == EMsImage)
+ return "";
+
+ switch (image) {
+ case EMsRgba32f: return "rgba32f";
+ case EMsRgba16f: return "rgba16f";
+ case EMsRg32f: return "rg32f";
+ case EMsRg16f: return "rg16f";
+ case EMsR11fG11fB10f: return "r11f_g11f_b10f";
+ case EMsR32f: return "r32f";
+ case EMsR16f: return "r16f";
+ case EMsRgba16: return "rgba16";
+ case EMsRgb10A2: return "rgb10_a2";
+ case EMsRgba8: return "rgba8";
+ case EMsRg16: return "rg16";
+ case EMsRg8: return "rg8";
+ case EMsR16: return "r16";
+ case EMsR8: return "r8";
+ case EMsRgba16Snorm: return "rgba16_snorm";
+ case EMsRgba8Snorm: return "rgba8_snorm";
+ case EMsRg16Snorm: return "rg16_snorm";
+ case EMsRg8Snorm: return "rg8_snorm";
+ case EMsR16Snorm: return "r16_snorm";
+ case EMsR8Snorm: return "r8_snorm";
+
+ case EMsRgba32i: return "rgba32i";
+ case EMsRgba16i: return "rgba16i";
+ case EMsRgba8i: return "rgba8i";
+ case EMsRg32i: return "rg32i";
+ case EMsRg16i: return "rg16i";
+ case EMsRg8i: return "rg8i";
+ case EMsR32i: return "r32i";
+ case EMsR16i: return "r16i";
+ case EMsR8i: return "r8i";
+
+ case EMsRgba32ui: return "rgba32ui";
+ case EMsRgba16ui: return "rgba16ui";
+ case EMsRgba8ui: return "rgba8ui";
+ case EMsRg32ui: return "rg32ui";
+ case EMsRg16ui: return "rg16ui";
+ case EMsRg8ui: return "rg8ui";
+ case EMsR32ui: return "r32ui";
+ case EMsR16ui: return "r16ui";
+ case EMsR8ui: return "r8ui";
+
+ default:
+ UnsupportedFunctionality("image format", EATContinue);
+ return "";
+ }
+}
const char* MapGlaToPrecisionString(EMdPrecision precision)
{
@@ -2871,10 +2932,13 @@
EMdPrecision precision = GetPrecision(llvmInstruction);
Assignment assignment(this, llvmInstruction);
+ if (llvmInstruction->getType()->getTypeID() == llvm::Type::VoidTyID)
+ assignment.setNoLvalue();
// Handle texturing
bool gather = false;
bool refZemitted = false;
+ bool load = false;
switch (llvmInstruction->getIntrinsicID()) {
case llvm::Intrinsic::gla_queryTextureSize:
case llvm::Intrinsic::gla_queryTextureSizeNoLod:
@@ -2904,6 +2968,36 @@
//case llvm::Intrinsic::gla_queryTextureLevels:
// TODO: 430 Functionality: textureQueryLevels()
+ case llvm::Intrinsic::gla_imageLoad:
+ case llvm::Intrinsic::gla_fImageLoad:
+ load = true;
+ // fall through
+ case llvm::Intrinsic::gla_imageStoreI:
+ case llvm::Intrinsic::gla_imageStoreF:
+ case llvm::Intrinsic::gla_imageOp:
+ {
+ bool needConversion =
samplerIsUint(llvmInstruction->getOperand(GetTextureOpIndex(ETOSamplerLoc)));
+ if (needConversion)
+ ConversionStart(assignment, llvmInstruction->getType(), false);
+ emitGlaSamplerFunction(assignment, llvmInstruction,
GetConstantInt(llvmInstruction->getOperand(GetTextureOpIndex(ETOFlag))));
+ assignment << "(";
+ emitGlaOperand(assignment,
llvmInstruction->getOperand(GetTextureOpIndex(ETOSamplerLoc)));
+ assignment << ", ";
+ emitGlaOperand(assignment,
llvmInstruction->getOperand(GetTextureOpIndex(ETOCoord)));
+
+ if (! load) {
+ assignment << ", ";
+ emitGlaOperand(assignment,
llvmInstruction->getOperand(GetTextureOpIndex(ETOImageData)));
+ }
+
+ if (needConversion)
+ ConversionStop(assignment, llvmInstruction->getType());
+ assignment << ")";
+
+ assignment.emit();
+
+ return;
+ }
case llvm::Intrinsic::gla_texelGather:
case llvm::Intrinsic::gla_fTexelGather:
case llvm::Intrinsic::gla_texelGatherOffset:
@@ -3417,9 +3511,6 @@
if (callString == 0)
UnsupportedFunctionality("Intrinsic in Bottom IR", EATContinue);
- if (llvmInstruction->getType()->getTypeID() == llvm::Type::VoidTyID)
- assignment.setNoLvalue();
-
if (convertResultToInt)
ConversionStart(assignment, llvmInstruction->getType(), false);
@@ -3526,6 +3617,27 @@
const llvm::Value* samplerType = llvmInstruction->getOperand(0);
// TODO: uint functionality: See if it's a uint sampler, requiring a
constructor to convert it
+
+ int imageOp = (texFlags & ETFImageOp) >> ImageOpShift;
+ if (imageOp) {
+ switch (imageOp) {
+ case EImageLoad: out << "imageLoad"; break;
+ case EImageStore: out << "imageStore"; break;
+ case EImageAtomicAdd: out << "imageAtomicAdd"; break;
+ case EImageAtomicMin: out << "imageAtomicMin"; break;
+ case EImageAtomicMax: out << "imageAtomicMax"; break;
+ case EImageAtomicAnd: out << "imageAtomicAnd"; break;
+ case EImageAtomicOr: out << "imageAtomicOr"; break;
+ case EImageAtomicXor: out << "imageAtomicXor"; break;
+ case EImageAtomicExchange: out << "imageAtomicExchange"; break;
+ case EImageAtomicCompSwap: out << "imageAtomicCompSwap"; break;
+ default:
+ UnsupportedFunctionality("image op");
+ break;
+ }
+
+ return;
+ }
// Original style shadowing returns vec4 while 2nd generation returns
float,
// so, have to stick to old-style for those cases.
@@ -3689,6 +3801,9 @@
const char* qualifierString = MapGlaToQualifierString(version, stage,
qualifier, metaType);
if (*qualifierString)
out << qualifierString << " ";
+ qualifierString = MapGlaToImageQualifierString(metaType);
+ if (*qualifierString)
+ out << "layout(" << qualifierString << ") ";
if (type->getTypeID() == llvm::Type::PointerTyID)
type = type->getContainedType(0);
@@ -3874,8 +3989,7 @@
}
switch (mdSampler) {
case EMsTexture: out << "sampler"; break;
- case EMsImage: out << "image"; break;
- default: UnsupportedFunctionality("kind of sampler");
break;
+ default: out << "image"; break;
}
switch (mdSamplerDim) {
case EMsd1D: out << "1D"; break;
=======================================
--- /trunk/Core/LLVM/llvm-3.4/include/llvm/IR/IntrinsicsLunarGLASSTop.td
Tue May 20 20:18:57 2014 UTC
+++ /trunk/Core/LLVM/llvm-3.4/include/llvm/IR/IntrinsicsLunarGLASSTop.td
Mon May 25 23:01:59 2015 UTC
@@ -212,6 +212,15 @@
def int_gla_queryTextureSizeNoLod : Intrinsic<[llvm_anyint_ty],
[llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_gla_fQueryTextureLod : Intrinsic<[llvm_anyfloat_ty],
[llvm_i32_ty, llvm_i32_ty, llvm_anyfloat_ty], [IntrNoMem]>;
}
+
+// Images
+let TargetPrefix = "gla" in {
+ def int_gla_imageLoad : Intrinsic<[llvm_anyint_ty], [llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_anyint_ty], [IntrReadArgMem]>;
+ def int_gla_fImageLoad: Intrinsic<[llvm_anyfloat_ty], [llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_anyint_ty], [IntrReadArgMem]>;
+ def int_gla_imageStoreI: Intrinsic<[], [llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_anyint_ty, llvm_v4i32_ty], [IntrReadWriteArgMem]>;
+ def int_gla_imageStoreF: Intrinsic<[], [llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_anyint_ty, llvm_v4f32_ty], [IntrReadWriteArgMem]>;
+ def int_gla_imageOp: Intrinsic<[llvm_i32_ty], [llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_anyint_ty, llvm_i32_ty],
[IntrReadWriteArgMem]>;
+}
// Geometry
let TargetPrefix = "gla" in {
=======================================
--- /trunk/Core/LunarGLASSTopIR.h Mon Jul 21 06:52:19 2014 UTC
+++ /trunk/Core/LunarGLASSTopIR.h Mon May 25 23:01:59 2015 UTC
@@ -60,22 +60,39 @@
ESampler2DMS,
};
+ enum EImageOp {
+ EImageNoop,
+ EImageLoad,
+ EImageStore,
+ EImageAtomicAdd,
+ EImageAtomicMin,
+ EImageAtomicMax,
+ EImageAtomicAnd,
+ EImageAtomicOr,
+ EImageAtomicXor,
+ EImageAtomicExchange,
+ EImageAtomicCompSwap,
+ };
+
enum ETextureFlags {
- ETFProjected = 0x0001,
- ETFBias = 0x0002,
- ETFLod = 0x0004,
- ETFShadow = 0x0008,
- ETFArrayed = 0x0010,
- ETFFetch = 0x0020,
- ETFGather = 0x0040,
- ETFBiasLodArg = 0x0080,
- ETFOffsetArg = 0x0100,
- ETFSampleArg = 0x0200,
- ETFComponentArg = 0x0400,
- ETFRefZArg = 0x0800,
- ETFProjectedArg = 0x1000,
- ETFOffsets = 0x2000, // means offset argument is an array
that needs to be broken up
+ ETFProjected = 0x00000001,
+ ETFBias = 0x00000002,
+ ETFLod = 0x00000004,
+ ETFShadow = 0x00000008,
+ ETFArrayed = 0x00000010,
+ ETFFetch = 0x00000020,
+ ETFGather = 0x00000040,
+ ETFBiasLodArg = 0x00000080,
+ ETFOffsetArg = 0x00000100,
+ ETFSampleArg = 0x00000200,
+ ETFComponentArg = 0x00000400,
+ ETFRefZArg = 0x00000800,
+ ETFProjectedArg = 0x00001000,
+ ETFOffsets = 0x00002000, // means offset argument is an
array that needs to be broken up
+ //ETF = 0x00008000, // placeholder for future growth
+ ETFImageOp = 0x000F0000, // wide slot to hold an EImageOp
value, see ImageOpShift below and EImageOp above
};
+ static const int ImageOpShift = 16;
// Texture op, for mapping operands
enum ETextureOperand {
@@ -89,6 +106,7 @@
ETODPdx = 7,
ETODPdy = 8,
};
+ static const ETextureOperand ETOImageData = (ETextureOperand)4;
inline int GetTextureOpIndex(ETextureOperand operand, bool SoA =
false, int numComps = 0, int comp = 0)
{
=======================================
--- /trunk/Core/TopBuilder.cpp Sat May 23 02:49:49 2015 UTC
+++ /trunk/Core/TopBuilder.cpp Mon May 25 23:01:59 2015 UTC
@@ -1714,8 +1714,8 @@
return createSwizzle(precision, scalar, 0x00, vectorType);
}
-// Accept all parameters needed to create LunarGLASS texture intrinsics
-// Select the correct intrinsic based on the inputs, and make the call
+// Accept all parameters needed to create LunarGLASS texture intrinsics.
+// Select the correct intrinsic based on the inputs, and make the call.
llvm::Value* Builder::createTextureCall(gla::EMdPrecision precision,
llvm::Type* resultType, gla::ESamplerType samplerType, int texFlags, const
TextureParameters& parameters, const char* name)
{
bool floatReturn = gla::GetBasicType(resultType)->isFloatTy();
@@ -1927,6 +1927,84 @@
return instr;
}
+
+// Accept all parameters needed to create LunarGLASS image intrinsics.
+// Select the correct intrinsic based on the inputs, and make the call.
+llvm::Value* Builder::createImageCall(gla::EMdPrecision precision,
llvm::Type* resultType, gla::ESamplerType samplerType, int texFlags,
+ const TextureParameters& parameters,
const char* name)
+{
+ name = name ? name : "image";
+
+ // Max args based on LunarGLASS TopIR, no SOA
+ static const int maxArgs = 5;
+ llvm::Value* imageArgs[maxArgs] = {};
+
+ // Base case: First arguments are fixed
+ int numArgs = 4;
+ const int dataArg = 4;
+ imageArgs[GetTextureOpIndex(ETOSamplerType)] =
MakeIntConstant(context, samplerType);
+ imageArgs[GetTextureOpIndex(ETOSamplerLoc)] = parameters.ETPSampler;
+ imageArgs[GetTextureOpIndex(ETOFlag)] =
MakeUnsignedConstant(context, *(int*)&texFlags);
+ imageArgs[GetTextureOpIndex(ETOCoord)] = parameters.ETPCoords;
+
+ // Add the data argument if needed, and select which intrinsic to call.
+ llvm::Intrinsic::ID intrinsicID = llvm::Intrinsic::not_intrinsic;
+ switch ((texFlags & ETFImageOp) >> ImageOpShift) {
+ case EImageLoad:
+ if (gla::GetBasicType(resultType)->isFloatTy())
+ intrinsicID = llvm::Intrinsic::gla_fImageLoad;
+ else
+ intrinsicID = llvm::Intrinsic::gla_imageLoad;
+ break;
+ case EImageStore:
+ if (gla::GetBasicType(parameters.ETPData)->isFloatTy())
+ intrinsicID = llvm::Intrinsic::gla_imageStoreF;
+ else
+ intrinsicID = llvm::Intrinsic::gla_imageStoreI;
+ imageArgs[dataArg] = parameters.ETPData;
+ ++numArgs;
+ break;
+ default:
+ intrinsicID = llvm::Intrinsic::gla_imageOp;
+ break;
+ }
+
+ llvm::Function* intrinsic = 0;
+
+ // Initialize required operands based on intrinsic
+ switch (intrinsicID) {
+ case llvm::Intrinsic::gla_fImageLoad:
+ case llvm::Intrinsic::gla_imageLoad:
+ intrinsic = getIntrinsic(intrinsicID, resultType,
imageArgs[GetTextureOpIndex(ETOCoord)]->getType());
+ break;
+
+ case llvm::Intrinsic::gla_imageStoreF:
+ case llvm::Intrinsic::gla_imageStoreI:
+ name = 0;
+ intrinsic = getIntrinsic(intrinsicID,
imageArgs[GetTextureOpIndex(ETOCoord)]->getType());
+ break;
+
+ case llvm::Intrinsic::gla_imageOp:
+ intrinsic = getIntrinsic(intrinsicID,
imageArgs[GetTextureOpIndex(ETOCoord)]->getType());
+ break;
+
+ default:
+ // caught be upcoming assert
+ break;
+ }
+
+ assert(intrinsic);
+
+ // Make the call: Those with no return value cannot have a name
argument.
+ llvm::Instruction* instr;
+ if (name)
+ instr = builder.CreateCall(intrinsic,
llvm::ArrayRef<llvm::Value*>(imageArgs, imageArgs + numArgs), name);
+ else
+ instr = builder.CreateCall(intrinsic,
llvm::ArrayRef<llvm::Value*>(imageArgs, imageArgs + numArgs));
+ setInstructionPrecision(instr, precision);
+
+ return instr;
+}
// Comments in header
llvm::Value* Builder::createTextureQueryCall(gla::EMdPrecision precision,
llvm::Intrinsic::ID intrinsicID, llvm::Type* returnType, llvm::Constant*
samplerType, llvm::Value* sampler,
=======================================
--- /trunk/Core/TopBuilder.h Mon May 11 01:14:44 2015 UTC
+++ /trunk/Core/TopBuilder.h Mon May 25 23:01:59 2015 UTC
@@ -373,10 +373,12 @@
llvm::Value* ETPSampleNum;
llvm::Value* ETPSampler;
llvm::Value* ETPDimensions;
+ llvm::Value* ETPData; // for image*() data argument
};
// Select the correct intrinsic based on all inputs, and make the call
llvm::Value* createTextureCall(EMdPrecision, llvm::Type*,
ESamplerType, int texFlags, const TextureParameters&, const char* name = 0);
+ llvm::Value* createImageCall(EMdPrecision, llvm::Type*, ESamplerType,
int texFlags, const TextureParameters&, const char* name = 0);
llvm::Value* createTextureQueryCall(EMdPrecision, llvm::Intrinsic::ID,
llvm::Type*, llvm::Constant*, llvm::Value*, llvm::Value*, const char* name
= 0);
llvm::Value* createSamplePositionCall(EMdPrecision, llvm::Type*,
llvm::Value*);
llvm::Value* createBitFieldExtractCall(EMdPrecision, llvm::Value*,
llvm::Value*, llvm::Value*, bool isSigned);
=======================================
--- /trunk/Core/metadata.h Thu May 21 01:11:19 2015 UTC
+++ /trunk/Core/metadata.h Mon May 25 23:01:59 2015 UTC
@@ -79,6 +79,7 @@
//
// !sampler -> { EMdSampler, Value*, EMdSamplerDim, array, shadow,
EMdSamplerBaseType }
// Notes:
+// - EMdSampler says whether it is an image or texture, and if an
image what its format is
// - texel return value has the same type as Value*, modified by
EMdSamplerBaseType (e.g., unsigned int)
// - array is bool, true if it is a samplerArray
// - shadow is bool, true if it is a samplerShadow
@@ -221,7 +222,54 @@
// What kind of sampler
enum EMdSampler {
EMsTexture,
+
+ // Image with no format
EMsImage,
+
+ // Floating-point format image
+ EMsRgba32f,
+ EMsRgba16f,
+ EMsR32f,
+ EMsRgba8,
+ EMsRgba8Snorm,
+ EMsRg32f,
+ EMsRg16f,
+ EMsR11fG11fB10f,
+ EMsR16f,
+ EMsRgba16,
+ EMsRgb10A2,
+ EMsRg16,
+ EMsRg8,
+ EMsR16,
+ EMsR8,
+ EMsRgba16Snorm,
+ EMsRg16Snorm,
+ EMsRg8Snorm,
+ EMsR16Snorm,
+ EMsR8Snorm,
+
+ // signed-int format image
+ EMsRgba32i,
+ EMsRgba16i,
+ EMsRgba8i,
+ EMsR32i,
+ EMsRg32i,
+ EMsRg16i,
+ EMsRg8i,
+ EMsR16i,
+ EMsR8i,
+
+ // unsigned-int format image
+ EMsRgba32ui,
+ EMsRgba16ui,
+ EMsRgba8ui,
+ EMsR32ui,
+ EMsRg32ui,
+ EMsRg16ui,
+ EMsRg8ui,
+ EMsR16ui,
+ EMsR8ui,
+
EMsCount,
};
=======================================
--- /trunk/Frontends/glslang/GlslangToTopVisitor.cpp Sat May 23 02:49:49
2015 UTC
+++ /trunk/Frontends/glslang/GlslangToTopVisitor.cpp Mon May 25 23:01:59
2015 UTC
@@ -101,6 +101,9 @@
void handleFunctionEntry(const glslang::TIntermAggregate* node);
void translateArguments(const glslang::TIntermSequence&
glslangArguments, std::vector<llvm::Value*>& arguments);
llvm::Value* handleBuiltinFunctionCall(const
glslang::TIntermAggregate*);
+ llvm::Value* handleTexImageQuery(const glslang::TIntermAggregate*,
const std::vector<llvm::Value*>& arguments, gla::ESamplerType);
+ llvm::Value* handleImageAccess(const glslang::TIntermAggregate*, const
std::vector<llvm::Value*>& arguments, gla::ESamplerType, int flags);
+ llvm::Value* handleTextureAccess(const glslang::TIntermAggregate*,
const std::vector<llvm::Value*>& arguments, gla::ESamplerType, int flags);
llvm::Value* handleUserFunctionCall(const glslang::TIntermAggregate*);
llvm::Value* createBinaryOperation(glslang::TOperator op,
gla::EMdPrecision, llvm::Value* left, llvm::Value* right, bool isUnsigned,
bool reduceComparison = true);
@@ -260,10 +263,55 @@
gla::EMdSampler GetMdSampler(const glslang::TType& type)
{
- if (type.getSampler().image)
- return gla::EMsImage;
- else
+ if (! type.getSampler().image)
return gla::EMsTexture;
+
+ // The rest is for images
+
+ switch (type.getQualifier().layoutFormat) {
+ case glslang::ElfNone: return gla::EMsImage;
+ case glslang::ElfRgba32f: return gla::EMsRgba32f;
+ case glslang::ElfRgba16f: return gla::EMsRgba16f;
+ case glslang::ElfR32f: return gla::EMsR32f;
+ case glslang::ElfRgba8: return gla::EMsRgba8;
+ case glslang::ElfRgba8Snorm: return gla::EMsRgba8Snorm;
+ case glslang::ElfRg32f: return gla::EMsRg32f;
+ case glslang::ElfRg16f: return gla::EMsRg16f;
+ case glslang::ElfR11fG11fB10f: return gla::EMsR11fG11fB10f;
+ case glslang::ElfR16f: return gla::EMsR16f;
+ case glslang::ElfRgba16: return gla::EMsRgba16;
+ case glslang::ElfRgb10A2: return gla::EMsRgb10A2;
+ case glslang::ElfRg16: return gla::EMsRg16;
+ case glslang::ElfRg8: return gla::EMsRg8;
+ case glslang::ElfR16: return gla::EMsR16;
+ case glslang::ElfR8: return gla::EMsR8;
+ case glslang::ElfRgba16Snorm: return gla::EMsRgba16Snorm;
+ case glslang::ElfRg16Snorm: return gla::EMsRg16Snorm;
+ case glslang::ElfRg8Snorm: return gla::EMsRg8Snorm;
+ case glslang::ElfR16Snorm: return gla::EMsR16Snorm;
+ case glslang::ElfR8Snorm: return gla::EMsR8Snorm;
+ case glslang::ElfRgba32i: return gla::EMsRgba32i;
+ case glslang::ElfRgba16i: return gla::EMsRgba16i;
+ case glslang::ElfRgba8i: return gla::EMsRgba8i;
+ case glslang::ElfR32i: return gla::EMsR32i;
+ case glslang::ElfRg32i: return gla::EMsRg32i;
+ case glslang::ElfRg16i: return gla::EMsRg16i;
+ case glslang::ElfRg8i: return gla::EMsRg8i;
+ case glslang::ElfR16i: return gla::EMsR16i;
+ case glslang::ElfR8i: return gla::EMsR8i;
+ case glslang::ElfRgba32ui: return gla::EMsRgba32ui;
+ case glslang::ElfRgba16ui: return gla::EMsRgba16ui;
+ case glslang::ElfRgba8ui: return gla::EMsRgba8ui;
+ case glslang::ElfR32ui: return gla::EMsR32ui;
+ case glslang::ElfRg32ui: return gla::EMsRg32ui;
+ case glslang::ElfRg16ui: return gla::EMsRg16ui;
+ case glslang::ElfRg8ui: return gla::EMsRg8ui;
+ case glslang::ElfR16ui: return gla::EMsR16ui;
+ case glslang::ElfR8ui: return gla::EMsR8ui;
+ default:
+ gla::UnsupportedFunctionality("unknown image format",
gla::EATContinue);
+ return gla::EMsImage;
+ }
}
gla::EMdSamplerDim GetMdSamplerDim(const glslang::TType& type)
@@ -1572,8 +1620,6 @@
std::vector<llvm::Value*> arguments;
translateArguments(node->getSequence(), arguments);
- gla::EMdPrecision precision = GetMdPrecision(node->getType());
-
if (node->getName() == "ftransform(") {
// TODO: back-end functionality: if this needs to support
decomposition, need to simulate
// access to the external gl_Vertex and
gl_ModelViewProjectionMatrix.
@@ -1584,12 +1630,14 @@
llvm::Value* matrix =
glaBuilder->createVariable(gla::Builder::ESQGlobal, 0,
llvm::VectorType::get(gla::GetFloatType(context), 4),
0,
0, "gl_ModelViewProjectionMatrix_sim");
- return glaBuilder->createIntrinsicCall(precision,
llvm::Intrinsic::gla_fFixedTransform, glaBuilder->createLoad(vertex),
glaBuilder->createLoad(matrix));
+ return
glaBuilder->createIntrinsicCall(GetMdPrecision(node->getType()),
llvm::Intrinsic::gla_fFixedTransform, glaBuilder->createLoad(vertex),
glaBuilder->createLoad(matrix));
}
- if (node->getName().substr(0, 7) == "texture" ||
node->getName().substr(0, 5) == "texel" || node->getName().substr(0, 6)
== "shadow") {
+ if (node->getName().substr(0, 7) == "texture" ||
node->getName().substr(0, 5) == "texel" || node->getName().substr(0, 6)
== "shadow" ||
+ node->getName().substr(0, 5) == "image") {
+ const glslang::TSampler& sampler =
node->getSequence()[0]->getAsTyped()->getType().getSampler();
gla::ESamplerType samplerType;
- switch
(node->getSequence()[0]->getAsTyped()->getType().getSampler().dim) {
+ switch (sampler.dim) {
case glslang::Esd1D: samplerType = gla::ESampler1D;
break;
case glslang::Esd2D: samplerType = gla::ESampler2D;
break;
case glslang::Esd3D: samplerType = gla::ESampler3D;
break;
@@ -1600,142 +1648,199 @@
gla::UnsupportedFunctionality("sampler type");
break;
}
- if
(node->getSequence()[0]->getAsTyped()->getType().getSampler().ms)
+ if (
sampler.ms)
samplerType = gla::ESampler2DMS;
- if (node->getName().find("Size", 0) != std::string::npos) {
- llvm::Value* lastArg;
- llvm::Intrinsic::ID intrinsicID;
+ if (node->getName().find("Size", 0) != std::string::npos ||
+ node->getName().find("Query", 0) != std::string::npos)
+ return handleTexImageQuery(node, arguments, samplerType);
+
+ int texFlags = 0;
+
+ if (sampler.arrayed)
+ texFlags |= gla::ETFArrayed;
+
+ if (sampler.shadow)
+ texFlags |= gla::ETFShadow;
+
+ if (sampler.image)
+ return handleImageAccess(node, arguments, samplerType,
texFlags);
+ else
+ return handleTextureAccess(node, arguments, samplerType,
texFlags);
+ }
+
+ return 0;
+}
+
+llvm::Value* TGlslangToTopTraverser::handleTexImageQuery(const
glslang::TIntermAggregate* node, const std::vector<llvm::Value*>&
arguments, gla::ESamplerType samplerType)
+{
+ gla::EMdPrecision precision = GetMdPrecision(node->getType());
- if
(node->getSequence()[0]->getAsTyped()->getType().getSampler().ms ||
- samplerType == gla::ESamplerBuffer || samplerType ==
gla::ESampler2DRect) {
- lastArg = 0;
- intrinsicID = llvm::Intrinsic::gla_queryTextureSizeNoLod;
- } else {
- assert(arguments.size() > 1);
- lastArg = arguments[1];
- intrinsicID = llvm::Intrinsic::gla_queryTextureSize;
- }
+ if (node->getName().find("Size", 0) != std::string::npos) {
+ llvm::Value* lastArg;
+ llvm::Intrinsic::ID intrinsicID;
- return glaBuilder->createTextureQueryCall(precision,
- intrinsicID,
-
convertGlslangToGlaType(node->getType()),
-
MakeIntConstant(context, samplerType),
- arguments[0],
lastArg, leftName);
+ if (samplerType == gla::ESampler2DMS || samplerType ==
gla::ESamplerBuffer || samplerType == gla::ESampler2DRect) {
+ lastArg = 0;
+ intrinsicID = llvm::Intrinsic::gla_queryTextureSizeNoLod;
+ } else {
+ assert(arguments.size() > 1);
+ lastArg = arguments[1];
+ intrinsicID = llvm::Intrinsic::gla_queryTextureSize;
}
- if (node->getName().find("Query", 0) != std::string::npos) {
- if (node->getName().find("Lod", 0) != std::string::npos) {
- gla::UnsupportedFunctionality("textureQueryLod");
- return glaBuilder->createTextureQueryCall(precision,
-
llvm::Intrinsic::gla_fQueryTextureLod,
-
convertGlslangToGlaType(node->getType()),
-
MakeIntConstant(context, samplerType),
- arguments[0],
arguments[1], leftName);
- } else if (node->getName().find("Levels", 0) !=
std::string::npos) {
- gla::UnsupportedFunctionality("textureQueryLevels");
- }
- }
+ return glaBuilder->createTextureQueryCall(precision,
+ intrinsicID,
+
convertGlslangToGlaType(node->getType()),
+ MakeIntConstant(context,
samplerType),
+ arguments[0], lastArg,
leftName);
+ }
- int texFlags = 0;
+ if (node->getName().find("Query", 0) != std::string::npos) {
if (node->getName().find("Lod", 0) != std::string::npos) {
- texFlags |= gla::ETFLod;
- texFlags |= gla::ETFBiasLodArg;
- }
+ gla::UnsupportedFunctionality("textureQueryLod");
+ return glaBuilder->createTextureQueryCall(precision,
+
llvm::Intrinsic::gla_fQueryTextureLod,
+
convertGlslangToGlaType(node->getType()),
+
MakeIntConstant(context, samplerType),
+ arguments[0],
arguments[1], leftName);
+ } else if (node->getName().find("Levels", 0) != std::string::npos)
+ gla::UnsupportedFunctionality("textureQueryLevels");
+ }
+
+ return 0;
+}
+
+llvm::Value* TGlslangToTopTraverser::handleImageAccess(const
glslang::TIntermAggregate* node, const std::vector<llvm::Value*>&
arguments, gla::ESamplerType samplerType, int texFlags)
+{
+ // set the arguments
+ gla::Builder::TextureParameters params = {};
+ params.ETPSampler = arguments[0];
+ params.ETPCoords = arguments[1];
+
+ gla::EImageOp imageOp;
+ if (node->getName().find("Load", 0) != std::string::npos)
+ imageOp = gla::EImageLoad;
+ else if (node->getName().find("Store", 0) != std::string::npos)
+ imageOp = gla::EImageStore;
+ else if (node->getName().find("AtomicAdd", 0) != std::string::npos)
+ imageOp = gla::EImageAtomicAdd;
+ else if (node->getName().find("AtomicMin", 0) != std::string::npos)
+ imageOp = gla::EImageAtomicMin;
+ else if (node->getName().find("AtomicMax", 0) != std::string::npos)
+ imageOp = gla::EImageAtomicMax;
+ else if (node->getName().find("AtomicAnd", 0) != std::string::npos)
+ imageOp = gla::EImageAtomicAnd;
+ else if (node->getName().find("AtomicOr", 0) != std::string::npos)
+ imageOp = gla::EImageAtomicOr;
+ else if (node->getName().find("AtomicXor", 0) != std::string::npos)
+ imageOp = gla::EImageAtomicXor;
+ else if (node->getName().find("AtomicExchange", 0) !=
std::string::npos)
+ imageOp = gla::EImageAtomicExchange;
+ else if (node->getName().find("AtomicCompSwap", 0) !=
std::string::npos)
+ imageOp = gla::EImageAtomicCompSwap;
+ else
+ gla::UnsupportedFunctionality("image access");
- if (node->getName().find("Proj", 0) != std::string::npos)
- texFlags |= gla::ETFProjected;
+ texFlags |= (imageOp << gla::ImageOpShift);
- if (node->getName().find("Offset", 0) != std::string::npos) {
- texFlags |= gla::ETFOffsetArg;
- if (node->getName().find("Offsets", 0) != std::string::npos)
- texFlags |= gla::ETFOffsets;
- }
+ if (imageOp != gla::EImageLoad)
+ params.ETPData = arguments[2];
- if (node->getName().find("Fetch", 0) != std::string::npos) {
- texFlags |= gla::ETFFetch;
- switch (samplerType) {
- case gla::ESampler1D:
- case gla::ESampler2D:
- case gla::ESampler3D:
- texFlags |= gla::ETFLod;
- texFlags |= gla::ETFBiasLodArg;
- break;
- case gla::ESampler2DMS:
- texFlags |= gla::ETFSampleArg;
- default:
- break;
- }
- }
+ return glaBuilder->createImageCall(GetMdPrecision(node->getType()),
convertGlslangToGlaType(node->getType()), samplerType, texFlags, params,
leftName);
+}
- if
(node->getSequence()[0]->getAsTyped()->getType().getSampler().shadow)
- texFlags |= gla::ETFShadow;
-
- if (node->getName().find("Gather", 0) != std::string::npos) {
- texFlags |= gla::ETFGather;
- if (texFlags & gla::ETFShadow)
- texFlags |= gla::ETFRefZArg;
- }
+llvm::Value* TGlslangToTopTraverser::handleTextureAccess(const
glslang::TIntermAggregate* node, const std::vector<llvm::Value*>&
arguments, gla::ESamplerType samplerType, int texFlags)
+{
+ if (node->getName().find("Lod", 0) != std::string::npos) {
+ texFlags |= gla::ETFLod;
+ texFlags |= gla::ETFBiasLodArg;
+ }
- if
(node->getSequence()[0]->getAsTyped()->getType().getSampler().arrayed)
- texFlags |= gla::ETFArrayed;
+ if (node->getName().find("Proj", 0) != std::string::npos)
+ texFlags |= gla::ETFProjected;
- // check for bias argument
- if (! (texFlags & gla::ETFLod) && ! (texFlags & gla::ETFGather)) {
- int nonBiasArgCount = 2;
- if (texFlags & gla::ETFOffsetArg)
- ++nonBiasArgCount;
- if (texFlags & gla::ETFBiasLodArg)
- ++nonBiasArgCount;
- if (node->getName().find("Grad", 0) != std::string::npos)
- nonBiasArgCount += 2;
+ if (node->getName().find("Offset", 0) != std::string::npos) {
+ texFlags |= gla::ETFOffsetArg;
+ if (node->getName().find("Offsets", 0) != std::string::npos)
+ texFlags |= gla::ETFOffsets;
+ }
- if ((int)arguments.size() > nonBiasArgCount) {
- texFlags |= gla::ETFBias;
- texFlags |= gla::ETFBiasLodArg;
- }
+ if (node->getName().find("Fetch", 0) != std::string::npos) {
+ texFlags |= gla::ETFFetch;
+ switch (samplerType) {
+ case gla::ESampler1D:
+ case gla::ESampler2D:
+ case gla::ESampler3D:
+ texFlags |= gla::ETFLod;
+ texFlags |= gla::ETFBiasLodArg;
+ break;
+ case gla::ESampler2DMS:
+ texFlags |= gla::ETFSampleArg;
+ default:
+ break;
}
+ }
- // check for comp argument
- if ((texFlags & gla::ETFGather) && ! (texFlags & gla::ETFShadow)) {
- int nonCompArgCount = 2;
- if (texFlags & gla::ETFOffsetArg)
- ++nonCompArgCount;
- if ((int)arguments.size() > nonCompArgCount)
- texFlags |= gla::ETFComponentArg;
+ if (node->getName().find("Gather", 0) != std::string::npos) {
+ texFlags |= gla::ETFGather;
+ if (texFlags & gla::ETFShadow)
+ texFlags |= gla::ETFRefZArg;
+ }
+
+ // check for bias argument
+ if (! (texFlags & gla::ETFLod) && ! (texFlags & gla::ETFGather)) {
+ int nonBiasArgCount = 2;
+ if (texFlags & gla::ETFOffsetArg)
+ ++nonBiasArgCount;
+ if (texFlags & gla::ETFBiasLodArg)
+ ++nonBiasArgCount;
+ if (node->getName().find("Grad", 0) != std::string::npos)
+ nonBiasArgCount += 2;
+
+ if ((int)arguments.size() > nonBiasArgCount) {
+ texFlags |= gla::ETFBias;
+ texFlags |= gla::ETFBiasLodArg;
}
+ }
- // set the arguments
- gla::Builder::TextureParameters params = {};
- params.ETPSampler = arguments[0];
- params.ETPCoords = arguments[1];
- int extraArgs = 0;
- if (texFlags & gla::ETFLod) {
- params.ETPBiasLod = arguments[2];
- ++extraArgs;
- }
- if (node->getName().find("Grad", 0) != std::string::npos) {
- params.ETPGradX = arguments[2 + extraArgs];
- params.ETPGradY = arguments[3 + extraArgs];
- extraArgs += 2;
- }
- if (texFlags & gla::ETFRefZArg) {
- params.ETPShadowRef = arguments[2 + extraArgs];
- ++extraArgs;
- }
- if (texFlags & gla::ETFOffsetArg) {
- params.ETPOffset = arguments[2 + extraArgs];
- ++extraArgs;
- }
- if ((texFlags & gla::ETFBias) || (texFlags &
gla::ETFComponentArg)) {
- params.ETPBiasLod = arguments[2 + extraArgs];
- ++extraArgs;
- }
+ // check for comp argument
+ if ((texFlags & gla::ETFGather) && ! (texFlags & gla::ETFShadow)) {
+ int nonCompArgCount = 2;
+ if (texFlags & gla::ETFOffsetArg)
+ ++nonCompArgCount;
+ if ((int)arguments.size() > nonCompArgCount)
+ texFlags |= gla::ETFComponentArg;
+ }
- return glaBuilder->createTextureCall(precision,
convertGlslangToGlaType(node->getType()), samplerType, texFlags, params,
leftName);
+ // set the arguments
+ gla::Builder::TextureParameters params = {};
+ params.ETPSampler = arguments[0];
+ params.ETPCoords = arguments[1];
+ int extraArgs = 0;
+ if (texFlags & gla::ETFLod) {
+ params.ETPBiasLod = arguments[2];
+ ++extraArgs;
+ }
+ if (node->getName().find("Grad", 0) != std::string::npos) {
+ params.ETPGradX = arguments[2 + extraArgs];
+ params.ETPGradY = arguments[3 + extraArgs];
+ extraArgs += 2;
+ }
+ if (texFlags & gla::ETFRefZArg) {
+ params.ETPShadowRef = arguments[2 + extraArgs];
+ ++extraArgs;
+ }
+ if (texFlags & gla::ETFOffsetArg) {
+ params.ETPOffset = arguments[2 + extraArgs];
+ ++extraArgs;
+ }
+ if ((texFlags & gla::ETFBias) || (texFlags & gla::ETFComponentArg)) {
+ params.ETPBiasLod = arguments[2 + extraArgs];
+ ++extraArgs;
}
- return 0;
+ return glaBuilder->createTextureCall(GetMdPrecision(node->getType()),
convertGlslangToGlaType(node->getType()), samplerType, texFlags, params,
leftName);
}
llvm::Value* TGlslangToTopTraverser::handleUserFunctionCall(const
glslang::TIntermAggregate* node)
=======================================
--- /trunk/test/310.comp Thu May 21 01:11:19 2015 UTC
+++ /trunk/test/310.comp Mon May 25 23:01:59 2015 UTC
@@ -25,6 +25,20 @@
vec4 va[];
} outnames;
+
+uniform writeonly highp iimage2DArray ii2da;
+
+layout(r32i) uniform highp iimage2D iimg2D;
+layout(rgba32i) uniform readonly highp iimage2D iimg2Drgba;
+layout(rgba32f) uniform readonly highp image3D img3Drgba;
+layout(r32ui) uniform highp uimageCube uimgCube;
+layout(rgba8_snorm) readonly uniform highp image2DArray img2DA;
+layout(rgba8) writeonly uniform highp image2DArray wimg2DA;
+layout(rgba16f) writeonly uniform highp image2D wimg2D;
+
+shared ivec2 coord2D;
+shared ivec3 coord3D;
+
void main()
{
barrier();
@@ -34,4 +48,14 @@
//outbname.uns[17] = vec3(3.0); // TODO: see note above, this one
bitcasts, which isn't handled
outbname.uns[i] = vec3(s);
outnames.va[gl_LocalInvocationID.x] = vec4(s);
+
+ ivec4 iv = imageLoad(iimg2Drgba, coord2D);
+ vec4 v = imageLoad(img3Drgba, coord3D);
+ uvec4 uv = imageLoad(uimgCube, coord3D);
+ v += imageLoad(img2DA, coord3D);
+
+ imageStore(iimg2D, coord2D, iv);
+ imageStore(uimgCube, coord3D, uv);
+ imageStore(wimg2DA, coord3D, v);
+ imageStore(wimg2D, coord2D, v);
}
=======================================
--- /trunk/test/baseResults/310.comp.out Thu May 21 01:11:19 2015 UTC
+++ /trunk/test/baseResults/310.comp.out Mon May 25 23:01:59 2015 UTC
@@ -12,10 +12,23 @@
@i = global i32 0
@outnames = external addrspace(2) constant %outs
@gl_LocalInvocationID = global <3 x i32> zeroinitializer
+@iimg2Drgba = external addrspace(1) constant i32
+@coord2D = global <2 x i32> zeroinitializer
+@img3Drgba = external addrspace(1) constant i32
+@coord3D = global <3 x i32> zeroinitializer
+@uimgCube = external addrspace(1) constant i32
+@img2DA = external addrspace(1) constant i32
+@iimg2D = external addrspace(1) constant i32
+@wimg2DA = external addrspace(1) constant i32
+@wimg2D = external addrspace(1) constant i32
+@ii2da = external addrspace(1) constant i32
define fastcc void @main() {
entry:
%gl_WorkGroupSize = alloca <3 x i32>
+ %uv = alloca <4 x i32>
+ %v = alloca <4 x float>
+ %iv = alloca <4 x i32>
%outnames = alloca <4 x float>
%outbname = alloca <3 x float>
%outbnamena = alloca <4 x float>
@@ -27,32 +40,66 @@
store float %0, float addrspace(2)* getelementptr inbounds (%outb
addrspace(2)* @outbname, i32 0, i32 0)
%1 = load float* @s
%2 = load <4 x float>* %outbnamena
- %3 = insertelement <4 x float> undef, float %1, i32 0, !gla.precision !14
- %4 = insertelement <4 x float> %3, float %1, i32 1, !gla.precision !14
- %5 = insertelement <4 x float> %4, float %1, i32 2, !gla.precision !14
- %6 = insertelement <4 x float> %5, float %1, i32 3, !gla.precision !14
+ %3 = insertelement <4 x float> undef, float %1, i32 0, !gla.precision !40
+ %4 = insertelement <4 x float> %3, float %1, i32 1, !gla.precision !40
+ %5 = insertelement <4 x float> %4, float %1, i32 2, !gla.precision !40
+ %6 = insertelement <4 x float> %5, float %1, i32 3, !gla.precision !40
store <4 x float> %6, <4 x float> addrspace(2)* getelementptr inbounds
(%outbna addrspace(2)* @outbnamena, i32 0, i32 1)
%7 = load <3 x float> addrspace(2)* getelementptr (<3 x float>
addrspace(2)* getelementptr inbounds (%outb addrspace(2)* @outbname, i32 0,
i32 3), i32 18)
- %s = extractelement <3 x float> %7, i32 0, !gla.precision !14
+ %s = extractelement <3 x float> %7, i32 0, !gla.precision !40
store float %s, float* @s
%8 = load i32* @i
%9 = load float* @s
%10 = load <3 x float>* %outbname
- %11 = insertelement <3 x float> undef, float %9, i32
0, !gla.precision !14
- %12 = insertelement <3 x float> %11, float %9, i32 1, !gla.precision !14
- %13 = insertelement <3 x float> %12, float %9, i32 2, !gla.precision !14
+ %11 = insertelement <3 x float> undef, float %9, i32
0, !gla.precision !40
+ %12 = insertelement <3 x float> %11, float %9, i32 1, !gla.precision !40
+ %13 = insertelement <3 x float> %12, float %9, i32 2, !gla.precision !40
%14 = getelementptr <3 x float> addrspace(2)* getelementptr inbounds
(%outb addrspace(2)* @outbname, i32 0, i32 3), i32 %8
store <3 x float> %13, <3 x float> addrspace(2)* %14
%15 = load <3 x i32>* @gl_LocalInvocationID
- %16 = extractelement <3 x i32> %15, i32 0, !gla.precision !14
+ %16 = extractelement <3 x i32> %15, i32 0, !gla.precision !40
%17 = load float* @s
%18 = load <4 x float>* %outnames
- %19 = insertelement <4 x float> undef, float %17, i32
0, !gla.precision !14
- %20 = insertelement <4 x float> %19, float %17, i32 1, !gla.precision !14
- %21 = insertelement <4 x float> %20, float %17, i32 2, !gla.precision !14
- %22 = insertelement <4 x float> %21, float %17, i32 3, !gla.precision !14
+ %19 = insertelement <4 x float> undef, float %17, i32
0, !gla.precision !40
+ %20 = insertelement <4 x float> %19, float %17, i32 1, !gla.precision !40
+ %21 = insertelement <4 x float> %20, float %17, i32 2, !gla.precision !40
+ %22 = insertelement <4 x float> %21, float %17, i32 3, !gla.precision !40
%23 = getelementptr <4 x float> addrspace(2)* getelementptr inbounds
(%outs addrspace(2)* @outnames, i32 0, i32 0), i32 %16
store <4 x float> %22, <4 x float> addrspace(2)* %23
+ %24 = load i32 addrspace(1)* @iimg2Drgba, !gla.uniform !10
+ %25 = load <2 x i32>* @coord2D
+ %iv1 = call <4 x i32> @llvm.gla.imageLoad.v4i32.v2i32(i32 2, i32 %24,
i32 65536, <2 x i32> %25), !gla.precision !40
+ store <4 x i32> %iv1, <4 x i32>* %iv
+ %26 = load i32 addrspace(1)* @img3Drgba, !gla.uniform !13
+ %27 = load <3 x i32>* @coord3D
+ %v3 = call <4 x float> @llvm.gla.fImageLoad.v4f32.v3i32(i32 3, i32 %26,
i32 65536, <3 x i32> %27), !gla.precision !40
+ store <4 x float> %v3, <4 x float>* %v
+ %28 = load i32 addrspace(1)* @uimgCube, !gla.uniform !16
+ %29 = load <3 x i32>* @coord3D
+ %uv4 = call <4 x i32> @llvm.gla.imageLoad.v4i32.v3i32(i32 4, i32 %28,
i32 65536, <3 x i32> %29), !gla.precision !40
+ store <4 x i32> %uv4, <4 x i32>* %uv
+ %30 = load i32 addrspace(1)* @img2DA, !gla.uniform !19
+ %31 = load <3 x i32>* @coord3D
+ %v5 = call <4 x float> @llvm.gla.fImageLoad.v4f32.v3i32(i32 2, i32 %30,
i32 65552, <3 x i32> %31), !gla.precision !40
+ %32 = load <4 x float>* %v
+ %v6 = fadd <4 x float> %32, %v5, !gla.precision !40
+ store <4 x float> %v6, <4 x float>* %v
+ %33 = load i32 addrspace(1)* @iimg2D, !gla.uniform !22
+ %34 = load <2 x i32>* @coord2D
+ %35 = load <4 x i32>* %iv
+ call void @llvm.gla.imageStoreI.v2i32(i32 2, i32 %33, i32 131072, <2 x
i32> %34, <4 x i32> %35), !gla.precision !40
+ %36 = load i32 addrspace(1)* @uimgCube, !gla.uniform !16
+ %37 = load <3 x i32>* @coord3D
+ %38 = load <4 x i32>* %uv
+ call void @llvm.gla.imageStoreI.v3i32(i32 4, i32 %36, i32 131072, <3 x
i32> %37, <4 x i32> %38), !gla.precision !40
+ %39 = load i32 addrspace(1)* @wimg2DA, !gla.uniform !25
+ %40 = load <3 x i32>* @coord3D
+ %41 = load <4 x float>* %v
+ call void @llvm.gla.imageStoreF.v3i32(i32 2, i32 %39, i32 131088, <3 x
i32> %40, <4 x float> %41), !gla.precision !40
+ %42 = load i32 addrspace(1)* @wimg2D, !gla.uniform !28
+ %43 = load <2 x i32>* @coord2D
+ %44 = load <4 x float>* %v
+ call void @llvm.gla.imageStoreF.v2i32(i32 2, i32 %42, i32 131072, <2 x
i32> %43, <4 x float> %44), !gla.precision !40
br label %stage-epilogue
stage-epilogue: ; preds = %mainBody
@@ -65,12 +112,35 @@
; Function Attrs: nounwind
declare void @llvm.gla.barrier() #0
+; Function Attrs: nounwind readonly
+declare <4 x i32> @llvm.gla.imageLoad.v4i32.v2i32(i32, i32, i32, <2 x
i32>) #1
+
+; Function Attrs: nounwind readonly
+declare <4 x float> @llvm.gla.fImageLoad.v4f32.v3i32(i32, i32, i32, <3 x
i32>) #1
+
+; Function Attrs: nounwind readonly
+declare <4 x i32> @llvm.gla.imageLoad.v4i32.v3i32(i32, i32, i32, <3 x
i32>) #1
+
+; Function Attrs: nounwind
+declare void @llvm.gla.imageStoreI.v2i32(i32, i32, i32, <2 x i32>, <4 x
i32>) #0
+
+; Function Attrs: nounwind
+declare void @llvm.gla.imageStoreI.v3i32(i32, i32, i32, <3 x i32>, <4 x
i32>) #0
+
+; Function Attrs: nounwind
+declare void @llvm.gla.imageStoreF.v3i32(i32, i32, i32, <3 x i32>, <4 x
float>) #0
+
+; Function Attrs: nounwind
+declare void @llvm.gla.imageStoreF.v2i32(i32, i32, i32, <2 x i32>, <4 x
float>) #0
+
attributes #0 = { nounwind }
+attributes #1 = { nounwind readonly }
!gla.entrypoint = !{!0}
-!gla.uniforms = !{!1, !6, !8}
-!gla.shared = !{!10, !11}
-!gla.inputs = !{!12}
+!gla.uniforms = !{!1, !6, !8, !10, !13, !16, !19, !22, !25, !28, !31}
+!gla.shared = !{!34, !35, !36, !37}
+!gla.inputs = !{!38}
+!gla.noStaticUse = !{!31}
!0 = metadata !{metadata !"main", i32 15}
!1 = metadata !{metadata !"outbname", i32 18, %outb* @outbname_typeProxy,
metadata !2, metadata !3}
@@ -82,11 +152,37 @@
!7 = metadata !{metadata !"outbna", metadata !2, metadata !"k",
metadata !4, metadata !"na", metadata !4}
!8 = metadata !{metadata !"outnames", i32 18, %outs* @outnames_typeProxy,
metadata !2, metadata !9}
!9 = metadata !{metadata !"outs", metadata !2, metadata !"va", metadata !4}
-!10 = metadata !{float* @s}
-!11 = metadata !{i32* @i}
-!12 = metadata !{metadata !"gl_LocalInvocationID", i32 1, <3 x i32>*
@gl_LocalInvocationID_typeProxy, metadata !13}
-!13 = metadata !{i32 1, i32 3, i32 1024, null, i32 0, i32 4}
-!14 = metadata !{i32 3}
+!10 = metadata !{metadata !"iimg2Drgba", i32 12, i32*
@iimg2Drgba_typeProxy, metadata !11}
+!11 = metadata !{i32 5, i32 3, i32 1024, metadata !12}
+!12 = metadata !{i32 22, i32* @iimg2Drgba_typeProxy, i32 1, i1 false, i1
false, i32 1}
+!13 = metadata !{metadata !"img3Drgba", i32 12, i32* @img3Drgba_typeProxy,
metadata !14}
+!14 = metadata !{i32 5, i32 3, i32 1024, metadata !15}
+!15 = metadata !{i32 2, i32* @img3Drgba_typeProxy, i32 2, i1 false, i1
false, i32 0}
+!16 = metadata !{metadata !"uimgCube", i32 12, i32* @uimgCube_typeProxy,
metadata !17}
+!17 = metadata !{i32 5, i32 3, i32 1024, metadata !18}
+!18 = metadata !{i32 34, i32* @uimgCube_typeProxy, i32 3, i1 false, i1
false, i32 2}
+!19 = metadata !{metadata !"img2DA", i32 12, i32* @img2DA_typeProxy,
metadata !20}
+!20 = metadata !{i32 5, i32 3, i32 1024, metadata !21}
+!21 = metadata !{i32 6, i32* @img2DA_typeProxy, i32 1, i1 true, i1 false,
i32 0}
+!22 = metadata !{metadata !"iimg2D", i32 12, i32* @iimg2D_typeProxy,
metadata !23}
+!23 = metadata !{i32 5, i32 3, i32 1024, metadata !24}
+!24 = metadata !{i32 25, i32* @iimg2D_typeProxy, i32 1, i1 false, i1
false, i32 1}
+!25 = metadata !{metadata !"wimg2DA", i32 12, i32* @wimg2DA_typeProxy,
metadata !26}
+!26 = metadata !{i32 5, i32 3, i32 1024, metadata !27}
+!27 = metadata !{i32 5, i32* @wimg2DA_typeProxy, i32 1, i1 true, i1 false,
i32 0}
+!28 = metadata !{metadata !"wimg2D", i32 12, i32* @wimg2D_typeProxy,
metadata !29}
+!29 = metadata !{i32 5, i32 3, i32 1024, metadata !30}
+!30 = metadata !{i32 3, i32* @wimg2D_typeProxy, i32 1, i1 false, i1 false,
i32 0}
+!31 = metadata !{metadata !"ii2da", i32 12, i32* @ii2da_typeProxy,
metadata !32}
+!32 = metadata !{i32 5, i32 3, i32 1024, metadata !33}
+!33 = metadata !{i32 1, i32* @ii2da_typeProxy, i32 1, i1 true, i1 false,
i32 1}
+!34 = metadata !{float* @s}
+!35 = metadata !{i32* @i}
+!36 = metadata !{<2 x i32>* @coord2D}
+!37 = metadata !{<3 x i32>* @coord3D}
+!38 = metadata !{metadata !"gl_LocalInvocationID", i32 1, <3 x i32>*
@gl_LocalInvocationID_typeProxy, metadata !39}
+!39 = metadata !{i32 1, i32 3, i32 1024, null, i32 0, i32 4}
+!40 = metadata !{i32 3}
Bottom IR:
@@ -102,6 +198,15 @@
@i = global i32 0
@outnames = external addrspace(2) constant %outs
@gl_LocalInvocationID = global <3 x i32> zeroinitializer
+@iimg2Drgba = external addrspace(1) constant i32
+@coord2D = global <2 x i32> zeroinitializer
+@img3Drgba = external addrspace(1) constant i32
+@coord3D = global <3 x i32> zeroinitializer
+@uimgCube = external addrspace(1) constant i32
+@img2DA = external addrspace(1) constant i32
+@iimg2D = external addrspace(1) constant i32
+@wimg2DA = external addrspace(1) constant i32
+@wimg2D = external addrspace(1) constant i32
define fastcc void @main() {
entry:
@@ -110,22 +215,40 @@
%1 = call <4 x float> @llvm.gla.fSwizzle.v4f32.f32.v4i32(float %0, <4 x
i32> zeroinitializer)
%gla_constGEP = getelementptr %outb addrspace(2)* @outbname, i32 0, i32 0
store float %0, float addrspace(2)* %gla_constGEP, align 16
- %gla_constGEP1 = getelementptr %outbna addrspace(2)* @outbnamena, i32 0,
i32 1
- store <4 x float> %1, <4 x float> addrspace(2)* %gla_constGEP1, align 16
- %gla_constGEP2 = getelementptr %outb addrspace(2)* @outbname, i32 9, i32
3
- %2 = load <3 x float> addrspace(2)* %gla_constGEP2, align 16
+ %gla_constGEP7 = getelementptr %outbna addrspace(2)* @outbnamena, i32 0,
i32 1
+ store <4 x float> %1, <4 x float> addrspace(2)* %gla_constGEP7, align 16
+ %gla_constGEP8 = getelementptr %outb addrspace(2)* @outbname, i32 9, i32
3
+ %2 = load <3 x float> addrspace(2)* %gla_constGEP8, align 16
%3 = call <4 x float> @llvm.gla.fSwizzle.v4f32.v3f32.v4i32(<3 x
float> %2, <4 x i32> zeroinitializer)
%4 = call <3 x float> @llvm.gla.fSwizzle.v3f32.v3f32.v3i32(<3 x
float> %2, <3 x i32> zeroinitializer)
- %s = extractelement <3 x float> %2, i32 0, !gla.precision !14
+ %s = extractelement <3 x float> %2, i32 0, !gla.precision !40
store float %s, float* @s, align 4
%5 = load i32* @i, align 4
- %gla_constGEP3 = getelementptr %outb addrspace(2)* @outbname, i32 0, i32
3
- %6 = getelementptr <3 x float> addrspace(2)* %gla_constGEP3, i32 %5
+ %gla_constGEP9 = getelementptr %outb addrspace(2)* @outbname, i32 0, i32
3
+ %6 = getelementptr <3 x float> addrspace(2)* %gla_constGEP9, i32 %5
store <3 x float> %4, <3 x float> addrspace(2)* %6, align 16
%7 = load <3 x i32>* @gl_LocalInvocationID, align 16
- %8 = extractelement <3 x i32> %7, i32 0, !gla.precision !14
+ %8 = extractelement <3 x i32> %7, i32 0, !gla.precision !40
%9 = getelementptr inbounds %outs addrspace(2)* @outnames, i32 %8, i32 0
store <4 x float> %3, <4 x float> addrspace(2)* %9, align 16
+ %10 = load i32 addrspace(1)* @iimg2Drgba, align 4, !gla.uniform !10
+ %11 = load <2 x i32>* @coord2D, align 8
+ %iv1 = call <4 x i32> @llvm.gla.imageLoad.v4i32.v2i32(i32 2, i32 %10,
i32 65536, <2 x i32> %11), !gla.precision !40
+ %12 = load i32 addrspace(1)* @img3Drgba, align 4, !gla.uniform !13
+ %13 = load <3 x i32>* @coord3D, align 16
+ %v3 = call <4 x float> @llvm.gla.fImageLoad.v4f32.v3i32(i32 3, i32 %12,
i32 65536, <3 x i32> %13), !gla.precision !40
+ %14 = load i32 addrspace(1)* @uimgCube, align 4, !gla.uniform !16
+ %uv4 = call <4 x i32> @llvm.gla.imageLoad.v4i32.v3i32(i32 4, i32 %14,
i32 65536, <3 x i32> %13), !gla.precision !40
+ %15 = load i32 addrspace(1)* @img2DA, align 4, !gla.uniform !19
+ %v5 = call <4 x float> @llvm.gla.fImageLoad.v4f32.v3i32(i32 2, i32 %15,
i32 65552, <3 x i32> %13), !gla.precision !40
+ %v6 = fadd <4 x float> %v3, %v5, !gla.precision !40
+ %16 = load i32 addrspace(1)* @iimg2D, align 4, !gla.uniform !22
+ call void @llvm.gla.imageStoreI.v2i32(i32 2, i32 %16, i32 131072, <2 x
i32> %11, <4 x i32> %iv1), !gla.precision !40
+ call void @llvm.gla.imageStoreI.v3i32(i32 4, i32 %14, i32 131072, <3 x
i32> %13, <4 x i32> %uv4), !gla.precision !40
+ %17 = load i32 addrspace(1)* @wimg2DA, align 4, !gla.uniform !25
+ call void @llvm.gla.imageStoreF.v3i32(i32 2, i32 %17, i32 131088, <3 x
i32> %13, <4 x float> %v6), !gla.precision !40
+ %18 = load i32 addrspace(1)* @wimg2D, align 4, !gla.uniform !28
+ call void @llvm.gla.imageStoreF.v2i32(i32 2, i32 %18, i32 131072, <2 x
i32> %11, <4 x float> %v6), !gla.precision !40
br label %stage-epilogue
stage-epilogue: ; preds = %entry
@@ -138,22 +261,45 @@
; Function Attrs: nounwind
declare void @llvm.gla.barrier() #0
+; Function Attrs: nounwind readonly
+declare <4 x i32> @llvm.gla.imageLoad.v4i32.v2i32(i32, i32, i32, <2 x
i32>) #1
+
+; Function Attrs: nounwind readonly
+declare <4 x float> @llvm.gla.fImageLoad.v4f32.v3i32(i32, i32, i32, <3 x
i32>) #1
+
+; Function Attrs: nounwind readonly
+declare <4 x i32> @llvm.gla.imageLoad.v4i32.v3i32(i32, i32, i32, <3 x
i32>) #1
+
+; Function Attrs: nounwind
+declare void @llvm.gla.imageStoreI.v2i32(i32, i32, i32, <2 x i32>, <4 x
i32>) #0
+
+; Function Attrs: nounwind
+declare void @llvm.gla.imageStoreI.v3i32(i32, i32, i32, <3 x i32>, <4 x
i32>) #0
+
+; Function Attrs: nounwind
+declare void @llvm.gla.imageStoreF.v3i32(i32, i32, i32, <3 x i32>, <4 x
float>) #0
+
+; Function Attrs: nounwind
+declare void @llvm.gla.imageStoreF.v2i32(i32, i32, i32, <2 x i32>, <4 x
float>) #0
+
; Function Attrs: nounwind readnone
-declare <4 x float> @llvm.gla.fSwizzle.v4f32.f32.v4i32(float, <4 x i32>) #1
+declare <4 x float> @llvm.gla.fSwizzle.v4f32.f32.v4i32(float, <4 x i32>) #2
; Function Attrs: nounwind readnone
-declare <3 x float> @llvm.gla.fSwizzle.v3f32.v3f32.v3i32(<3 x float>, <3 x
i32>) #1
+declare <3 x float> @llvm.gla.fSwizzle.v3f32.v3f32.v3i32(<3 x float>, <3 x
i32>) #2
; Function Attrs: nounwind readnone
-declare <4 x float> @llvm.gla.fSwizzle.v4f32.v3f32.v4i32(<3 x float>, <4 x
i32>) #1
+declare <4 x float> @llvm.gla.fSwizzle.v4f32.v3f32.v4i32(<3 x float>, <4 x
i32>) #2
attributes #0 = { nounwind }
-attributes #1 = { nounwind readnone }
+attributes #1 = { nounwind readonly }
+attributes #2 = { nounwind readnone }
!gla.entrypoint = !{!0}
-!gla.uniforms = !{!1, !6, !8}
-!gla.shared = !{!10, !11}
-!gla.inputs = !{!12}
+!gla.uniforms = !{!1, !6, !8, !10, !13, !16, !19, !22, !25, !28, !31}
+!gla.shared = !{!34, !35, !36, !37}
+!gla.inputs = !{!38}
+!gla.noStaticUse = !{!31}
!0 = metadata !{metadata !"main", i32 15}
!1 = metadata !{metadata !"outbname", i32 18, %outb* @outbname_typeProxy,
metadata !2, metadata !3}
@@ -165,11 +311,37 @@
!7 = metadata !{metadata !"outbna", metadata !2, metadata !"k",
metadata !4, metadata !"na", metadata !4}
!8 = metadata !{metadata !"outnames", i32 18, %outs* @outnames_typeProxy,
metadata !2, metadata !9}
!9 = metadata !{metadata !"outs", metadata !2, metadata !"va", metadata !4}
-!10 = metadata !{float* @s}
-!11 = metadata !{i32* @i}
-!12 = metadata !{metadata !"gl_LocalInvocationID", i32 1, <3 x i32>*
@gl_LocalInvocationID_typeProxy, metadata !13}
-!13 = metadata !{i32 1, i32 3, i32 1024, null, i32 0, i32 4}
-!14 = metadata !{i32 3}
+!10 = metadata !{metadata !"iimg2Drgba", i32 12, i32*
@iimg2Drgba_typeProxy, metadata !11}
+!11 = metadata !{i32 5, i32 3, i32 1024, metadata !12}
+!12 = metadata !{i32 22, i32* @iimg2Drgba_typeProxy, i32 1, i1 false, i1
false, i32 1}
+!13 = metadata !{metadata !"img3Drgba", i32 12, i32* @img3Drgba_typeProxy,
metadata !14}
+!14 = metadata !{i32 5, i32 3, i32 1024, metadata !15}
+!15 = metadata !{i32 2, i32* @img3Drgba_typeProxy, i32 2, i1 false, i1
false, i32 0}
+!16 = metadata !{metadata !"uimgCube", i32 12, i32* @uimgCube_typeProxy,
metadata !17}
+!17 = metadata !{i32 5, i32 3, i32 1024, metadata !18}
+!18 = metadata !{i32 34, i32* @uimgCube_typeProxy, i32 3, i1 false, i1
false, i32 2}
+!19 = metadata !{metadata !"img2DA", i32 12, i32* @img2DA_typeProxy,
metadata !20}
+!20 = metadata !{i32 5, i32 3, i32 1024, metadata !21}
+!21 = metadata !{i32 6, i32* @img2DA_typeProxy, i32 1, i1 true, i1 false,
i32 0}
+!22 = metadata !{metadata !"iimg2D", i32 12, i32* @iimg2D_typeProxy,
metadata !23}
+!23 = metadata !{i32 5, i32 3, i32 1024, metadata !24}
+!24 = metadata !{i32 25, i32* @iimg2D_typeProxy, i32 1, i1 false, i1
false, i32 1}
+!25 = metadata !{metadata !"wimg2DA", i32 12, i32* @wimg2DA_typeProxy,
metadata !26}
+!26 = metadata !{i32 5, i32 3, i32 1024, metadata !27}
+!27 = metadata !{i32 5, i32* @wimg2DA_typeProxy, i32 1, i1 true, i1 false,
i32 0}
+!28 = metadata !{metadata !"wimg2D", i32 12, i32* @wimg2D_typeProxy,
metadata !29}
+!29 = metadata !{i32 5, i32 3, i32 1024, metadata !30}
+!30 = metadata !{i32 3, i32* @wimg2D_typeProxy, i32 1, i1 false, i1 false,
i32 0}
+!31 = metadata !{metadata !"ii2da", i32 12, i32* @ii2da_typeProxy,
metadata !32}
+!32 = metadata !{i32 5, i32 3, i32 1024, metadata !33}
+!33 = metadata !{i32 1, i32* @ii2da_typeProxy, i32 1, i1 true, i1 false,
i32 1}
+!34 = metadata !{float* @s}
+!35 = metadata !{i32* @i}
+!36 = metadata !{<2 x i32>* @coord2D}
+!37 = metadata !{<3 x i32>* @coord3D}
+!38 = metadata !{metadata !"gl_LocalInvocationID", i32 1, <3 x i32>*
@gl_LocalInvocationID_typeProxy, metadata !39}
+!39 = metadata !{i32 1, i32 3, i32 1024, null, i32 0, i32 4}
+!40 = metadata !{i32 3}
#version 310 es
// LunarGOO output
buffer outb {
@@ -185,8 +357,18 @@
buffer outs {
highp vec4 va[];
} outnames;
+uniform layout(rgba32i) highp iimage2D iimg2Drgba;
+uniform layout(rgba32f) highp image3D img3Drgba;
+uniform layout(r32ui) highp uimageCube uimgCube;
+uniform layout(rgba8_snorm) highp image2DArray img2DA;
+uniform layout(r32i) highp iimage2D iimg2D;
+uniform layout(rgba8) highp image2DArray wimg2DA;
+uniform layout(rgba16f) highp image2D wimg2D;
+uniform highp iimage2DArray ii2da;
shared float s;
shared int i;
+shared ivec2 coord2D;
+shared ivec3 coord3D;
void main()
{
@@ -197,28 +379,44 @@
s = outbname[9].uns.x;
outbname.uns[i] = outbname[9].uns.xxx;
outnames[ivec3(gl_LocalInvocationID).x].va = outbname[9].uns.xxxx;
+ highp ivec4 iv = imageLoad(iimg2Drgba, coord2D);
+ highp vec4 H_d28na9 = imageLoad(img3Drgba, coord3D);
+ highp ivec4 uv = ivec4(imageLoad(uimgCube, coord3D));
+ highp vec4 H_vp6gnj = imageLoad(img2DA, coord3D);
+ highp vec4 H_hlq1hy1 = H_d28na9 + H_vp6gnj;
+ imageStore(iimg2D, coord2D, iv);
+ imageStore(uimgCube, coord3D, uv);
+ imageStore(wimg2DA, coord3D, H_hlq1hy1);
+ imageStore(wimg2D, coord2D, H_hlq1hy1);
}
tempglsl.comp
Warning, version 310 is not yet complete; most version-specific features
are present, but some are missing.
-ERROR: 0:25: 'outbname' : left of '[' is not of type array, matrix, or
vector
-ERROR: 0:25: 'scalar swizzle' : not supported with this profile: es
-ERROR: 0:25: 'uns' : illegal vector field selection
-ERROR: 0:25: 'scalar swizzle' : not supported with this profile: es
-ERROR: 0:26: 'outbname' : left of '[' is not of type array, matrix, or
vector
-ERROR: 0:26: 'scalar swizzle' : not supported with this profile: es
-ERROR: 0:26: 'uns' : illegal vector field selection
-ERROR: 0:26: 'scalar swizzle' : not supported with this profile: es
-ERROR: 0:27: 'outnames' : left of '[' is not of type array, matrix, or
vector
-ERROR: 0:27: 'scalar swizzle' : not supported with this profile: es
-ERROR: 0:27: 'va' : illegal vector field selection
-ERROR: 0:27: 'outbname' : left of '[' is not of type array, matrix, or
vector
-ERROR: 0:27: 'scalar swizzle' : not supported with this profile: es
-ERROR: 0:27: 'uns' : illegal vector field selection
-ERROR: 0:27: 'scalar swizzle' : not supported with this profile: es
-ERROR: 0:27: 'assign' : l-value required (can't modify a const)
-ERROR: 0:27: 'assign' : cannot convert from 'temp 4-component vector of
float' to 'const float'
-ERROR: 17 compilation errors. No code generated.
+ERROR: 0:16: 'rgba32i' : format requires readonly or writeonly memory
qualifier
+ERROR: 0:17: 'rgba32f' : format requires readonly or writeonly memory
qualifier
+ERROR: 0:19: 'rgba8_snorm' : format requires readonly or writeonly memory
qualifier
+ERROR: 0:21: 'rgba8' : format requires readonly or writeonly memory
qualifier
+ERROR: 0:22: 'rgba16f' : format requires readonly or writeonly memory
qualifier
+ERROR: 0:23: '' : image variables not declared 'writeonly' must have a
format layout qualifier
+ERROR: 0:35: 'outbname' : left of '[' is not of type array, matrix, or
vector
+ERROR: 0:35: 'scalar swizzle' : not supported with this profile: es
+ERROR: 0:35: 'uns' : illegal vector field selection
+ERROR: 0:35: 'scalar swizzle' : not supported with this profile: es
+ERROR: 0:36: 'outbname' : left of '[' is not of type array, matrix, or
vector
+ERROR: 0:36: 'scalar swizzle' : not supported with this profile: es
+ERROR: 0:36: 'uns' : illegal vector field selection
+ERROR: 0:36: 'scalar swizzle' : not supported with this profile: es
+ERROR: 0:37: 'outnames' : left of '[' is not of type array, matrix, or
vector
+ERROR: 0:37: 'scalar swizzle' : not supported with this profile: es
+ERROR: 0:37: 'va' : illegal vector field selection
+ERROR: 0:37: 'outbname' : left of '[' is not of type array, matrix, or
vector
+ERROR: 0:37: 'scalar swizzle' : not supported with this profile: es
+ERROR: 0:37: 'uns' : illegal vector field selection
+ERROR: 0:37: 'scalar swizzle' : not supported with this profile: es
+ERROR: 0:37: 'assign' : l-value required (can't modify a const)
+ERROR: 0:37: 'assign' : cannot convert from 'temp 4-component vector of
float' to 'const float'
+ERROR: 0:44: 'imageStore' : no matching overloaded function found
+ERROR: 24 compilation errors. No code generated.