[spirv] Support translation of Buffer & RWBuffer (#588)
This commit is contained in:
Родитель
a4efd3babc
Коммит
6b09a407bb
|
@ -291,7 +291,9 @@ public:
|
|||
Type::DecorationSet decorations = {});
|
||||
uint32_t getFunctionType(uint32_t returnType,
|
||||
llvm::ArrayRef<uint32_t> paramTypes);
|
||||
uint32_t getImageType(uint32_t sampledType, spv::Dim, bool isArray);
|
||||
uint32_t getImageType(uint32_t sampledType, spv::Dim, uint32_t depth,
|
||||
bool isArray, uint32_t ms = 0, uint32_t sampled = 1,
|
||||
spv::ImageFormat format = spv::ImageFormat::Unknown);
|
||||
uint32_t getSamplerType();
|
||||
uint32_t getSampledImageType(uint32_t imageType);
|
||||
uint32_t getByteAddressBufferType(bool isRW);
|
||||
|
|
|
@ -622,13 +622,47 @@ uint32_t ModuleBuilder::getFunctionType(uint32_t returnType,
|
|||
}
|
||||
|
||||
uint32_t ModuleBuilder::getImageType(uint32_t sampledType, spv::Dim dim,
|
||||
bool isArray) {
|
||||
const Type *type = Type::getImage(theContext, sampledType, dim,
|
||||
/*depth*/ 0, isArray, /*ms*/ 0,
|
||||
/*sampled*/ 1, spv::ImageFormat::Unknown);
|
||||
uint32_t depth, bool isArray, uint32_t ms,
|
||||
uint32_t sampled,
|
||||
spv::ImageFormat format) {
|
||||
const Type *type = Type::getImage(theContext, sampledType, dim, depth,
|
||||
isArray, ms, sampled, format);
|
||||
const uint32_t typeId = theContext.getResultIdForType(type);
|
||||
theModule.addType(type, typeId);
|
||||
|
||||
switch (format) {
|
||||
case spv::ImageFormat::Rg32f:
|
||||
case spv::ImageFormat::Rg16f:
|
||||
case spv::ImageFormat::R11fG11fB10f:
|
||||
case spv::ImageFormat::R16f:
|
||||
case spv::ImageFormat::Rgba16:
|
||||
case spv::ImageFormat::Rgb10A2:
|
||||
case spv::ImageFormat::Rg16:
|
||||
case spv::ImageFormat::Rg8:
|
||||
case spv::ImageFormat::R16:
|
||||
case spv::ImageFormat::R8:
|
||||
case spv::ImageFormat::Rgba16Snorm:
|
||||
case spv::ImageFormat::Rg16Snorm:
|
||||
case spv::ImageFormat::Rg8Snorm:
|
||||
case spv::ImageFormat::R16Snorm:
|
||||
case spv::ImageFormat::R8Snorm:
|
||||
case spv::ImageFormat::Rg32i:
|
||||
case spv::ImageFormat::Rg16i:
|
||||
case spv::ImageFormat::Rg8i:
|
||||
case spv::ImageFormat::R16i:
|
||||
case spv::ImageFormat::R8i:
|
||||
case spv::ImageFormat::Rgb10a2ui:
|
||||
case spv::ImageFormat::Rg32ui:
|
||||
case spv::ImageFormat::Rg16ui:
|
||||
case spv::ImageFormat::Rg8ui:
|
||||
case spv::ImageFormat::R16ui:
|
||||
case spv::ImageFormat::R8ui:
|
||||
requireCapability(spv::Capability::StorageImageExtendedFormats);
|
||||
}
|
||||
|
||||
if (dim == spv::Dim::Buffer)
|
||||
requireCapability(spv::Capability::SampledBuffer);
|
||||
|
||||
const char *dimStr = "";
|
||||
switch (dim) {
|
||||
case spv::Dim::Dim1D:
|
||||
|
|
|
@ -432,7 +432,7 @@ uint32_t TypeTranslator::translateResourceType(QualType type) {
|
|||
theBuilder.requireCapability(spv::Capability::Sampled1D);
|
||||
const auto sampledType = hlsl::GetHLSLResourceResultType(type);
|
||||
return theBuilder.getImageType(translateType(getElementType(sampledType)),
|
||||
dim, isArray);
|
||||
dim, /*depth*/ 0, isArray);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,9 +450,46 @@ uint32_t TypeTranslator::translateResourceType(QualType type) {
|
|||
return theBuilder.getByteAddressBufferType(/*isRW*/ true);
|
||||
}
|
||||
|
||||
// Buffer and RWBuffer types
|
||||
if (name == "Buffer" || name == "RWBuffer") {
|
||||
theBuilder.requireCapability(spv::Capability::SampledBuffer);
|
||||
const auto sampledType = hlsl::GetHLSLResourceResultType(type);
|
||||
const auto format = translateSampledTypeToImageFormat(sampledType);
|
||||
return theBuilder.getImageType(
|
||||
translateType(getElementType(sampledType)), spv::Dim::Buffer,
|
||||
/*depth*/ 0, /*isArray*/ 0, /*ms*/ 0,
|
||||
/*sampled*/ name == "Buffer" ? 1 : 2, format);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
spv::ImageFormat
|
||||
TypeTranslator::translateSampledTypeToImageFormat(QualType sampledType) {
|
||||
uint32_t elemCount = 1;
|
||||
QualType ty = {};
|
||||
if (isScalarType(sampledType, &ty) ||
|
||||
isVectorType(sampledType, &ty, &elemCount)) {
|
||||
if (const auto *builtinType = ty->getAs<BuiltinType>()) {
|
||||
switch (builtinType->getKind()) {
|
||||
case BuiltinType::Int:
|
||||
return elemCount == 1 ? spv::ImageFormat::R32i
|
||||
: elemCount == 2 ? spv::ImageFormat::Rg32i
|
||||
: spv::ImageFormat::Rgba32i;
|
||||
case BuiltinType::UInt:
|
||||
return elemCount == 1 ? spv::ImageFormat::R32ui
|
||||
: elemCount == 2 ? spv::ImageFormat::Rg32ui
|
||||
: spv::ImageFormat::Rgba32ui;
|
||||
case BuiltinType::Float:
|
||||
return elemCount == 1 ? spv::ImageFormat::R32f
|
||||
: elemCount == 2 ? spv::ImageFormat::Rg32f
|
||||
: spv::ImageFormat::Rgba32f;
|
||||
}
|
||||
}
|
||||
}
|
||||
emitError("Unimplemented resource result type was used.");
|
||||
return spv::ImageFormat::Unknown;
|
||||
}
|
||||
|
||||
std::pair<uint32_t, uint32_t>
|
||||
TypeTranslator::getAlignmentAndSize(QualType type, uint32_t *stride,
|
||||
const bool isRowMajor) {
|
||||
|
|
|
@ -144,6 +144,10 @@ private:
|
|||
std::pair<uint32_t, uint32_t>
|
||||
getAlignmentAndSize(QualType type, uint32_t *stride, bool isRowMajor);
|
||||
|
||||
/// \bried For the given sampled type, returns the corresponding image format
|
||||
/// that can be used to create an image object.
|
||||
spv::ImageFormat translateSampledTypeToImageFormat(QualType type);
|
||||
|
||||
private:
|
||||
ASTContext &astContext;
|
||||
ModuleBuilder &theBuilder;
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
// Run: %dxc -T ps_6_0 -E main
|
||||
|
||||
// CHECK: OpCapability SampledBuffer
|
||||
// CHECK: OpCapability StorageImageExtendedFormats
|
||||
|
||||
// CHECK: %type_buffer_image = OpTypeImage %int Buffer 0 0 0 1 R32i
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image
|
||||
Buffer<int> intbuf;
|
||||
// CHECK: %type_buffer_image_0 = OpTypeImage %uint Buffer 0 0 0 1 R32ui
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_0 = OpTypePointer UniformConstant %type_buffer_image_0
|
||||
Buffer<uint> uintbuf;
|
||||
// CHECK: %type_buffer_image_1 = OpTypeImage %float Buffer 0 0 0 1 R32f
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_1 = OpTypePointer UniformConstant %type_buffer_image_1
|
||||
Buffer<float> floatbuf;
|
||||
|
||||
// CHECK: %type_buffer_image_2 = OpTypeImage %int Buffer 0 0 0 2 R32i
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_2 = OpTypePointer UniformConstant %type_buffer_image_2
|
||||
RWBuffer<int> intrwbuf;
|
||||
// CHECK: %type_buffer_image_3 = OpTypeImage %uint Buffer 0 0 0 2 R32ui
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_3 = OpTypePointer UniformConstant %type_buffer_image_3
|
||||
RWBuffer<uint> uintrwbuf;
|
||||
// CHECK: %type_buffer_image_4 = OpTypeImage %float Buffer 0 0 0 2 R32f
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_4 = OpTypePointer UniformConstant %type_buffer_image_4
|
||||
RWBuffer<float> floatrwbuf;
|
||||
|
||||
// CHECK: %type_buffer_image_5 = OpTypeImage %int Buffer 0 0 0 1 Rg32i
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_5 = OpTypePointer UniformConstant %type_buffer_image_5
|
||||
Buffer<int2> int2buf;
|
||||
// CHECK: %type_buffer_image_6 = OpTypeImage %uint Buffer 0 0 0 1 Rg32ui
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_6 = OpTypePointer UniformConstant %type_buffer_image_6
|
||||
Buffer<uint2> uint2buf;
|
||||
// CHECK: %type_buffer_image_7 = OpTypeImage %float Buffer 0 0 0 1 Rg32f
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_7 = OpTypePointer UniformConstant %type_buffer_image_7
|
||||
Buffer<float2> float2buf;
|
||||
|
||||
// CHECK: %type_buffer_image_8 = OpTypeImage %int Buffer 0 0 0 2 Rg32i
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_8 = OpTypePointer UniformConstant %type_buffer_image_8
|
||||
RWBuffer<int2> int2rwbuf;
|
||||
// CHECK: %type_buffer_image_9 = OpTypeImage %uint Buffer 0 0 0 2 Rg32ui
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_9 = OpTypePointer UniformConstant %type_buffer_image_9
|
||||
RWBuffer<uint2> uint2rwbuf;
|
||||
// CHECK: %type_buffer_image_10 = OpTypeImage %float Buffer 0 0 0 2 Rg32f
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_10 = OpTypePointer UniformConstant %type_buffer_image_10
|
||||
RWBuffer<float2> float2rwbuf;
|
||||
|
||||
// CHECK: %type_buffer_image_11 = OpTypeImage %int Buffer 0 0 0 1 Rgba32i
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_11 = OpTypePointer UniformConstant %type_buffer_image_11
|
||||
Buffer<int3> int3buf;
|
||||
Buffer<int4> int4buf;
|
||||
// CHECK: %type_buffer_image_12 = OpTypeImage %uint Buffer 0 0 0 1 Rgba32ui
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_12 = OpTypePointer UniformConstant %type_buffer_image_12
|
||||
Buffer<uint3> uint3buf;
|
||||
Buffer<uint4> uint4buf;
|
||||
// CHECK: %type_buffer_image_13 = OpTypeImage %float Buffer 0 0 0 1 Rgba32f
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_13 = OpTypePointer UniformConstant %type_buffer_image_13
|
||||
Buffer<float3> float3buf;
|
||||
Buffer<float4> float4buf;
|
||||
|
||||
// CHECK: %type_buffer_image_14 = OpTypeImage %int Buffer 0 0 0 2 Rgba32i
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_14 = OpTypePointer UniformConstant %type_buffer_image_14
|
||||
RWBuffer<int3> int3rwbuf;
|
||||
RWBuffer<int4> int4rwbuf;
|
||||
// CHECK: %type_buffer_image_15 = OpTypeImage %uint Buffer 0 0 0 2 Rgba32ui
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_15 = OpTypePointer UniformConstant %type_buffer_image_15
|
||||
RWBuffer<uint3> uint3rwbuf;
|
||||
RWBuffer<uint4> uint4rwbuf;
|
||||
// CHECK: %type_buffer_image_16 = OpTypeImage %float Buffer 0 0 0 2 Rgba32f
|
||||
// CHECK: %_ptr_UniformConstant_type_buffer_image_16 = OpTypePointer UniformConstant %type_buffer_image_16
|
||||
RWBuffer<float3> float3rwbuf;
|
||||
RWBuffer<float4> float4rwbuf;
|
||||
|
||||
// CHECK: %intbuf = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant
|
||||
// CHECK: %uintbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_0 UniformConstant
|
||||
// CHECK: %floatbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_1 UniformConstant
|
||||
// CHECK: %intrwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_2 UniformConstant
|
||||
// CHECK: %uintrwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_3 UniformConstant
|
||||
// CHECK: %floatrwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_4 UniformConstant
|
||||
// CHECK: %int2buf = OpVariable %_ptr_UniformConstant_type_buffer_image_5 UniformConstant
|
||||
// CHECK: %uint2buf = OpVariable %_ptr_UniformConstant_type_buffer_image_6 UniformConstant
|
||||
// CHECK: %float2buf = OpVariable %_ptr_UniformConstant_type_buffer_image_7 UniformConstant
|
||||
// CHECK: %int2rwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_8 UniformConstant
|
||||
// CHECK: %uint2rwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_9 UniformConstant
|
||||
// CHECK: %float2rwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_10 UniformConstant
|
||||
// CHECK: %int3buf = OpVariable %_ptr_UniformConstant_type_buffer_image_11 UniformConstant
|
||||
// CHECK: %int4buf = OpVariable %_ptr_UniformConstant_type_buffer_image_11 UniformConstant
|
||||
// CHECK: %uint3buf = OpVariable %_ptr_UniformConstant_type_buffer_image_12 UniformConstant
|
||||
// CHECK: %uint4buf = OpVariable %_ptr_UniformConstant_type_buffer_image_12 UniformConstant
|
||||
// CHECK: %float3buf = OpVariable %_ptr_UniformConstant_type_buffer_image_13 UniformConstant
|
||||
// CHECK: %float4buf = OpVariable %_ptr_UniformConstant_type_buffer_image_13 UniformConstant
|
||||
// CHECK: %int3rwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_14 UniformConstant
|
||||
// CHECK: %int4rwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_14 UniformConstant
|
||||
// CHECK: %uint3rwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_15 UniformConstant
|
||||
// CHECK: %uint4rwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_15 UniformConstant
|
||||
// CHECK: %float3rwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_16 UniformConstant
|
||||
// CHECK: %float4rwbuf = OpVariable %_ptr_UniformConstant_type_buffer_image_16 UniformConstant
|
||||
|
||||
void main() {}
|
|
@ -20,6 +20,16 @@ Texture2D<float4> texture1;
|
|||
[[vk::binding(2, 2)]]
|
||||
Texture3D<float4> texture2 : register(t0, space0);
|
||||
|
||||
// CHECK: OpDecorate %myBuffer DescriptorSet 2
|
||||
// CHECK-NEXT: OpDecorate %myBuffer Binding 3
|
||||
[[vk::binding(3, 2)]]
|
||||
Buffer<int> myBuffer : register(t1, space0);
|
||||
|
||||
// CHECK: OpDecorate %myRWBuffer DescriptorSet 1
|
||||
// CHECK-NEXT: OpDecorate %myRWBuffer Binding 4
|
||||
[[vk::binding(4, 1)]]
|
||||
RWBuffer<float4> myRWBuffer : register(u0, space1);
|
||||
|
||||
// TODO: support [[vk::binding()]] on cbuffer
|
||||
|
||||
float4 main() : SV_Target {
|
||||
|
|
|
@ -22,6 +22,14 @@ cbuffer myCbuffer {
|
|||
float4 stuff;
|
||||
}
|
||||
|
||||
// CHECK: OpDecorate %myBuffer DescriptorSet 0
|
||||
// CHECK-NEXT: OpDecorate %myBuffer Binding 5
|
||||
Buffer<int> myBuffer;
|
||||
|
||||
// CHECK: OpDecorate %myRWBuffer DescriptorSet 0
|
||||
// CHECK-NEXT: OpDecorate %myRWBuffer Binding 6
|
||||
RWBuffer<float4> myRWBuffer;
|
||||
|
||||
float4 main() : SV_Target {
|
||||
return 1.0;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,14 @@ cbuffer myCbuffer : register(b1, space3) {
|
|||
float4 stuff;
|
||||
}
|
||||
|
||||
// CHECK: OpDecorate %myBuffer DescriptorSet 0
|
||||
// CHECK-NEXT: OpDecorate %myBuffer Binding 3
|
||||
Buffer<int> myBuffer : register(t3, space0);
|
||||
|
||||
// CHECK: OpDecorate %myRWBuffer DescriptorSet 1
|
||||
// CHECK-NEXT: OpDecorate %myRWBuffer Binding 4
|
||||
RWBuffer<float4> myRWBuffer : register(u4, space1);
|
||||
|
||||
float4 main() : SV_Target {
|
||||
return 1.0;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ TEST_F(FileTest, ArrayTypes) { runFileTest("type.array.hlsl"); }
|
|||
TEST_F(FileTest, TypedefTypes) { runFileTest("type.typedef.hlsl"); }
|
||||
TEST_F(FileTest, SamplerTypes) { runFileTest("type.sampler.hlsl"); }
|
||||
TEST_F(FileTest, TextureTypes) { runFileTest("type.texture.hlsl"); }
|
||||
TEST_F(FileTest, BufferType) { runFileTest("type.buffer.hlsl"); }
|
||||
TEST_F(FileTest, CBufferType) { runFileTest("type.cbuffer.hlsl"); }
|
||||
TEST_F(FileTest, ByteAddressBufferTypes) {
|
||||
runFileTest("type.byte-address-buffer.hlsl");
|
||||
|
|
Загрузка…
Ссылка в новой задаче