Commit 0461d8d4 by Shahbaz Youssefi Committed by Angle LUCI CQ

Vulkan: SPIR-V Gen: texture and image built-ins

GLSL contains a large number of built-in texture* and image* functions, but these map to only a handful of SPIR-V instructions. The bulk of the work to map these is to extract the arguments from the built-ins based on their ordinal position. Bug: angleproject:4889 Change-Id: I760d986bd9171ddde35f9f046c549ca53252df17 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2992980Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent d665593b
{
"src/common/spirv/gen_spirv_builder_and_parser.py":
"e8d99c4791b23c8613a3a6830904bd19",
"ee5f0698336e5e021b38d3af06cc56f0",
"src/common/spirv/spirv_instruction_builder_autogen.cpp":
"450a8ccffc5a5586dbbfd0c8c8c3673d",
"bf5cc47686e9dbd00b6229e4ee38a283",
"src/common/spirv/spirv_instruction_builder_autogen.h":
"c46c849dbea811cc8d16c51de1883deb",
"2a1f5f5f2067858ca7df00b89895a111",
"src/common/spirv/spirv_instruction_parser_autogen.cpp":
"ec8ace46aa3fb858eb01cfede3c1e6df",
"388f17f462daa8e091238b4d1fd42ef5",
"src/common/spirv/spirv_instruction_parser_autogen.h":
"66b41c497bef1ea01b906c3f4875b6ff",
"58282734b793c994dbe52c3aa988e40e",
"third_party/vulkan-deps/spirv-headers/src/include/spirv/1.0/spirv.core.grammar.json":
"a8c4239344b2fc10bfc4ace7ddee1867"
}
\ No newline at end of file
......@@ -4,15 +4,15 @@
"src/compiler/translator/ImmutableString_autogen.cpp":
"e4496ab13c424a15bb77b80e61b0accf",
"src/compiler/translator/Operator_autogen.h":
"1c32b1e3ad62d6f0b44a591f4d532472",
"340c7966d65f4f46858cc228e103cd86",
"src/compiler/translator/SymbolTable_ESSL_autogen.cpp":
"d61ce1e67574d03128e4abf375084df0",
"e4b9dcbb8c5291fcd577693037c8e036",
"src/compiler/translator/SymbolTable_autogen.cpp":
"6c05e64b546c4daf06532252be416264",
"de6cd4d4e80a689af91e8da4c2045b3c",
"src/compiler/translator/SymbolTable_autogen.h":
"d43593050c4d1b31b0be9cdd3a2d0ea5",
"src/compiler/translator/builtin_function_declarations.txt":
"236adf21399deafd706d93dad20e94c3",
"e1067f6d0c321cd49343df4f010e0b2b",
"src/compiler/translator/builtin_variables.json":
"0663a24c595b9221f44e3776337dec56",
"src/compiler/translator/gen_builtin_symbols.py":
......
......@@ -179,7 +179,7 @@ class Writer:
# If an instruction has a parameter of these types, the instruction is ignored
self.unsupported_kinds = set(['LiteralSpecConstantOpInteger'])
# If an instruction requires a capability of these kinds, the instruction is ignored
self.unsupported_capabilities = set(['Kernel'])
self.unsupported_capabilities = set(['Kernel', 'Addresses'])
# If an instruction requires an extension other than these, the instruction is ignored
self.supported_extensions = set([])
# List of bit masks. These have 'Mask' added to their typename in SPIR-V headers.
......@@ -245,7 +245,9 @@ class Writer:
def requires_unsupported_capability(self, item):
depends = item.get('capabilities', [])
return any([dep in self.unsupported_capabilities for dep in depends])
if len(depends) == 0:
return False
return all([dep in self.unsupported_capabilities for dep in depends])
def requires_unsupported_extension(self, item):
extensions = item.get('extensions', [])
......
......@@ -408,14 +408,6 @@ void WriteTypeFunction(Blob *blob,
}
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeFunction);
}
void WriteTypeForwardPointer(Blob *blob, IdRef pointerType, spv::StorageClass storageClass)
{
const size_t startSize = blob->size();
blob->push_back(0);
blob->push_back(pointerType);
blob->push_back(storageClass);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpTypeForwardPointer);
}
void WriteConstantTrue(Blob *blob, IdResultType idResultType, IdResult idResult)
{
const size_t startSize = blob->size();
......@@ -633,23 +625,6 @@ void WriteCopyMemory(Blob *blob,
}
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpCopyMemory);
}
void WriteCopyMemorySized(Blob *blob,
IdRef target,
IdRef source,
IdRef size,
const spv::MemoryAccessMask *memoryAccess)
{
const size_t startSize = blob->size();
blob->push_back(0);
blob->push_back(target);
blob->push_back(source);
blob->push_back(size);
if (memoryAccess)
{
blob->push_back(*memoryAccess);
}
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpCopyMemorySized);
}
void WriteAccessChain(Blob *blob,
IdResultType idResultType,
IdResult idResult,
......@@ -698,25 +673,6 @@ void WriteArrayLength(Blob *blob,
blob->push_back(arraymember);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpArrayLength);
}
void WriteInBoundsPtrAccessChain(Blob *blob,
IdResultType idResultType,
IdResult idResult,
IdRef base,
IdRef element,
const IdRefList &indexesList)
{
const size_t startSize = blob->size();
blob->push_back(0);
blob->push_back(idResultType);
blob->push_back(idResult);
blob->push_back(base);
blob->push_back(element);
for (const auto &operand : indexesList)
{
blob->push_back(operand);
}
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpInBoundsPtrAccessChain);
}
void WriteDecorate(Blob *blob,
IdRef target,
spv::Decoration decoration,
......@@ -1234,6 +1190,29 @@ void WriteImage(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef
blob->push_back(sampledImage);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImage);
}
void WriteImageQuerySizeLod(Blob *blob,
IdResultType idResultType,
IdResult idResult,
IdRef image,
IdRef levelofDetail)
{
const size_t startSize = blob->size();
blob->push_back(0);
blob->push_back(idResultType);
blob->push_back(idResult);
blob->push_back(image);
blob->push_back(levelofDetail);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageQuerySizeLod);
}
void WriteImageQuerySize(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef image)
{
const size_t startSize = blob->size();
blob->push_back(0);
blob->push_back(idResultType);
blob->push_back(idResult);
blob->push_back(image);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageQuerySize);
}
void WriteImageQueryLod(Blob *blob,
IdResultType idResultType,
IdResult idResult,
......@@ -1248,6 +1227,24 @@ void WriteImageQueryLod(Blob *blob,
blob->push_back(coordinate);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageQueryLod);
}
void WriteImageQueryLevels(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef image)
{
const size_t startSize = blob->size();
blob->push_back(0);
blob->push_back(idResultType);
blob->push_back(idResult);
blob->push_back(image);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageQueryLevels);
}
void WriteImageQuerySamples(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef image)
{
const size_t startSize = blob->size();
blob->push_back(0);
blob->push_back(idResultType);
blob->push_back(idResult);
blob->push_back(image);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpImageQuerySamples);
}
void WriteConvertFToU(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef floatValue)
{
const size_t startSize = blob->size();
......@@ -1320,27 +1317,6 @@ void WriteQuantizeToF16(Blob *blob, IdResultType idResultType, IdResult idResult
blob->push_back(value);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpQuantizeToF16);
}
void WriteConvertPtrToU(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef pointer)
{
const size_t startSize = blob->size();
blob->push_back(0);
blob->push_back(idResultType);
blob->push_back(idResult);
blob->push_back(pointer);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConvertPtrToU);
}
void WriteConvertUToPtr(Blob *blob,
IdResultType idResultType,
IdResult idResult,
IdRef integerValue)
{
const size_t startSize = blob->size();
blob->push_back(0);
blob->push_back(idResultType);
blob->push_back(idResult);
blob->push_back(integerValue);
(*blob)[startSize] = MakeLengthOp(blob->size() - startSize, spv::OpConvertUToPtr);
}
void WriteBitcast(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef operand)
{
const size_t startSize = blob->size();
......
......@@ -84,7 +84,6 @@ void WriteTypeFunction(Blob *blob,
IdResult idResult,
IdRef returnType,
const IdRefList &parameterList);
void WriteTypeForwardPointer(Blob *blob, IdRef pointerType, spv::StorageClass storageClass);
void WriteConstantTrue(Blob *blob, IdResultType idResultType, IdResult idResult);
void WriteConstantFalse(Blob *blob, IdResultType idResultType, IdResult idResult);
void WriteConstant(Blob *blob,
......@@ -139,11 +138,6 @@ void WriteCopyMemory(Blob *blob,
IdRef target,
IdRef source,
const spv::MemoryAccessMask *memoryAccess);
void WriteCopyMemorySized(Blob *blob,
IdRef target,
IdRef source,
IdRef size,
const spv::MemoryAccessMask *memoryAccess);
void WriteAccessChain(Blob *blob,
IdResultType idResultType,
IdResult idResult,
......@@ -159,12 +153,6 @@ void WriteArrayLength(Blob *blob,
IdResult idResult,
IdRef structure,
LiteralInteger arraymember);
void WriteInBoundsPtrAccessChain(Blob *blob,
IdResultType idResultType,
IdResult idResult,
IdRef base,
IdRef element,
const IdRefList &indexesList);
void WriteDecorate(Blob *blob,
IdRef target,
spv::Decoration decoration,
......@@ -315,11 +303,19 @@ void WriteImageWrite(Blob *blob,
const spv::ImageOperandsMask *imageOperands,
const IdRefList &imageOperandIdsList);
void WriteImage(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef sampledImage);
void WriteImageQuerySizeLod(Blob *blob,
IdResultType idResultType,
IdResult idResult,
IdRef image,
IdRef levelofDetail);
void WriteImageQuerySize(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef image);
void WriteImageQueryLod(Blob *blob,
IdResultType idResultType,
IdResult idResult,
IdRef sampledImage,
IdRef coordinate);
void WriteImageQueryLevels(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef image);
void WriteImageQuerySamples(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef image);
void WriteConvertFToU(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef floatValue);
void WriteConvertFToS(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef floatValue);
void WriteConvertSToF(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef signedValue);
......@@ -331,11 +327,6 @@ void WriteUConvert(Blob *blob, IdResultType idResultType, IdResult idResult, IdR
void WriteSConvert(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef signedValue);
void WriteFConvert(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef floatValue);
void WriteQuantizeToF16(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef value);
void WriteConvertPtrToU(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef pointer);
void WriteConvertUToPtr(Blob *blob,
IdResultType idResultType,
IdResult idResult,
IdRef integerValue);
void WriteBitcast(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef operand);
void WriteSNegate(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef operand);
void WriteFNegate(Blob *blob, IdResultType idResultType, IdResult idResult, IdRef operand);
......
......@@ -439,18 +439,6 @@ void ParseTypeFunction(const uint32_t *_instruction,
}
}
}
void ParseTypeForwardPointer(const uint32_t *_instruction,
IdRef *pointerType,
spv::StorageClass *storageClass)
{
spv::Op _op;
uint32_t _length;
GetInstructionOpAndLength(_instruction, &_op, &_length);
ASSERT(_op == spv::OpTypeForwardPointer);
uint32_t _o = 1;
*pointerType = IdRef(_instruction[_o++]);
*storageClass = spv::StorageClass(_instruction[_o++]);
}
void ParseConstantTrue(const uint32_t *_instruction, IdResultType *idResultType, IdResult *idResult)
{
spv::Op _op;
......@@ -715,25 +703,6 @@ void ParseCopyMemory(const uint32_t *_instruction,
*memoryAccess = spv::MemoryAccessMask(_instruction[_o++]);
}
}
void ParseCopyMemorySized(const uint32_t *_instruction,
IdRef *target,
IdRef *source,
IdRef *size,
spv::MemoryAccessMask *memoryAccess)
{
spv::Op _op;
uint32_t _length;
GetInstructionOpAndLength(_instruction, &_op, &_length);
ASSERT(_op == spv::OpCopyMemorySized);
uint32_t _o = 1;
*target = IdRef(_instruction[_o++]);
*source = IdRef(_instruction[_o++]);
*size = IdRef(_instruction[_o++]);
if (memoryAccess && _o < _length)
{
*memoryAccess = spv::MemoryAccessMask(_instruction[_o++]);
}
}
void ParseAccessChain(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
......@@ -794,30 +763,6 @@ void ParseArrayLength(const uint32_t *_instruction,
*structure = IdRef(_instruction[_o++]);
*arraymember = LiteralInteger(_instruction[_o++]);
}
void ParseInBoundsPtrAccessChain(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *base,
IdRef *element,
IdRefList *indexesList)
{
spv::Op _op;
uint32_t _length;
GetInstructionOpAndLength(_instruction, &_op, &_length);
ASSERT(_op == spv::OpInBoundsPtrAccessChain);
uint32_t _o = 1;
*idResultType = IdResultType(_instruction[_o++]);
*idResult = IdResult(_instruction[_o++]);
*base = IdRef(_instruction[_o++]);
*element = IdRef(_instruction[_o++]);
if (indexesList)
{
while (_o < _length)
{
indexesList->emplace_back(_instruction[_o++]);
}
}
}
void ParseDecorate(const uint32_t *_instruction,
IdRef *target,
spv::Decoration *decoration,
......@@ -1464,6 +1409,36 @@ void ParseImage(const uint32_t *_instruction,
*idResult = IdResult(_instruction[_o++]);
*sampledImage = IdRef(_instruction[_o++]);
}
void ParseImageQuerySizeLod(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *image,
IdRef *levelofDetail)
{
spv::Op _op;
uint32_t _length;
GetInstructionOpAndLength(_instruction, &_op, &_length);
ASSERT(_op == spv::OpImageQuerySizeLod);
uint32_t _o = 1;
*idResultType = IdResultType(_instruction[_o++]);
*idResult = IdResult(_instruction[_o++]);
*image = IdRef(_instruction[_o++]);
*levelofDetail = IdRef(_instruction[_o++]);
}
void ParseImageQuerySize(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *image)
{
spv::Op _op;
uint32_t _length;
GetInstructionOpAndLength(_instruction, &_op, &_length);
ASSERT(_op == spv::OpImageQuerySize);
uint32_t _o = 1;
*idResultType = IdResultType(_instruction[_o++]);
*idResult = IdResult(_instruction[_o++]);
*image = IdRef(_instruction[_o++]);
}
void ParseImageQueryLod(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
......@@ -1480,6 +1455,34 @@ void ParseImageQueryLod(const uint32_t *_instruction,
*sampledImage = IdRef(_instruction[_o++]);
*coordinate = IdRef(_instruction[_o++]);
}
void ParseImageQueryLevels(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *image)
{
spv::Op _op;
uint32_t _length;
GetInstructionOpAndLength(_instruction, &_op, &_length);
ASSERT(_op == spv::OpImageQueryLevels);
uint32_t _o = 1;
*idResultType = IdResultType(_instruction[_o++]);
*idResult = IdResult(_instruction[_o++]);
*image = IdRef(_instruction[_o++]);
}
void ParseImageQuerySamples(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *image)
{
spv::Op _op;
uint32_t _length;
GetInstructionOpAndLength(_instruction, &_op, &_length);
ASSERT(_op == spv::OpImageQuerySamples);
uint32_t _o = 1;
*idResultType = IdResultType(_instruction[_o++]);
*idResult = IdResult(_instruction[_o++]);
*image = IdRef(_instruction[_o++]);
}
void ParseConvertFToU(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
......@@ -1592,34 +1595,6 @@ void ParseQuantizeToF16(const uint32_t *_instruction,
*idResult = IdResult(_instruction[_o++]);
*value = IdRef(_instruction[_o++]);
}
void ParseConvertPtrToU(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *pointer)
{
spv::Op _op;
uint32_t _length;
GetInstructionOpAndLength(_instruction, &_op, &_length);
ASSERT(_op == spv::OpConvertPtrToU);
uint32_t _o = 1;
*idResultType = IdResultType(_instruction[_o++]);
*idResult = IdResult(_instruction[_o++]);
*pointer = IdRef(_instruction[_o++]);
}
void ParseConvertUToPtr(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *integerValue)
{
spv::Op _op;
uint32_t _length;
GetInstructionOpAndLength(_instruction, &_op, &_length);
ASSERT(_op == spv::OpConvertUToPtr);
uint32_t _o = 1;
*idResultType = IdResultType(_instruction[_o++]);
*idResult = IdResult(_instruction[_o++]);
*integerValue = IdRef(_instruction[_o++]);
}
void ParseBitcast(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
......
......@@ -100,9 +100,6 @@ void ParseTypeFunction(const uint32_t *_instruction,
IdResult *idResult,
IdRef *returnType,
IdRefList *parameterList);
void ParseTypeForwardPointer(const uint32_t *_instruction,
IdRef *pointerType,
spv::StorageClass *storageClass);
void ParseConstantTrue(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult);
......@@ -171,11 +168,6 @@ void ParseCopyMemory(const uint32_t *_instruction,
IdRef *target,
IdRef *source,
spv::MemoryAccessMask *memoryAccess);
void ParseCopyMemorySized(const uint32_t *_instruction,
IdRef *target,
IdRef *source,
IdRef *size,
spv::MemoryAccessMask *memoryAccess);
void ParseAccessChain(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
......@@ -191,12 +183,6 @@ void ParseArrayLength(const uint32_t *_instruction,
IdResult *idResult,
IdRef *structure,
LiteralInteger *arraymember);
void ParseInBoundsPtrAccessChain(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *base,
IdRef *element,
IdRefList *indexesList);
void ParseDecorate(const uint32_t *_instruction,
IdRef *target,
spv::Decoration *decoration,
......@@ -358,11 +344,28 @@ void ParseImage(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *sampledImage);
void ParseImageQuerySizeLod(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *image,
IdRef *levelofDetail);
void ParseImageQuerySize(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *image);
void ParseImageQueryLod(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *sampledImage,
IdRef *coordinate);
void ParseImageQueryLevels(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *image);
void ParseImageQuerySamples(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *image);
void ParseConvertFToU(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
......@@ -395,14 +398,6 @@ void ParseQuantizeToF16(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *value);
void ParseConvertPtrToU(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *pointer);
void ParseConvertUToPtr(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
IdRef *integerValue);
void ParseBitcast(const uint32_t *_instruction,
IdResultType *idResultType,
IdResult *idResult,
......
......@@ -348,6 +348,11 @@ inline bool IsSampler2DMSArray(TBasicType type)
}
}
inline bool IsSamplerMS(TBasicType type)
{
return IsSampler2DMS(type) || IsSampler2DMSArray(type);
}
inline bool IsFloatImage(TBasicType type)
{
switch (type)
......@@ -645,6 +650,62 @@ inline bool IsSamplerArray(TBasicType type)
return false;
}
inline bool IsSampler1D(TBasicType type)
{
switch (type)
{
case EbtSampler1D:
case EbtISampler1D:
case EbtUSampler1D:
case EbtSampler1DShadow:
return true;
case EbtSampler2D:
case EbtSamplerCube:
case EbtSampler3D:
case EbtISampler3D:
case EbtUSampler3D:
case EbtSamplerExternalOES:
case EbtSamplerExternal2DY2YEXT:
case EbtSampler2DRect:
case EbtSampler2DArray:
case EbtSampler2DMS:
case EbtSampler2DMSArray:
case EbtISampler2D:
case EbtISamplerCube:
case EbtISampler2DArray:
case EbtISampler2DMS:
case EbtISampler2DMSArray:
case EbtUSampler2D:
case EbtUSamplerCube:
case EbtUSampler2DArray:
case EbtUSampler2DMS:
case EbtUSampler2DMSArray:
case EbtSampler2DShadow:
case EbtSamplerCubeShadow:
case EbtSampler2DArrayShadow:
case EbtSampler1DArray:
case EbtSampler1DArrayShadow:
case EbtSamplerBuffer:
case EbtSamplerCubeArray:
case EbtSamplerCubeArrayShadow:
case EbtSampler2DRectShadow:
case EbtISampler1DArray:
case EbtISampler2DRect:
case EbtISamplerBuffer:
case EbtISamplerCubeArray:
case EbtUSampler1DArray:
case EbtUSampler2DRect:
case EbtUSamplerBuffer:
case EbtUSamplerCubeArray:
case EbtSamplerVideoWEBGL:
return false;
default:
ASSERT(!IsSampler(type));
}
return false;
}
inline bool IsShadowSampler(TBasicType type)
{
switch (type)
......
......@@ -60,8 +60,8 @@ struct SpirvType
TLayoutImageInternalFormat imageInternalFormat = EiifUnspecified;
// For sampled images (i.e. GLSL samplers), there are two type ids; one is the OpTypeImage that
// declares the image itself, and one OpTypeSampledImage. `imageOnly` distinguishes between
// these two types. Note that for the former, the basic type is still Ebt*Sampler* to
// declares the image itself, and one OpTypeSampledImage. `isSamplerBaseImage` distinguishes
// between these two types. Note that for the former, the basic type is still Ebt*Sampler* to
// distinguish it from storage images (which have a basic type of Ebt*Image*).
bool isSamplerBaseImage = false;
};
......
......@@ -297,12 +297,6 @@ enum TOperator : uint16_t
EOpTexture2DLodVS,
EOpTexture2DProjLodVS,
EOpTextureCubeLodVS,
EOpTexture1DLodVS,
EOpTexture1DProjLodVS,
EOpShadow1DLodVS,
EOpShadow1DProjLodVS,
EOpShadow2DLodVS,
EOpShadow2DProjLodVS,
// Group TextureFirstVersionsLodFS
EOpTexture2DLodEXTFS,
......
......@@ -240,12 +240,11 @@ class OutputSPIRVTraverser : public TIntermTraverser
spirv::IdRef visitOperator(TIntermOperator *node, spirv::IdRef resultTypeId);
spirv::IdRef createIncrementDecrement(TIntermOperator *node, spirv::IdRef resultTypeId);
spirv::IdRef createAtomicBuiltIn(TIntermOperator *node, spirv::IdRef resultTypeId);
spirv::IdRef createTextureBuiltIn(TIntermOperator *node, spirv::IdRef resultTypeId);
spirv::IdRef createImageBuiltIn(TIntermOperator *node, spirv::IdRef resultTypeId);
spirv::IdRef createImageTextureBuiltIn(TIntermOperator *node, spirv::IdRef resultTypeId);
spirv::IdRef createFunctionCall(TIntermAggregate *node, spirv::IdRef resultTypeId);
ANGLE_MAYBE_UNUSED TCompiler *mCompiler;
TCompiler *mCompiler;
ShCompileOptions mCompileOptions;
SPIRVBuilder mBuilder;
......@@ -1693,13 +1692,9 @@ spirv::IdRef OutputSPIRVTraverser::visitOperator(TIntermOperator *node, spirv::I
{
return createAtomicBuiltIn(node, resultTypeId);
}
if (BuiltInGroup::IsTexture(op))
if (BuiltInGroup::IsImage(op) || BuiltInGroup::IsTexture(op))
{
return createTextureBuiltIn(node, resultTypeId);
}
if (BuiltInGroup::IsImage(op))
{
return createImageBuiltIn(node, resultTypeId);
return createImageTextureBuiltIn(node, resultTypeId);
}
const size_t childCount = node->getChildCount();
......@@ -2588,20 +2583,776 @@ spirv::IdRef OutputSPIRVTraverser::createAtomicBuiltIn(TIntermOperator *node,
return result;
}
spirv::IdRef OutputSPIRVTraverser::createTextureBuiltIn(TIntermOperator *node,
spirv::IdRef resultTypeId)
spirv::IdRef OutputSPIRVTraverser::createImageTextureBuiltIn(TIntermOperator *node,
spirv::IdRef resultTypeId)
{
// TODO: http://anglebug.com/4889
UNIMPLEMENTED();
return spirv::IdRef{};
}
const TOperator op = node->getOp();
const TFunction *function = node->getAsAggregate()->getFunction();
const TType &samplerType = function->getParam(0)->getType();
const TBasicType samplerBasicType = samplerType.getBasicType();
spirv::IdRef OutputSPIRVTraverser::createImageBuiltIn(TIntermOperator *node,
spirv::IdRef resultTypeId)
{
// TODO: http://anglebug.com/4889
UNIMPLEMENTED();
return spirv::IdRef{};
// Load the parameters.
spirv::IdRefList parameters = loadAllParams(node);
// GLSL texture* and image* built-ins map to the following SPIR-V instructions. Some of these
// instructions take a "sampled image" while the others take the image itself. In these
// functions, the image, coordinates and Dref (for shadow sampling) are specified as positional
// parameters while the rest are bundled in a list of image operands.
//
// Image operations that query:
//
// - OpImageQuerySizeLod
// - OpImageQuerySize
// - OpImageQueryLod <-- sampled image
// - OpImageQueryLevels
// - OpImageQuerySamples
//
// Image operations that read/write:
//
// - OpImageSampleImplicitLod <-- sampled image
// - OpImageSampleExplicitLod <-- sampled image
// - OpImageSampleDrefImplicitLod <-- sampled image
// - OpImageSampleDrefExplicitLod <-- sampled image
// - OpImageSampleProjImplicitLod <-- sampled image
// - OpImageSampleProjExplicitLod <-- sampled image
// - OpImageSampleProjDrefImplicitLod <-- sampled image
// - OpImageSampleProjDrefExplicitLod <-- sampled image
// - OpImageFetch
// - OpImageGather <-- sampled image
// - OpImageDrefGather <-- sampled image
// - OpImageRead
// - OpImageWrite
//
// The additional image parameters are:
//
// - Bias: Only used with ImplicitLod.
// - Lod: Only used with ExplicitLod.
// - Grad: 2x operands; dx and dy. Only used with ExplicitLod.
// - ConstOffset: Constant offset added to coordinates of OpImage*Gather.
// - Offset: Non-constant offset added to coordinates of OpImage*Gather.
// - ConstOffsets: Constant offsets added to coordinates of OpImage*Gather.
// - Sample: Only used with OpImageFetch, OpImageRead and OpImageWrite.
//
// Where GLSL's built-in takes a sampler but SPIR-V expects an image, OpImage can be used to get
// the SPIR-V image out of a SPIR-V sampled image.
// The first parameter, which is either a sampled image or an image. Some GLSL built-ins
// receive a sampled image but their SPIR-V equivalent expects an image. OpImage is used in
// that case.
spirv::IdRef image = parameters[0];
bool extractImageFromSampledImage = false;
// The argument index for different possible parameters. 0 indicates that the argument is
// unused. Coordinates are usually at index 1, so it's pre-initialized.
size_t coordinatesIndex = 1;
size_t biasIndex = 0;
size_t lodIndex = 0;
size_t compareIndex = 0;
size_t dPdxIndex = 0;
size_t dPdyIndex = 0;
size_t offsetIndex = 0;
size_t offsetsIndex = 0;
size_t gatherComponentIndex = 0;
size_t sampleIndex = 0;
size_t dataIndex = 0;
// Whether this is a Dref variant of a sample call.
bool isDref = IsShadowSampler(samplerBasicType);
// Whether this is a Proj variant of a sample call.
bool isProj = false;
// The SPIR-V op used to implement the built-in. For OpImageSample* instructions,
// OpImageSampleImplicitLod is initially specified, which is later corrected based on |isDref|
// and |isProj|.
spv::Op spirvOp = BuiltInGroup::IsTexture(op) ? spv::OpImageSampleImplicitLod : spv::OpNop;
// Organize the parameters and decide the SPIR-V Op to use.
switch (op)
{
case EOpTexture2D:
case EOpTextureCube:
case EOpTexture1D:
case EOpTexture3D:
case EOpShadow1D:
case EOpShadow2D:
case EOpShadow2DEXT:
case EOpTexture2DRect:
case EOpTextureVideoWEBGL:
case EOpTexture:
case EOpTexture2DBias:
case EOpTextureCubeBias:
case EOpTexture3DBias:
case EOpTexture1DBias:
case EOpShadow1DBias:
case EOpShadow2DBias:
case EOpTextureBias:
// For shadow cube arrays, the compare value is specified through an additional
// parameter, while for the rest is taken out of the coordinates.
if (function->getParamCount() == 3)
{
if (samplerBasicType == EbtSamplerCubeArrayShadow)
{
compareIndex = 2;
}
else
{
biasIndex = 2;
}
}
break;
case EOpTexture2DProj:
case EOpTexture1DProj:
case EOpTexture3DProj:
case EOpShadow1DProj:
case EOpShadow2DProj:
case EOpShadow2DProjEXT:
case EOpTexture2DRectProj:
case EOpTextureProj:
case EOpTexture2DProjBias:
case EOpTexture3DProjBias:
case EOpTexture1DProjBias:
case EOpShadow1DProjBias:
case EOpShadow2DProjBias:
case EOpTextureProjBias:
isProj = true;
if (function->getParamCount() == 3)
{
biasIndex = 2;
}
break;
case EOpTexture2DLod:
case EOpTextureCubeLod:
case EOpTexture1DLod:
case EOpShadow1DLod:
case EOpShadow2DLod:
case EOpTexture3DLod:
case EOpTexture2DLodVS:
case EOpTextureCubeLodVS:
case EOpTexture2DLodEXTFS:
case EOpTextureCubeLodEXTFS:
case EOpTextureLod:
ASSERT(function->getParamCount() == 3);
lodIndex = 2;
break;
case EOpTexture2DProjLod:
case EOpTexture1DProjLod:
case EOpShadow1DProjLod:
case EOpShadow2DProjLod:
case EOpTexture3DProjLod:
case EOpTexture2DProjLodVS:
case EOpTexture2DProjLodEXTFS:
case EOpTextureProjLod:
ASSERT(function->getParamCount() == 3);
isProj = true;
lodIndex = 2;
break;
case EOpTexelFetch:
case EOpTexelFetchOffset:
// texelFetch has the following forms:
//
// - texelFetch(sampler, P);
// - texelFetch(sampler, P, lod);
// - texelFetch(samplerMS, P, sample);
//
// texelFetchOffset has an additional offset parameter at the end.
//
// In SPIR-V, OpImageFetch is used which operates on the image itself.
spirvOp = spv::OpImageFetch;
extractImageFromSampledImage = true;
if (IsSamplerMS(samplerBasicType))
{
ASSERT(function->getParamCount() == 3);
sampleIndex = 2;
}
else if (function->getParamCount() >= 3)
{
lodIndex = 2;
}
if (op == EOpTexelFetchOffset)
{
offsetIndex = function->getParamCount() - 1;
}
break;
case EOpTexture2DGradEXT:
case EOpTextureCubeGradEXT:
case EOpTextureGrad:
ASSERT(function->getParamCount() == 4);
dPdxIndex = 2;
dPdyIndex = 3;
break;
case EOpTexture2DProjGradEXT:
case EOpTextureProjGrad:
ASSERT(function->getParamCount() == 4);
isProj = true;
dPdxIndex = 2;
dPdyIndex = 3;
break;
case EOpTextureOffset:
case EOpTextureOffsetBias:
ASSERT(function->getParamCount() >= 3);
offsetIndex = 2;
if (function->getParamCount() == 4)
{
biasIndex = 3;
}
break;
case EOpTextureProjOffset:
case EOpTextureProjOffsetBias:
ASSERT(function->getParamCount() >= 3);
isProj = true;
offsetIndex = 2;
if (function->getParamCount() == 4)
{
biasIndex = 3;
}
break;
case EOpTextureLodOffset:
ASSERT(function->getParamCount() == 4);
lodIndex = 2;
offsetIndex = 3;
break;
case EOpTextureProjLodOffset:
ASSERT(function->getParamCount() == 4);
isProj = true;
lodIndex = 2;
offsetIndex = 3;
break;
case EOpTextureGradOffset:
ASSERT(function->getParamCount() == 5);
dPdxIndex = 2;
dPdyIndex = 3;
offsetIndex = 4;
break;
case EOpTextureProjGradOffset:
ASSERT(function->getParamCount() == 5);
isProj = true;
dPdxIndex = 2;
dPdyIndex = 3;
offsetIndex = 4;
break;
case EOpTextureGather:
// For shadow textures, refZ (same as Dref) is specified as the last argument.
// Otherwise a component may be specified which defaults to 0 if not specified.
spirvOp = spv::OpImageGather;
if (isDref)
{
ASSERT(function->getParamCount() == 3);
compareIndex = 2;
}
else if (function->getParamCount() == 3)
{
gatherComponentIndex = 2;
}
break;
case EOpTextureGatherOffset:
case EOpTextureGatherOffsetComp:
case EOpTextureGatherOffsets:
case EOpTextureGatherOffsetsComp:
// textureGatherOffset and textureGatherOffsets have the following forms:
//
// - texelGatherOffset*(sampler, P, offset*);
// - texelGatherOffset*(sampler, P, offset*, component);
// - texelGatherOffset*(sampler, P, refZ, offset*);
//
spirvOp = spv::OpImageGather;
if (isDref)
{
ASSERT(function->getParamCount() == 4);
compareIndex = 2;
}
else if (function->getParamCount() == 4)
{
gatherComponentIndex = 3;
}
ASSERT(function->getParamCount() >= 3);
if (BuiltInGroup::IsTextureGatherOffset(op))
{
offsetIndex = isDref ? 3 : 2;
}
else
{
offsetsIndex = isDref ? 3 : 2;
}
break;
case EOpImageStore:
// imageStore has the following forms:
//
// - imageStore(image, P, data);
// - imageStore(imageMS, P, sample, data);
//
spirvOp = spv::OpImageWrite;
if (IsSamplerMS(samplerBasicType))
{
ASSERT(function->getParamCount() == 4);
sampleIndex = 2;
dataIndex = 3;
}
else
{
ASSERT(function->getParamCount() == 3);
dataIndex = 2;
}
break;
case EOpImageLoad:
// imageStore has the following forms:
//
// - imageLoad(image, P);
// - imageLoad(imageMS, P, sample);
//
spirvOp = spv::OpImageRead;
if (IsSamplerMS(samplerBasicType))
{
ASSERT(function->getParamCount() == 3);
sampleIndex = 2;
}
else
{
ASSERT(function->getParamCount() == 2);
}
break;
// Queries:
case EOpTextureSize:
case EOpImageSize:
// textureSize has the following forms:
//
// - textureSize(sampler);
// - textureSize(sampler, lod);
//
// while imageSize has only one form:
//
// - imageSize(image);
//
extractImageFromSampledImage = true;
if (function->getParamCount() == 2)
{
spirvOp = spv::OpImageQuerySizeLod;
lodIndex = 1;
}
else
{
spirvOp = spv::OpImageQuerySize;
}
// No coordinates parameter.
coordinatesIndex = 0;
break;
case EOpTextureSamples:
case EOpImageSamples:
extractImageFromSampledImage = true;
spirvOp = spv::OpImageQuerySamples;
// No coordinates parameter.
coordinatesIndex = 0;
break;
case EOpTextureQueryLevels:
extractImageFromSampledImage = true;
spirvOp = spv::OpImageQueryLevels;
// No coordinates parameter.
coordinatesIndex = 0;
break;
case EOpTextureQueryLod:
spirvOp = spv::OpImageQueryLod;
break;
default:
UNREACHABLE();
}
// If an implicit-lod instruction is used outside a fragment shader, change that to an explicit
// one as they are not allowed in SPIR-V outside fragment shaders.
bool makeLodExplicit =
mCompiler->getShaderType() != GL_FRAGMENT_SHADER && lodIndex == 0 &&
(spirvOp == spv::OpImageSampleImplicitLod || spirvOp == spv::OpImageFetch);
// Apply any necessary fix up.
if (extractImageFromSampledImage && IsSampler(samplerBasicType))
{
// Get the (non-sampled) image type.
SpirvType imageType = mBuilder.getSpirvType(samplerType, EbsUnspecified);
ASSERT(!imageType.isSamplerBaseImage);
imageType.isSamplerBaseImage = true;
const spirv::IdRef extractedImageTypeId = mBuilder.getSpirvTypeData(imageType, nullptr).id;
// Use OpImage to get the image out of the sampled image.
const spirv::IdRef extractedImage = mBuilder.getNewId({});
spirv::WriteImage(mBuilder.getSpirvCurrentFunctionBlock(), extractedImageTypeId,
extractedImage, image);
image = extractedImage;
}
// Gather operands as necessary.
// - Coordinates
int coordinatesChannelCount = 0;
spirv::IdRef coordinatesId;
const TType *coordinatesType = nullptr;
if (coordinatesIndex > 0)
{
coordinatesId = parameters[coordinatesIndex];
coordinatesType = &function->getParam(coordinatesIndex)->getType();
coordinatesChannelCount = coordinatesType->getNominalSize();
}
// - Dref; either specified as a compare/refz argument (cube array, gather), or:
// * coordinates.z for proj variants
// * coordinates.<last> for others
spirv::IdRef drefId;
if (compareIndex > 0)
{
drefId = parameters[compareIndex];
}
else if (isDref)
{
// Get the component index
ASSERT(coordinatesChannelCount > 0);
int drefComponent = isProj ? 2 : coordinatesChannelCount - 1;
// Get the component type
SpirvType drefSpirvType = mBuilder.getSpirvType(*coordinatesType, EbsUnspecified);
drefSpirvType.primarySize = 1;
const spirv::IdRef drefTypeId = mBuilder.getSpirvTypeData(drefSpirvType, nullptr).id;
// Extract the dref component out of coordinates.
drefId = mBuilder.getNewId(mBuilder.getDecorations(*coordinatesType));
spirv::WriteCompositeExtract(mBuilder.getSpirvCurrentFunctionBlock(), drefTypeId, drefId,
coordinatesId, {spirv::LiteralInteger(drefComponent)});
}
// - Gather component
spirv::IdRef gatherComponentId;
if (gatherComponentIndex > 0)
{
gatherComponentId = parameters[gatherComponentIndex];
}
else if (spirvOp == spv::OpImageGather)
{
// If comp is not specified, component 0 is taken as default.
gatherComponentId = mBuilder.getIntConstant(0);
}
// - Image write data
spirv::IdRef dataId;
if (dataIndex > 0)
{
dataId = parameters[dataIndex];
}
// - Other operands
spv::ImageOperandsMask operandsMask = spv::ImageOperandsMaskNone;
spirv::IdRefList imageOperandsList;
if (biasIndex > 0)
{
operandsMask = operandsMask | spv::ImageOperandsBiasMask;
imageOperandsList.push_back(parameters[biasIndex]);
}
if (lodIndex > 0)
{
operandsMask = operandsMask | spv::ImageOperandsLodMask;
imageOperandsList.push_back(parameters[lodIndex]);
}
else if (makeLodExplicit)
{
// If the implicit-lod variant is used outside fragment shaders, switch to explicit and use
// lod 0.
operandsMask = operandsMask | spv::ImageOperandsLodMask;
imageOperandsList.push_back(spirvOp == spv::OpImageFetch ? mBuilder.getUintConstant(0)
: mBuilder.getFloatConstant(0));
}
if (dPdxIndex > 0)
{
ASSERT(dPdyIndex > 0);
operandsMask = operandsMask | spv::ImageOperandsGradMask;
imageOperandsList.push_back(parameters[dPdxIndex]);
imageOperandsList.push_back(parameters[dPdyIndex]);
}
if (offsetIndex > 0)
{
// Non-const offsets require the ImageGatherExtended feature.
if (node->getChildNode(offsetIndex)->getAsTyped()->hasConstantValue())
{
operandsMask = operandsMask | spv::ImageOperandsConstOffsetMask;
}
else
{
ASSERT(spirvOp == spv::OpImageGather);
operandsMask = operandsMask | spv::ImageOperandsOffsetMask;
mBuilder.addCapability(spv::CapabilityImageGatherExtended);
}
imageOperandsList.push_back(parameters[offsetIndex]);
}
if (offsetsIndex > 0)
{
ASSERT(node->getChildNode(offsetsIndex)->getAsTyped()->hasConstantValue());
operandsMask = operandsMask | spv::ImageOperandsConstOffsetsMask;
mBuilder.addCapability(spv::CapabilityImageGatherExtended);
imageOperandsList.push_back(parameters[offsetsIndex]);
}
if (sampleIndex > 0)
{
operandsMask = operandsMask | spv::ImageOperandsSampleMask;
imageOperandsList.push_back(parameters[sampleIndex]);
}
const spv::ImageOperandsMask *imageOperands =
imageOperandsList.empty() ? nullptr : &operandsMask;
// GLSL and SPIR-V are different in the way the projective component is specified:
//
// In GLSL:
//
// > The texture coordinates consumed from P, not including the last component of P, are divided
// > by the last component of P.
//
// In SPIR-V, there's a similar language (division by last element), but with the following
// added:
//
// > ... all unused components will appear after all used components.
//
// So for example for textureProj(sampler, vec4 P), the projective coordinates are P.xy/P.w,
// where P.z is ignored. In SPIR-V instead that would be P.xy/P.z and P.w is ignored.
//
if (isProj)
{
int requiredChannelCount = coordinatesChannelCount;
// texture*Proj* operate on the following parameters:
//
// - sampler1D, vec2 P
// - sampler1D, vec4 P
// - sampler2D, vec3 P
// - sampler2D, vec4 P
// - sampler2DRect, vec3 P
// - sampler2DRect, vec4 P
// - sampler3D, vec4 P
// - sampler1DShadow, vec4 P
// - sampler2DShadow, vec4 P
// - sampler2DRectShadow, vec4 P
//
// Of these cases, only (sampler1D*, vec4 P) and (sampler2D*, vec4 P) require moving the
// proj channel from .w to the appropriate location (.y for 1D and .z for 2D).
if (IsSampler2D(samplerBasicType))
{
requiredChannelCount = 3;
}
else if (IsSampler1D(samplerBasicType))
{
requiredChannelCount = 2;
}
if (requiredChannelCount != coordinatesChannelCount)
{
ASSERT(coordinatesChannelCount == 4);
// Get the component type
SpirvType spirvType = mBuilder.getSpirvType(*coordinatesType, EbsUnspecified);
const spirv::IdRef coordinatesTypeId = mBuilder.getSpirvTypeData(spirvType, nullptr).id;
spirvType.primarySize = 1;
const spirv::IdRef channelTypeId = mBuilder.getSpirvTypeData(spirvType, nullptr).id;
// Extract the last component out of coordinates.
const spirv::IdRef projChannelId =
mBuilder.getNewId(mBuilder.getDecorations(*coordinatesType));
spirv::WriteCompositeExtract(mBuilder.getSpirvCurrentFunctionBlock(), channelTypeId,
projChannelId, coordinatesId,
{spirv::LiteralInteger(coordinatesChannelCount - 1)});
// Insert it after the channels that are consumed. The extra channels are ignored per
// the SPIR-V spec.
const spirv::IdRef newCoordinatesId =
mBuilder.getNewId(mBuilder.getDecorations(*coordinatesType));
spirv::WriteCompositeInsert(mBuilder.getSpirvCurrentFunctionBlock(), coordinatesTypeId,
newCoordinatesId, coordinatesId, projChannelId,
{spirv::LiteralInteger(requiredChannelCount - 1)});
coordinatesId = newCoordinatesId;
}
}
// Select the correct sample Op based on whether the Proj, Dref or Explicit variants are used.
if (spirvOp == spv::OpImageSampleImplicitLod)
{
const bool isExplicitLod = lodIndex != 0 || makeLodExplicit || dPdxIndex != 0;
if (isDref)
{
if (isProj)
{
spirvOp = isExplicitLod ? spv::OpImageSampleProjDrefExplicitLod
: spv::OpImageSampleProjDrefImplicitLod;
}
else
{
spirvOp = isExplicitLod ? spv::OpImageSampleDrefExplicitLod
: spv::OpImageSampleDrefImplicitLod;
}
}
else
{
if (isProj)
{
spirvOp = isExplicitLod ? spv::OpImageSampleProjExplicitLod
: spv::OpImageSampleProjImplicitLod;
}
else
{
spirvOp =
isExplicitLod ? spv::OpImageSampleExplicitLod : spv::OpImageSampleImplicitLod;
}
}
}
if (spirvOp == spv::OpImageGather && isDref)
{
spirvOp = spv::OpImageDrefGather;
}
spirv::IdRef result;
if (spirvOp != spv::OpImageWrite)
{
result = mBuilder.getNewId(mBuilder.getDecorations(node->getType()));
}
switch (spirvOp)
{
case spv::OpImageQuerySizeLod:
mBuilder.addCapability(spv::CapabilityImageQuery);
ASSERT(imageOperandsList.size() == 1);
spirv::WriteImageQuerySizeLod(mBuilder.getSpirvCurrentFunctionBlock(), resultTypeId,
result, image, imageOperandsList[0]);
break;
case spv::OpImageQuerySize:
mBuilder.addCapability(spv::CapabilityImageQuery);
spirv::WriteImageQuerySize(mBuilder.getSpirvCurrentFunctionBlock(), resultTypeId,
result, image);
break;
case spv::OpImageQueryLod:
mBuilder.addCapability(spv::CapabilityImageQuery);
spirv::WriteImageQueryLod(mBuilder.getSpirvCurrentFunctionBlock(), resultTypeId, result,
image, coordinatesId);
break;
case spv::OpImageQueryLevels:
mBuilder.addCapability(spv::CapabilityImageQuery);
spirv::WriteImageQueryLevels(mBuilder.getSpirvCurrentFunctionBlock(), resultTypeId,
result, image);
break;
case spv::OpImageQuerySamples:
mBuilder.addCapability(spv::CapabilityImageQuery);
spirv::WriteImageQuerySamples(mBuilder.getSpirvCurrentFunctionBlock(), resultTypeId,
result, image);
break;
case spv::OpImageSampleImplicitLod:
spirv::WriteImageSampleImplicitLod(mBuilder.getSpirvCurrentFunctionBlock(),
resultTypeId, result, image, coordinatesId,
imageOperands, imageOperandsList);
break;
case spv::OpImageSampleExplicitLod:
spirv::WriteImageSampleExplicitLod(mBuilder.getSpirvCurrentFunctionBlock(),
resultTypeId, result, image, coordinatesId,
*imageOperands, imageOperandsList);
break;
case spv::OpImageSampleDrefImplicitLod:
spirv::WriteImageSampleDrefImplicitLod(mBuilder.getSpirvCurrentFunctionBlock(),
resultTypeId, result, image, coordinatesId,
drefId, imageOperands, imageOperandsList);
break;
case spv::OpImageSampleDrefExplicitLod:
spirv::WriteImageSampleDrefExplicitLod(mBuilder.getSpirvCurrentFunctionBlock(),
resultTypeId, result, image, coordinatesId,
drefId, *imageOperands, imageOperandsList);
break;
case spv::OpImageSampleProjImplicitLod:
spirv::WriteImageSampleProjImplicitLod(mBuilder.getSpirvCurrentFunctionBlock(),
resultTypeId, result, image, coordinatesId,
imageOperands, imageOperandsList);
break;
case spv::OpImageSampleProjExplicitLod:
spirv::WriteImageSampleProjExplicitLod(mBuilder.getSpirvCurrentFunctionBlock(),
resultTypeId, result, image, coordinatesId,
*imageOperands, imageOperandsList);
break;
case spv::OpImageSampleProjDrefImplicitLod:
spirv::WriteImageSampleProjDrefImplicitLod(mBuilder.getSpirvCurrentFunctionBlock(),
resultTypeId, result, image, coordinatesId,
drefId, imageOperands, imageOperandsList);
break;
case spv::OpImageSampleProjDrefExplicitLod:
spirv::WriteImageSampleProjDrefExplicitLod(mBuilder.getSpirvCurrentFunctionBlock(),
resultTypeId, result, image, coordinatesId,
drefId, *imageOperands, imageOperandsList);
break;
case spv::OpImageFetch:
spirv::WriteImageFetch(mBuilder.getSpirvCurrentFunctionBlock(), resultTypeId, result,
image, coordinatesId, imageOperands, imageOperandsList);
break;
case spv::OpImageGather:
spirv::WriteImageGather(mBuilder.getSpirvCurrentFunctionBlock(), resultTypeId, result,
image, coordinatesId, gatherComponentId, imageOperands,
imageOperandsList);
break;
case spv::OpImageDrefGather:
spirv::WriteImageDrefGather(mBuilder.getSpirvCurrentFunctionBlock(), resultTypeId,
result, image, coordinatesId, drefId, imageOperands,
imageOperandsList);
break;
case spv::OpImageRead:
spirv::WriteImageRead(mBuilder.getSpirvCurrentFunctionBlock(), resultTypeId, result,
image, coordinatesId, imageOperands, imageOperandsList);
break;
case spv::OpImageWrite:
spirv::WriteImageWrite(mBuilder.getSpirvCurrentFunctionBlock(), image, coordinatesId,
dataId, imageOperands, imageOperandsList);
break;
default:
UNREACHABLE();
}
// In Desktop GLSL, the legacy shadow* built-ins produce a vec4, while SPIR-V
// OpImageSample*Dref* instructions produce a scalar. EXT_shadow_samplers in ESSL introduces
// similar functions but which return a scalar.
//
// TODO: For desktop GLSL, the result must be turned into a vec4. http://anglebug.com/4889.
return result;
}
void OutputSPIRVTraverser::visitSymbol(TIntermSymbol *node)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -481,14 +481,6 @@ GROUP BEGIN Texture {"queryFunction": true}
vec4 texture2DProjLod(sampler2D, vec3, float);
vec4 texture2DProjLod(sampler2D, vec4, float);
vec4 textureCubeLod(samplerCube, vec3, float);
DEFAULT METADATA {"hasSideEffects": "true"}
vec4 texture1DLod(sampler1D, float, float);
vec4 texture1DProjLod(sampler1D, vec2, float);
vec4 texture1DProjLod(sampler1D, vec4, float);
vec4 shadow1DLod(sampler1DShadow, vec3, float);
vec4 shadow1DProjLod(sampler1DShadow, vec4, float);
vec4 shadow2DLod(sampler2DShadow, vec3, float);
vec4 shadow2DProjLod(sampler2DShadow, vec4, float);
GROUP END LodVS
// EXT_shader_texture_lod brings some lod variants to fragment shaders
......
......@@ -395,11 +395,14 @@ class RewriteCubeMapSamplersAs2DArrayTraverser : public TIntermTraverser
// Create the function parameters: vec3 P, vec3 dPdx, vec3 dPdy,
// out vec2 dUVdx, out vec2 dUVdy
const TType *vec3Type = StaticType::GetBasic<EbtFloat, 3>();
TVariable *pVar =
new TVariable(mSymbolTable, ImmutableString("P"), vec3Type, SymbolType::AngleInternal);
TVariable *dPdxVar = new TVariable(mSymbolTable, ImmutableString("dPdx"), vec3Type,
TType *inVec3Type = new TType(*vec3Type);
inVec3Type->setQualifier(EvqIn);
TVariable *pVar = new TVariable(mSymbolTable, ImmutableString("P"), inVec3Type,
SymbolType::AngleInternal);
TVariable *dPdxVar = new TVariable(mSymbolTable, ImmutableString("dPdx"), inVec3Type,
SymbolType::AngleInternal);
TVariable *dPdyVar = new TVariable(mSymbolTable, ImmutableString("dPdy"), vec3Type,
TVariable *dPdyVar = new TVariable(mSymbolTable, ImmutableString("dPdy"), inVec3Type,
SymbolType::AngleInternal);
const TType *vec2Type = StaticType::GetBasic<EbtFloat, 2>();
......
......@@ -178,5 +178,5 @@ void main()
// Samplers are only supported on ES3.
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SamplersTest);
ANGLE_INSTANTIATE_TEST_ES3(SamplersTest);
ANGLE_INSTANTIATE_TEST_ES31(SamplersTest31);
ANGLE_INSTANTIATE_TEST_ES31_AND(SamplersTest31, WithDirectSPIRVGeneration(ES31_VULKAN()));
} // namespace angle
......@@ -9482,7 +9482,7 @@ ANGLE_INSTANTIATE_TEST_ES3(Texture2DBaseMaxTestES3);
ANGLE_INSTANTIATE_TEST_ES2(Texture3DTestES2);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture3DTestES3);
ANGLE_INSTANTIATE_TEST_ES3(Texture3DTestES3);
ANGLE_INSTANTIATE_TEST_ES3_AND(Texture3DTestES3, WithDirectSPIRVGeneration(ES3_VULKAN()));
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DIntegerAlpha1TestES3);
ANGLE_INSTANTIATE_TEST_ES3(Texture2DIntegerAlpha1TestES3);
......@@ -9491,13 +9491,14 @@ GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DUnsignedIntegerAlpha1Test
ANGLE_INSTANTIATE_TEST_ES3(Texture2DUnsignedIntegerAlpha1TestES3);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShadowSamplerPlusSampler3DTestES3);
ANGLE_INSTANTIATE_TEST_ES3(ShadowSamplerPlusSampler3DTestES3);
ANGLE_INSTANTIATE_TEST_ES3_AND(ShadowSamplerPlusSampler3DTestES3,
WithDirectSPIRVGeneration(ES3_VULKAN()));
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SamplerTypeMixTestES3);
ANGLE_INSTANTIATE_TEST_ES3(SamplerTypeMixTestES3);
ANGLE_INSTANTIATE_TEST_ES3_AND(SamplerTypeMixTestES3, WithDirectSPIRVGeneration(ES3_VULKAN()));
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture2DArrayTestES3);
ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayTestES3);
ANGLE_INSTANTIATE_TEST_ES3_AND(Texture2DArrayTestES3, WithDirectSPIRVGeneration(ES3_VULKAN()));
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureSizeTextureArrayTest);
ANGLE_INSTANTIATE_TEST_ES3(TextureSizeTextureArrayTest);
......@@ -9553,12 +9554,12 @@ ANGLE_INSTANTIATE_TEST_ES3(Texture2DArrayIntegerTestES3);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(Texture3DIntegerTestES3);
ANGLE_INSTANTIATE_TEST_ES3(Texture3DIntegerTestES3);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(Texture2DDepthTest);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(Texture2DDepthTest, WithDirectSPIRVGeneration(ES3_VULKAN()));
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(PBOCompressedTextureTest);
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ETC1CompressedTextureTest);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TextureBufferTestES31);
ANGLE_INSTANTIATE_TEST_ES31(TextureBufferTestES31);
ANGLE_INSTANTIATE_TEST_ES31_AND(TextureBufferTestES31, WithDirectSPIRVGeneration(ES31_VULKAN()));
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CopyImageTestES31);
ANGLE_INSTANTIATE_TEST_ES31(CopyImageTestES31);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment