diff options
| author | Gangzheng Tong <tonggangzheng@gmail.com> | 2025-06-18 10:38:31 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-18 17:38:31 +0000 |
| commit | 3822f9243f7b80be4c47318cf3d0b8d9800e67dd (patch) | |
| tree | 2a0f92310625b7d83fccaef205087579f292281a | |
| parent | 63ca2325d7f6afdbf07e8f00975fab01ec516302 (diff) | |
Fix additional VVL violations (#7377)
* fix: add sampleCount and mipMaps to st2DMS_f32v4
Fix VUID-VkImageCreateInfo-samples-02257:
The Vulkan spec states: If an OpTypeImage has an MS operand 1,
its bound image must not have been created with
VkImageCreateInfo::samples as VK_SAMPLE_COUNT_1_BIT
* Fix VUID-VkShaderModuleCreateInfo-pCode-08740
Rename VK_KHR_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME
to VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME
* fix: add sampleCount and mipMaps to st2DMS_f32v4
Fix VUID-VkImageCreateInfo-samples-02257:
The Vulkan spec states: If an OpTypeImage has an MS operand 1,
its bound image must not have been created with
VkImageCreateInfo::samples as VK_SAMPLE_COUNT_1_BIT
* Fix VUID-VkShaderModuleCreateInfo-pCode-08740
Rename VK_KHR_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME
to VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME
* Fix VUID-vkCmdDispatch-None-06479
Use correct format for combined depth texture.
* Fix VUID-vkCmdDispatch-format-07753 by setting format
Parse filtering mode for sampler because the RGBA8* formats do not
support linear filtering
* Create MS texture type for sample count > 1
* Use different texture formats for depth compare and gather ops
* Use clearTexture for init the data for MS textures
| -rw-r--r-- | tests/hlsl-intrinsic/texture/partial-resident-texture-combined.slang | 6 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/texture/partial-resident-texture.slang | 7 | ||||
| -rw-r--r-- | tests/hlsl-intrinsic/texture/texture-intrinsics.slang | 54 | ||||
| -rw-r--r-- | tests/metal/texture.slang | 40 | ||||
| -rw-r--r-- | tools/gfx/vulkan/vk-device.cpp | 2 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.cpp | 26 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.h | 10 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.cpp | 158 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.h | 6 |
9 files changed, 244 insertions, 65 deletions
diff --git a/tests/hlsl-intrinsic/texture/partial-resident-texture-combined.slang b/tests/hlsl-intrinsic/texture/partial-resident-texture-combined.slang index 018f220f2..2281118b7 100644 --- a/tests/hlsl-intrinsic/texture/partial-resident-texture-combined.slang +++ b/tests/hlsl-intrinsic/texture/partial-resident-texture-combined.slang @@ -37,7 +37,7 @@ Sampler1DArray<float4> st1DArray_f32v4; //TEST_INPUT: TextureSampler2D(size=4, content = one, arrayLength=2):name st2DArray_f32v4 Sampler2DArray<float4> st2DArray_f32v4; -//TEST_INPUT: TextureSampler2D(size=4, content = one):name st2DMS_f32v4 +//TEST_INPUT: TextureSampler2D(size=4, content = one, sampleCount = two, mipMaps=1, format=RGBA32Float):name st2DMS_f32v4 Sampler2DMS<float4> st2DMS_f32v4; // @@ -71,9 +71,9 @@ typealias CombinedDepth2d_array = _Texture< >; -//TEST_INPUT: TextureSampler2D(size=4, content = zero):name cd2D +//TEST_INPUT: TextureSampler2D(size=4, content = zero, format=D32Float):name cd2D CombinedDepth2d<float> cd2D; -//TEST_INPUT: TextureSampler2D(size=4, content = zero, arrayLength=2):name cd2DArray +//TEST_INPUT: TextureSampler2D(size=4, content = zero, arrayLength=2, format=D32Float):name cd2DArray CombinedDepth2d_array<float> cd2DArray; uint getNotMapped() diff --git a/tests/hlsl-intrinsic/texture/partial-resident-texture.slang b/tests/hlsl-intrinsic/texture/partial-resident-texture.slang index edf67ddc1..2997463af 100644 --- a/tests/hlsl-intrinsic/texture/partial-resident-texture.slang +++ b/tests/hlsl-intrinsic/texture/partial-resident-texture.slang @@ -48,7 +48,7 @@ Texture2DArray<float4> t2DArray_f32v4; //TEST_INPUT: TextureCube(size=4, content = one, arrayLength=2):name tCubeArray_f32v4 TextureCubeArray<float4> tCubeArray_f32v4; -//TEST_INPUT: Texture2D(size=4, content = one):name t2DMS_f32v4 +//TEST_INPUT: Texture2D(size=4, content = one, format=RGBA32Float, sampleCount=two):name t2DMS_f32v4 Texture2DMS<float4> t2DMS_f32v4; // @@ -106,9 +106,9 @@ typealias depthcube_array = _Texture< format >; -//TEST_INPUT: Texture2D(size=4, content = zero):name d2D +//TEST_INPUT: Texture2D(size=4, content = zero, format=D32Float):name d2D depth2d<float> d2D; -//TEST_INPUT: Texture2D(size=4, content = zero, arrayLength=2):name d2DArray +//TEST_INPUT: Texture2D(size=4, content = zero, arrayLength=2, format=D32Float):name d2DArray depth2d_array<float> d2DArray; uint getNotMapped() @@ -235,6 +235,7 @@ bool TEST_load<T>( int3 iuvs = int3(iuv, sampleIndex); return true + && (status = getNotMapped(), all(TN(T(1)) == t2DMS.Load(iuv, sampleIndex, offset, status))) && CheckAccessFullyMapped(status) && (status = getNotMapped(), all(TN(T(1)) == t2D.Load(iuvs, offset, status))) && CheckAccessFullyMapped(status) // SPIRV does not support sparse buffer loads. diff --git a/tests/hlsl-intrinsic/texture/texture-intrinsics.slang b/tests/hlsl-intrinsic/texture/texture-intrinsics.slang index 60b616a7f..a848353a1 100644 --- a/tests/hlsl-intrinsic/texture/texture-intrinsics.slang +++ b/tests/hlsl-intrinsic/texture/texture-intrinsics.slang @@ -5,25 +5,34 @@ //TEST(compute, vulkan):COMPARE_COMPUTE_EX(filecheck-buffer=VK):-vk -emit-spirv-directly -compute -shaderobj -output-using-type -render-feature hardware-device -xslang -DVK //DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-cuda -compute -shaderobj -output-using-type -//TEST_INPUT: Texture1D(size=4, content = one):name t1D +//TEST_INPUT: Texture1D(size=4, format=D32Float, content = one):name t1D Texture1D<float> t1D; -//TEST_INPUT: Texture2D(size=4, content = one):name t2D +//TEST_INPUT: Texture2D(size=4, format=D32Float, content = one):name t2D Texture2D<float> t2D; -//TEST_INPUT: Texture3D(size=4, content = one):name t3D +//TEST_INPUT: Texture3D(size=4, format=D32Float, content = one):name t3D Texture3D<float> t3D; -//TEST_INPUT: TextureCube(size=4, content = one):name tCube +//TEST_INPUT: TextureCube(size=4, format=D32Float, content = one):name tCube TextureCube<float> tCube; -//TEST_INPUT: Texture1D(size=4, content = one, arrayLength=2):name t1DArray +//TEST_INPUT: Texture1D(size=4, format=D32Float, content = one, arrayLength=2):name t1DArray Texture1DArray<float> t1DArray; -//TEST_INPUT: Texture2D(size=4, content = one, arrayLength=2):name t2DArray +//TEST_INPUT: Texture2D(size=4, format=D32Float, content = one, arrayLength=2):name t2DArray Texture2DArray<float> t2DArray; -//TEST_INPUT: TextureCube(size=4, content = one, arrayLength=2):name tCubeArray +//TEST_INPUT: TextureCube(size=4, format=D32Float, content = one, arrayLength=2):name tCubeArray TextureCubeArray<float> tCubeArray; +//TEST_INPUT: Texture2D(size=4, content = one):name t2D_RGBA +Texture2D<float> t2D_RGBA; +//TEST_INPUT: Texture2D(size=4, content = one, arrayLength=2):name t2DArray_RGBA +Texture2DArray<float> t2DArray_RGBA; +//TEST_INPUT: TextureCube(size=4, content = one):name tCube_RGBA +TextureCube<float> tCube_RGBA; +//TEST_INPUT: TextureCube(size=4, content = one, arrayLength=2):name tCubeArray_RGBA +TextureCubeArray<float> tCubeArray_RGBA; + //TEST_INPUT: Sampler:name samplerState SamplerState samplerState; -//TEST_INPUT: Sampler:name shadowSampler +//TEST_INPUT: Sampler(depthCompare):name shadowSampler SamplerComparisonState shadowSampler; @@ -83,6 +92,7 @@ void computeMain(int3 dispatchThreadID: SV_DispatchThreadID) float Object.SampleCmpLevelZero() */ // NOTE: These are having issues with vulkan (glsl) + // SampleCmpLevelZero() requires format with VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT. val += t1D.SampleCmpLevelZero(shadowSampler, u, 0); val += t2D.SampleCmpLevelZero(shadowSampler, float2(u, u), 0); val += t1DArray.SampleCmpLevelZero(shadowSampler, float2(u, u), 0); @@ -96,7 +106,8 @@ void computeMain(int3 dispatchThreadID: SV_DispatchThreadID) // TextureCube does not have an offset version of this // Status variant -#if !defined(VK) + #if !defined(VK) + val += t1D.SampleCmpLevelZero(shadowSampler, u, 0, 0, status); val += t2D.SampleCmpLevelZero(shadowSampler, float2(u, u), 0, int2(0, 0), status); @@ -268,44 +279,44 @@ void computeMain(int3 dispatchThreadID: SV_DispatchThreadID) /* <Template Type>4 Object.Gather() */ - float4 f4 = t2D.Gather(samplerState, float2(u, u)); + float4 f4 = t2D_RGBA.Gather(samplerState, float2(u, u)); val += f4.x; val += f4.y; val += f4.z; val += f4.w; - f4 = tCube.Gather(samplerState, normalize(float3(u, 1 - u, u))); + f4 = tCube_RGBA.Gather(samplerState, normalize(float3(u, 1 - u, u))); val += f4.x; val += f4.y; val += f4.z; val += f4.w; - f4 = t2DArray.Gather(samplerState, float3(u, u, 0)); + f4 = t2DArray_RGBA.Gather(samplerState, float3(u, u, 0)); val += f4.x; val += f4.y; val += f4.z; val += f4.w; - f4 = tCubeArray.Gather(samplerState, float4(normalize(float3(u, 1 - u, u)), 0)); + f4 = tCubeArray_RGBA.Gather(samplerState, float4(normalize(float3(u, 1 - u, u)), 0)); val += f4.x; val += f4.y; val += f4.z; val += f4.w; // Offset variant - f4 = t2D.Gather(samplerState, float2(u, u), int2(0, 0)); + f4 = t2D_RGBA.Gather(samplerState, float2(u, u), int2(0, 0)); val += f4.x; val += f4.y; val += f4.z; val += f4.w; - f4 = t2DArray.Gather(samplerState, float3(u, u, 0), int2(0, 0)); + f4 = t2DArray_RGBA.Gather(samplerState, float3(u, u, 0), int2(0, 0)); val += f4.x; val += f4.y; val += f4.z; val += f4.w; // Object.GatherGreen() - f4 = t2D.GatherGreen(samplerState, float2(u, u), int2(1, 2)); + f4 = t2D_RGBA.GatherGreen(samplerState, float2(u, u), int2(1, 2)); val += f4.x; val += f4.y; val += f4.z; val += f4.w; - f4 = t2D.GatherGreen(samplerState, float2(u, u), int2(1, 2), int2(3, 4), int2(5, 6), int2(7, 8)); + f4 = t2D_RGBA.GatherGreen(samplerState, float2(u, u), int2(1, 2), int2(3, 4), int2(5, 6), int2(7, 8)); val += f4.x; val += f4.y; val += f4.z; val += f4.w; - f4 = tCubeArray.GatherGreen(samplerState, float4(1.5, 1.5, 1.5, 1.5)); + f4 = tCubeArray_RGBA.GatherGreen(samplerState, float4(1.5, 1.5, 1.5, 1.5)); val += f4.x; val += f4.y; val += f4.z; val += f4.w; // status variant #if !defined(VK) - f4 = t2D.GatherGreen(samplerState, float2(u, u), int2(1, 2), status); + f4 = t2D_RGBA.GatherGreen(samplerState, float2(u, u), int2(1, 2), status); val += f4.x; val += f4.y; val += f4.z; val += f4.w; - f4 = t2D.GatherGreen(samplerState, float2(u, u), int2(1, 2), int2(3, 4), int2(5, 6), int2(7, 8), status); + f4 = t2D_RGBA.GatherGreen(samplerState, float2(u, u), int2(1, 2), int2(3, 4), int2(5, 6), int2(7, 8), status); val += f4.x; val += f4.y; val += f4.z; val += f4.w; - f4 = tCubeArray.GatherGreen(samplerState, float4(1.5, 1.5, 1.5, 1.5), status); + f4 = tCubeArray_RGBA.GatherGreen(samplerState, float4(1.5, 1.5, 1.5, 1.5), status); val += f4.x; val += f4.y; val += f4.z; val += f4.w; #endif @@ -331,6 +342,7 @@ void computeMain(int3 dispatchThreadID: SV_DispatchThreadID) <Template Type> Object.SampleGrad() */ float _ddx = 0.0f, _ddy = 0.0f; + val += t1D.SampleGrad(samplerState, 0.0f, _ddx, _ddy); val += t2D.SampleGrad(samplerState, float2(u, u), float2(_ddx, _ddx), float2(_ddy, _ddy)); val += t3D.SampleGrad(samplerState, float3(u, u, u), float3(_ddx, _ddx, _ddx), float3(_ddy, _ddy, _ddy)); diff --git a/tests/metal/texture.slang b/tests/metal/texture.slang index 174717da4..70cd1b266 100644 --- a/tests/metal/texture.slang +++ b/tests/metal/texture.slang @@ -56,36 +56,36 @@ Texture2DArray<half4> t2DArray_f16; //TEST_INPUT: TextureCube(size=4, content = zero, arrayLength=2):name tCubeArray_f16 TextureCubeArray<half4> tCubeArray_f16; -//TEST_INPUT: Texture1D(size=4, content = zero):name t1D_i32 +//TEST_INPUT: Texture1D(size=4, format=RGBA8Sint, content = zero):name t1D_i32 Texture1D<int4> t1D_i32; -//TEST_INPUT: Texture2D(size=4, content = zero):name t2D_i32 +//TEST_INPUT: Texture2D(size=4, format=RGBA8Sint, content = zero):name t2D_i32 Texture2D<int4> t2D_i32; -//TEST_INPUT: Texture3D(size=4, content = zero):name t3D_i32 +//TEST_INPUT: Texture3D(size=4, format=RGBA8Sint, content = zero):name t3D_i32 Texture3D<int4> t3D_i32; -//TEST_INPUT: TextureCube(size=4, content = zero):name tCube_i32 +//TEST_INPUT: TextureCube(size=4, format=RGBA8Sint, content = zero):name tCube_i32 TextureCube<int4> tCube_i32; -//TEST_INPUT: Texture1D(size=4, content = zero, arrayLength=2):name t1DArray_i32 +//TEST_INPUT: Texture1D(size=4, format=RGBA8Sint, content = zero, arrayLength=2):name t1DArray_i32 Texture1DArray<int4> t1DArray_i32; -//TEST_INPUT: Texture2D(size=4, content = zero, arrayLength=2):name t2DArray_i32 +//TEST_INPUT: Texture2D(size=4, format=RGBA8Sint, content = zero, arrayLength=2):name t2DArray_i32 Texture2DArray<int4> t2DArray_i32; -//TEST_INPUT: TextureCube(size=4, content = zero, arrayLength=2):name tCubeArray_i32 +//TEST_INPUT: TextureCube(size=4, format=RGBA8Sint, content = zero, arrayLength=2):name tCubeArray_i32 TextureCubeArray<int4> tCubeArray_i32; -//TEST_INPUT: Texture1D(size=4, content = zero):name t1D_u32 +//TEST_INPUT: Texture1D(size=4, format=RGBA8Uint, content = zero):name t1D_u32 Texture1D<uint4> t1D_u32; -//TEST_INPUT: Texture2D(size=4, content = zero):name t2D_u32 +//TEST_INPUT: Texture2D(size=4, format=RGBA8Uint, content = zero):name t2D_u32 Texture2D<uint4> t2D_u32; -//TEST_INPUT: Texture3D(size=4, content = zero):name t3D_u32 +//TEST_INPUT: Texture3D(size=4, format=RGBA8Uint, content = zero):name t3D_u32 Texture3D<uint4> t3D_u32; -//TEST_INPUT: TextureCube(size=4, content = zero):name tCube_u32 +//TEST_INPUT: TextureCube(size=4, format=RGBA8Uint, content = zero):name tCube_u32 TextureCube<uint4> tCube_u32; -//TEST_INPUT: Texture1D(size=4, content = zero, arrayLength=2):name t1DArray_u32 +//TEST_INPUT: Texture1D(size=4, format=RGBA8Uint, content = zero, arrayLength=2):name t1DArray_u32 Texture1DArray<uint4> t1DArray_u32; -//TEST_INPUT: Texture2D(size=4, content = zero, arrayLength=2):name t2DArray_u32 +//TEST_INPUT: Texture2D(size=4, format=RGBA8Uint, content = zero, arrayLength=2):name t2DArray_u32 Texture2DArray<uint4> t2DArray_u32; -//TEST_INPUT: TextureCube(size=4, content = zero, arrayLength=2):name tCubeArray_u32 +//TEST_INPUT: TextureCube(size=4, format=RGBA8Uint, content = zero, arrayLength=2):name tCubeArray_u32 TextureCubeArray<uint4> tCubeArray_u32; //TEST_INPUT: Texture1D(size=4, content = zero):name t1D_i16 @@ -173,18 +173,18 @@ typealias depthcube_array = _Texture< format >; -//TEST_INPUT: Texture2D(size=4, content = zero):name d2D +//TEST_INPUT: Texture2D(size=4, format=D32Float, content = zero):name d2D depth2d<float> d2D; -//TEST_INPUT: TextureCube(size=4, content = zero):name dCube +//TEST_INPUT: TextureCube(size=4, format=D32Float, content = zero):name dCube depthcube<float> dCube; -//TEST_INPUT: Texture2D(size=4, content = zero, arrayLength=2):name d2DArray +//TEST_INPUT: Texture2D(size=4, format=D32Float, content = zero, arrayLength=2):name d2DArray depth2d_array<float> d2DArray; -//TEST_INPUT: TextureCube(size=4, content = zero, arrayLength=2):name dCubeArray +//TEST_INPUT: TextureCube(size=4, format=D32Float, content = zero, arrayLength=2):name dCubeArray depthcube_array<float> dCubeArray; -//TEST_INPUT: Sampler:name samplerState +//TEST_INPUT: Sampler(filteringMode=point):name samplerState SamplerState samplerState; -//TEST_INPUT: Sampler:name shadowSampler +//TEST_INPUT: Sampler(depthCompare):name shadowSampler SamplerComparisonState shadowSampler; diff --git a/tools/gfx/vulkan/vk-device.cpp b/tools/gfx/vulkan/vk-device.cpp index d056e3984..a94d4f492 100644 --- a/tools/gfx/vulkan/vk-device.cpp +++ b/tools/gfx/vulkan/vk-device.cpp @@ -717,7 +717,7 @@ Result DeviceImpl::initVulkanInstanceAndDevice( SIMPLE_EXTENSION_FEATURE( extendedFeatures.computeShaderDerivativeFeatures, computeDerivativeGroupLinear, - VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME, + VK_KHR_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME, "computeDerivativeGroupLinear"); // Only enable raytracing validation if both requested and supported diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp index ab9ed3c7b..bb213cdaa 100644 --- a/tools/render-test/shader-input-layout.cpp +++ b/tools/render-test/shader-input-layout.cpp @@ -171,6 +171,19 @@ struct ShaderInputLayoutParser { val->samplerDesc.isCompareSampler = true; } + else if (word == "filteringMode") + { + parser.Read("="); + auto contentWord = parser.ReadWord(); + if (contentWord == "point") + { + val->samplerDesc.filteringMode = TextureFilteringMode::Point; + } + else + { + val->samplerDesc.filteringMode = TextureFilteringMode::Linear; + } + } else { return SLANG_FAIL; @@ -643,14 +656,15 @@ struct ShaderInputLayoutParser default: throw ShaderInputLayoutFormatException( - String("Unexpected '") + parser.NextToken().Content + String("' at line") + + String("Unexpected '") + parser.NextToken().Content + String("' at line ") + String(parser.NextToken().Position.Line)); } } RefPtr<ShaderInputLayout::Val> parseVal(Misc::TokenReader& parser) { - auto word = parser.NextToken().Content; + auto nextToken = parser.NextToken(); + auto word = nextToken.Content; if (parser.AdvanceIf("begin_array")) { RefPtr<ShaderInputLayout::ArrayVal> val = new ShaderInputLayout::ArrayVal; @@ -820,8 +834,8 @@ struct ShaderInputLayoutParser else { throw ShaderInputLayoutFormatException( - String("Unknown shader input type '") + word + String("' at line") + - String(parser.NextToken().Position.Line)); + String("Unknown shader input type '") + word + String("' at line: ") + + String(nextToken.Position.Line)); } parser.ReadToken(); return nullptr; @@ -997,8 +1011,10 @@ struct ShaderInputLayoutParser parentVal = rootVal; auto lines = Misc::Split(source, '\n'); + int lineNum = 0; for (auto& line : lines) { + lineNum++; if (line.startsWith("//TEST_INPUT:")) { auto lineContent = line.subString(13, line.getLength() - 13); @@ -1010,7 +1026,7 @@ struct ShaderInputLayoutParser catch (const Misc::TextFormatException&) { StringBuilder msg; - msg << "Invalid input syntax at line " << parser.NextToken().Position.Line; + msg << "Invalid input syntax at line " << lineNum << ": " << line; throw ShaderInputLayoutFormatException(msg); } } diff --git a/tools/render-test/shader-input-layout.h b/tools/render-test/shader-input-layout.h index e0a2be886..b5ee99566 100644 --- a/tools/render-test/shader-input-layout.h +++ b/tools/render-test/shader-input-layout.h @@ -82,6 +82,7 @@ struct InputBufferDesc struct InputSamplerDesc { bool isCompareSampler = false; + TextureFilteringMode filteringMode = TextureFilteringMode::Linear; }; struct TextureData @@ -109,7 +110,8 @@ struct TextureData } void* addSlice(size_t elemCount) { - void* dst = ::malloc(m_formatSize * elemCount); + const size_t totalSize = m_formatSize * elemCount; + void* dst = ::malloc(totalSize); m_slices.add(Slice::make(dst, elemCount)); return dst; } @@ -153,9 +155,9 @@ struct TextureData uint8_t m_formatSize = 0; Slang::List<Slice> m_slices; - int m_textureSize; - int m_mipLevels; - int m_arraySize; + int m_textureSize = 0; + int m_mipLevels = 1; + int m_arraySize = 1; }; class ShaderInputLayout diff --git a/tools/render-test/shader-renderer-util.cpp b/tools/render-test/shader-renderer-util.cpp index 5046a1b10..3ac62f37a 100644 --- a/tools/render-test/shader-renderer-util.cpp +++ b/tools/render-test/shader-renderer-util.cpp @@ -76,6 +76,7 @@ inline int calcNumMipLevels(TextureType type, Extent3D size) const FormatInfo& formatInfo = getFormatInfo(format); bool isArray = inputDesc.arrayLength > 1; + bool isMS = inputDesc.sampleCount > 1; textureDesc.sampleCount = inputDesc.sampleCount; textureDesc.format = format; @@ -113,9 +114,13 @@ inline int calcNumMipLevels(TextureType type, Extent3D size) case 2: { textureDesc.type = - isArray ? (inputDesc.isCube ? TextureType::TextureCubeArray - : TextureType::Texture2DArray) - : (inputDesc.isCube ? TextureType::TextureCube : TextureType::Texture2D); + isArray + ? (inputDesc.isCube + ? TextureType::TextureCubeArray + : (isMS ? TextureType::Texture2DMSArray : TextureType::Texture2DArray)) + : (inputDesc.isCube + ? TextureType::TextureCube + : (isMS ? TextureType::Texture2DMS : TextureType::Texture2D)); textureDesc.size.width = inputDesc.size; textureDesc.size.height = inputDesc.size; textureDesc.size.depth = 1; @@ -137,9 +142,9 @@ inline int calcNumMipLevels(TextureType type, Extent3D size) } // Metal doesn't support mip maps for 1D textures. - if (device->getDeviceType() == DeviceType::Metal && - (textureDesc.type == TextureType::Texture1D || - textureDesc.type == TextureType::Texture1DArray)) + if ((isMS) || (device->getDeviceType() == DeviceType::Metal && + (textureDesc.type == TextureType::Texture1D || + textureDesc.type == TextureType::Texture1DArray))) { textureDesc.mipCount = 1; } @@ -167,7 +172,16 @@ inline int calcNumMipLevels(TextureType type, Extent3D size) } } - textureOut = device->createTexture(textureDesc, initSubresources.getBuffer()); + if (isMS) + { + textureDesc.usage |= TextureUsage::RenderTarget; + textureOut = device->createTexture(textureDesc); + clearTexture(textureOut.get(), inputDesc.content, device); + } + else + { + textureOut = device->createTexture(textureDesc, initSubresources.getBuffer()); + } return textureOut ? SLANG_OK : SLANG_FAIL; } @@ -177,7 +191,7 @@ inline int calcNumMipLevels(TextureType type, Extent3D size) size_t bufferSize, const void* initData, IDevice* device, - Slang::ComPtr<IBuffer>& bufferOut) + ComPtr<IBuffer>& bufferOut) { BufferDesc bufferDesc; bufferDesc.size = bufferSize; @@ -197,6 +211,131 @@ inline int calcNumMipLevels(TextureType type, Extent3D size) return SLANG_OK; } +/* static */ Result ShaderRendererUtil::clearTexture( + ITexture* texture, + InputTextureContent content, + IDevice* device) +{ + SLANG_ASSERT(texture); + ComPtr<ICommandQueue> queue; + SLANG_RETURN_ON_FAIL(device->getQueue(QueueType::Graphics, queue.writeRef())); + + ComPtr<ICommandEncoder> commandEncoder; + SLANG_RETURN_ON_FAIL(queue->createCommandEncoder(commandEncoder.writeRef())); + + TextureDesc desc = texture->getDesc(); + SubresourceRange range; + range.layer = 0; + range.layerCount = texture->getDesc().arrayLength; + range.mip = 0; + range.mipCount = texture->getDesc().mipCount; + + FormatInfo formatInfo = getFormatInfo(desc.format); + switch (formatInfo.kind) + { + case FormatKind::Float: + { + float clearValue[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + switch (content) + { + case InputTextureContent::Zero: + // clearValue is already all zeros + break; + case InputTextureContent::One: + clearValue[0] = clearValue[1] = clearValue[2] = clearValue[3] = 1.0f; + break; + case InputTextureContent::ChessBoard: + case InputTextureContent::Gradient: + // For chessboard or gradient, we can't use a single clear value + // Instead, we should use a compute shader or multiple draw calls + SLANG_ASSERT(!"ChessBoard or Gradient content type is not supported for " + "multisampled textures - requires compute shader implementation"); + return SLANG_FAIL; + } + commandEncoder->clearTextureFloat(texture, range, clearValue); + break; + } + case FormatKind::Integer: + { + uint32_t clearValue[4] = {0U, 0U, 0U, 0U}; + switch (content) + { + case InputTextureContent::Zero: + // clearValue is already all zeros + break; + case InputTextureContent::One: + clearValue[0] = clearValue[1] = clearValue[2] = clearValue[3] = 1U; + break; + case InputTextureContent::ChessBoard: + case InputTextureContent::Gradient: + // For chessboard or gradient, we can't use a single clear value + // Instead, we should use a compute shader or multiple draw calls + SLANG_ASSERT(!"ChessBoard or Gradient content type is not supported for " + "multisampled textures - requires compute shader implementation"); + return SLANG_FAIL; + } + commandEncoder->clearTextureUint(texture, range, clearValue); + break; + } + case FormatKind::Normalized: + { + int32_t clearValue[4] = {0, 0, 0, 0}; + switch (content) + { + case InputTextureContent::Zero: + // clearValue is already all zeros + break; + case InputTextureContent::One: + clearValue[0] = clearValue[1] = clearValue[2] = clearValue[3] = 1; + break; + case InputTextureContent::ChessBoard: + case InputTextureContent::Gradient: + // For chessboard or gradient, we can't use a single clear value + // Instead, we should use a compute shader or multiple draw calls + SLANG_ASSERT(!"ChessBoard or Gradient content type is not supported for " + "multisampled textures - requires compute shader implementation"); + return SLANG_FAIL; + } + commandEncoder->clearTextureSint(texture, range, clearValue); + break; + } + case FormatKind::DepthStencil: + { + float depthValue = 0.f; + uint8_t stencilValue = 0U; + switch (content) + { + case InputTextureContent::Zero: + // clearValue is already all zeros + break; + case InputTextureContent::One: + depthValue = 1; + stencilValue = 1U; + break; + case InputTextureContent::ChessBoard: + case InputTextureContent::Gradient: + // For chessboard or gradient, we can't use a single clear value + // Instead, we should use a compute shader or multiple draw calls + SLANG_ASSERT(!"ChessBoard or Gradient content type is not supported for " + "multisampled textures - requires compute shader implementation"); + return SLANG_FAIL; + } + commandEncoder + ->clearTextureDepthStencil(texture, range, true, depthValue, true, stencilValue); + break; + } + default: + { + SLANG_ASSERT(!"Unsupported FormatKind type"); + return SLANG_FAIL; + } + } + + SLANG_RETURN_ON_FAIL(queue->submit(commandEncoder->finish())); + + return SLANG_OK; +} + static SamplerDesc _calcSamplerDesc(const InputSamplerDesc& srcDesc) { SamplerDesc samplerDesc; @@ -205,6 +344,9 @@ static SamplerDesc _calcSamplerDesc(const InputSamplerDesc& srcDesc) samplerDesc.reductionOp = TextureReductionOp::Comparison; samplerDesc.comparisonFunc = ComparisonFunc::Less; } + samplerDesc.minFilter = srcDesc.filteringMode; + samplerDesc.magFilter = srcDesc.filteringMode; + samplerDesc.mipFilter = srcDesc.filteringMode; return samplerDesc; } diff --git a/tools/render-test/shader-renderer-util.h b/tools/render-test/shader-renderer-util.h index bf0569988..257b41039 100644 --- a/tools/render-test/shader-renderer-util.h +++ b/tools/render-test/shader-renderer-util.h @@ -39,6 +39,12 @@ struct ShaderRendererUtil const void* initData, IDevice* device, ComPtr<IBuffer>& bufferOut); + + /// Clear a texture with the specified content + static Slang::Result clearTexture( + ITexture* texture, + InputTextureContent content, + IDevice* device); }; } // namespace renderer_test |
