Skip to content

Commit

Permalink
Add bgra8 format (#6163)
Browse files Browse the repository at this point in the history
* add brga8 format

* add tests

* minor fixes

* cleanup

* maybe fix broken quad control test

* add missing xslang flag on test

---------

Co-authored-by: Yong He <yonghe@outlook.com>
  • Loading branch information
fairywreath and csyonghe authored Jan 24, 2025
1 parent 92c9fff commit 0dd9076
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 6 deletions.
1 change: 1 addition & 0 deletions include/slang-image-format-defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@ SLANG_FORMAT(r16ui, (UINT16, 1, sizeof(uint16_t)))
SLANG_FORMAT(r8ui, (UINT8, 1, sizeof(uint8_t)))
SLANG_FORMAT(r64ui, (UINT64, 1, sizeof(uint64_t)))
SLANG_FORMAT(r64i, (INT64, 1, sizeof(int64_t)))
SLANG_FORMAT(bgra8, (UINT8, 4, sizeof(uint32_t)))

#undef SLANG_FORMAT
7 changes: 7 additions & 0 deletions source/slang/slang-diagnostic-defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,13 @@ DIAGNOSTIC(
explicitUniformLocation,
"Explicit binding of uniform locations is discouraged. Prefer 'ConstantBuffer<$0>' over "
"'uniform $0'")
DIAGNOSTIC(
31105,
Warning,
imageFormatUnsupportedByBackend,
"Image format '$0' is not explicitly supported by the $1 backend, using supported format '$2' "
"instead.")


DIAGNOSTIC(31120, Error, invalidAttributeTarget, "invalid syntax target for user defined attribute")

Expand Down
26 changes: 25 additions & 1 deletion source/slang/slang-emit-glsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,19 @@ void GLSLSourceEmitter::_emitGLSLParameterGroup(
m_writer->emit(";\n");
}

static bool isImageFormatSupportedByGLSL(ImageFormat format)
{
switch (format)
{
case ImageFormat::bgra8:
// These are formats Slang accept, but are not explicitly supported in GLSL.
return false;
default:
return true;
}
};


void GLSLSourceEmitter::_emitGLSLImageFormatModifier(IRInst* var, IRTextureType* resourceType)
{
SLANG_UNUSED(resourceType);
Expand All @@ -618,6 +631,18 @@ void GLSLSourceEmitter::_emitGLSLImageFormatModifier(IRInst* var, IRTextureType*
if (auto formatDecoration = var->findDecoration<IRFormatDecoration>())
{
auto format = formatDecoration->getFormat();
const auto formatInfo = getImageFormatInfo(format);
if (!isImageFormatSupportedByGLSL(format))
{
getSink()->diagnose(
SourceLoc(),
Diagnostics::imageFormatUnsupportedByBackend,
formatInfo.name,
"GLSL",
"unknown");
format = ImageFormat::unknown;
}

if (format == ImageFormat::unknown)
{
// If the user explicitly opts out of having a format, then
Expand All @@ -636,7 +661,6 @@ void GLSLSourceEmitter::_emitGLSLImageFormatModifier(IRInst* var, IRTextureType*
}
else
{
auto formatInfo = getImageFormatInfo(format);
if (formatInfo.scalarType == SLANG_SCALAR_TYPE_UINT64 ||
formatInfo.scalarType == SLANG_SCALAR_TYPE_INT64)
{
Expand Down
11 changes: 9 additions & 2 deletions source/slang/slang-emit-spirv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1901,7 +1901,7 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
}
}

static SpvImageFormat getSpvImageFormat(IRTextureTypeBase* type)
SpvImageFormat getSpvImageFormat(IRTextureTypeBase* type)
{
ImageFormat imageFormat =
type->hasFormat() ? (ImageFormat)type->getFormat() : ImageFormat::unknown;
Expand Down Expand Up @@ -1992,7 +1992,14 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex
case ImageFormat::r64i:
return SpvImageFormatR64i;
default:
SLANG_UNIMPLEMENTED_X("unknown image format for spirv emit");
const auto imageFormatInfo = getImageFormatInfo(imageFormat);
m_sink->diagnose(
SourceLoc(),
Diagnostics::imageFormatUnsupportedByBackend,
imageFormatInfo.name,
"SPIRV",
"unknown");
return SpvImageFormatUnknown;
}
}

Expand Down
12 changes: 10 additions & 2 deletions source/slang/slang-emit-wgsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ void WGSLSourceEmitter::emit(const AddressSpace addressSpace)
}
}

static const char* getWgslImageFormat(IRTextureTypeBase* type)
const char* WGSLSourceEmitter::getWgslImageFormat(IRTextureTypeBase* type)
{
// You can find the supported WGSL texel format from the URL:
// https://www.w3.org/TR/WGSL/#storage-texel-formats
Expand Down Expand Up @@ -405,11 +405,19 @@ static const char* getWgslImageFormat(IRTextureTypeBase* type)
return "rgba32sint";
case ImageFormat::rgba32f:
return "rgba32float";
case ImageFormat::bgra8:
return "bgra8unorm";
case ImageFormat::unknown:
// Unlike SPIR-V, WGSL doesn't have a texel format for "unknown".
return "rgba32float";
default:
// We may need to print a warning for types WGSL doesn't support
const auto imageFormatInfo = getImageFormatInfo(imageFormat);
getSink()->diagnose(
SourceLoc(),
Diagnostics::imageFormatUnsupportedByBackend,
imageFormatInfo.name,
"WGSL",
"rgba32float");
return "rgba32float";
}
}
Expand Down
2 changes: 2 additions & 0 deletions source/slang/slang-emit-wgsl.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class WGSLSourceEmitter : public CLikeSourceEmitter
const IRIntegerValue& rowCountWGSL,
const IRIntegerValue& colCountWGSL);

const char* getWgslImageFormat(IRTextureTypeBase* type);

bool m_f16ExtensionEnabled = false;
};

Expand Down
19 changes: 19 additions & 0 deletions tests/diagnostics/image-format-unsupported-by-backend.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK_SPIRV): -target spirv
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK_GLSL): -target glsl
//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK_WGSL): -target wgsl

// CHECK_SPIRV: warning 31105{{.*}}bgra8
// CHECK_GLSL: warning 31105{{.*}}bgra8
[format("bgra8")]
RWTexture2D<float4> outputTexture;

// CHECK_WGSL: warning 31105{{.*}}rg8
[format("rg8")]
RWTexture2D<float4> outputTexture2;

[numthreads(8, 8, 1)]
void main(uint3 threadID : SV_DispatchThreadID)
{
outputTexture[threadID.xy] = float4(1.0, 1.0, 1.0, 1.0);
outputTexture2[threadID.xy] = float4(1.0, 1.0, 1.0, 1.0);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
//TEST(compute):COMPARE_COMPUTE_EX:-vk -compute -shaderobj -emit-spirv-directly
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -profile cs_6_7 -dx12 -use-dxil -shaderobj -render-feature hardware-device
//TEST(compute):COMPARE_COMPUTE_EX:-metal -compute -shaderobj
//TEST(compute):COMPARE_COMPUTE_EX:-metal -compute -shaderobj -xslang -DMETAL

//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], stride=4):out,name outputBuffer
RWStructuredBuffer<uint> outputBuffer;

[numthreads(16, 1, 1)]
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
{
#if !defined(METAL)
uint index = WaveGetLaneIndex();
#else
uint index = dispatchThreadID.x;
#endif

if (index < 4)
{
Expand Down
11 changes: 11 additions & 0 deletions tests/wgsl/texture-storage.slang
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ RWStructuredBuffer<int> outputBuffer;
[format("rgba8")] RWTexture3D<float4> w3D_f32v4;
[format("rgba8")] RWTexture2DArray<float4> w2DArray_f32v4;

//TEST_INPUT: RWTexture1D(format=B8G8R8A8_UNORM, size=4, content = zero):name w1D_f32_bgra_v4
//TEST_INPUT: RWTexture2D(format=B8G8R8A8_UNORM, size=4, content = zero):name w2D_f32_bgra_v4
//TEST_INPUT: RWTexture3D(format=B8G8R8A8_UNORM, size=4, content = zero):name w3D_f32_bgra_v4
//TEST_INPUT: RWTexture2D(format=B8G8R8A8_UNORM, size=4, content = zero, arrayLength=2):name w2DArray_f32_bgra_v4
// WGSL: var w1D_f32_bgra_v4{{[^:]*}}: texture_storage_1d<bgra8unorm, read_write>
[format("bgra8")] RWTexture1D<float4> w1D_f32_bgra_v4;
[format("bgra8")] RWTexture2D<float4> w2D_f32_bgra_v4;
[format("bgra8")] RWTexture3D<float4> w3D_f32_bgra_v4;
[format("bgra8")] RWTexture2DArray<float4> w2DArray_f32_bgra_v4;

// i32 types

//TEST_INPUT: RWTexture1D(format=R32G32_SINT, size=4, content = zero):name w1D_i32v2
Expand Down Expand Up @@ -127,6 +137,7 @@ void fragMain()
bool result = true
&& TEST_textureStorage_StoreLoad<float2>(w1D_f32v2, w2D_f32v2, w3D_f32v2, w2DArray_f32v2)
&& TEST_textureStorage_StoreLoad<float4>(w1D_f32v4, w2D_f32v4, w3D_f32v4, w2DArray_f32v4)
&& TEST_textureStorage_StoreLoad<float4>(w1D_f32_bgra_v4, w2D_f32_bgra_v4, w3D_f32_bgra_v4, w2DArray_f32_bgra_v4)
&& TEST_textureStorage_StoreLoad<int32_t2>(w1D_i32v2, w2D_i32v2, w3D_i32v2, w2DArray_i32v2)
&& TEST_textureStorage_StoreLoad<int32_t4>(w1D_i32v4, w2D_i32v4, w3D_i32v4, w2DArray_i32v4)
&& TEST_textureStorage_StoreLoad<uint32_t2>(w1D_u32v2, w2D_u32v2, w3D_u32v2, w2DArray_u32v2)
Expand Down

0 comments on commit 0dd9076

Please sign in to comment.