[spirv] Support translation of Buffer & RWBuffer (#588)

This commit is contained in:
Ehsan 2017-08-23 12:15:11 -04:00 коммит произвёл David Peixotto
Родитель a4efd3babc
Коммит 6b09a407bb
9 изменённых файлов: 207 добавлений и 6 удалений

Просмотреть файл

@ -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");