From 3e950e11f46fa3d2a84f04345ea860907ae9715a Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Mon, 23 Sep 2024 16:32:47 -0700 Subject: Implemented Combined-texture for WGSL (#5130) * Implemented Combined-texture for WGSL * Remove unnecessary comment * Limit to std430 layout * Fix compiler warning for unused variable --------- Co-authored-by: Yong He --- source/slang/slang-compiler.cpp | 1 + source/slang/slang-emit.cpp | 3 +- .../slang-ir-lower-combined-texture-sampler.cpp | 28 +- .../slang-ir-lower-combined-texture-sampler.h | 2 + source/slang/slang-type-layout.cpp | 120 ++++++- tests/wgsl/texture-sampler-less.slang | 393 +++++++++++++++++++++ 6 files changed, 537 insertions(+), 10 deletions(-) create mode 100644 tests/wgsl/texture-sampler-less.slang diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index c89d94c80..1f962d625 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -547,6 +547,7 @@ namespace Slang case CodeGenTarget::PyTorchCppBinding: case CodeGenTarget::CSource: case CodeGenTarget::Metal: + case CodeGenTarget::WGSL: { return PassThroughMode::None; } diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 6e3556064..71ef7ee33 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -973,8 +973,9 @@ Result linkAndOptimizeIR( case CodeGenTarget::Metal: case CodeGenTarget::MetalLib: case CodeGenTarget::MetalLibAssembly: + case CodeGenTarget::WGSL: if (requiredLoweringPassSet.combinedTextureSamplers) - lowerCombinedTextureSamplers(irModule, sink); + lowerCombinedTextureSamplers(codeGenContext, irModule, sink); break; } diff --git a/source/slang/slang-ir-lower-combined-texture-sampler.cpp b/source/slang/slang-ir-lower-combined-texture-sampler.cpp index b6f65c933..656bd84a6 100644 --- a/source/slang/slang-ir-lower-combined-texture-sampler.cpp +++ b/source/slang/slang-ir-lower-combined-texture-sampler.cpp @@ -19,6 +19,7 @@ namespace Slang struct LowerCombinedSamplerContext { Dictionary mapTypeToLoweredInfo; + CodeGenTarget codeGenTarget; LoweredCombinedSamplerStructInfo lowerCombinedTextureSamplerType(IRTextureTypeBase* textureType) { @@ -57,8 +58,16 @@ namespace Slang builder.createStructField(structType, info.sampler, info.samplerType); // Type layout. - - auto textureResourceKind = isMutable ? LayoutResourceKind::UnorderedAccess : LayoutResourceKind::ShaderResource; + + bool isWGSLTarget = codeGenTarget == CodeGenTarget::WGSL; + LayoutResourceKind textureResourceKind = isMutable ? LayoutResourceKind::UnorderedAccess : LayoutResourceKind::ShaderResource; + LayoutResourceKind samplerResourceKind = LayoutResourceKind::SamplerState; + if (isWGSLTarget) + { + textureResourceKind = LayoutResourceKind::DescriptorTableSlot; + samplerResourceKind = LayoutResourceKind::DescriptorTableSlot; + } + IRTypeLayout::Builder textureTypeLayoutBuilder(&builder); textureTypeLayoutBuilder.addResourceUsage( textureResourceKind, @@ -67,7 +76,7 @@ namespace Slang IRTypeLayout::Builder samplerTypeLayoutBuilder(&builder); samplerTypeLayoutBuilder.addResourceUsage( - LayoutResourceKind::SamplerState, + samplerResourceKind, LayoutSize(1)); auto samplerTypeLayout = samplerTypeLayoutBuilder.build(); @@ -76,7 +85,7 @@ namespace Slang auto textureVarLayout = textureVarLayoutBuilder.build(); IRVarLayout::Builder samplerVarLayoutBuilder(&builder, samplerTypeLayout); - samplerVarLayoutBuilder.findOrAddResourceInfo(LayoutResourceKind::SamplerState)->offset = 0; + samplerVarLayoutBuilder.findOrAddResourceInfo(samplerResourceKind)->offset = isWGSLTarget ? 1 : 0; auto samplerVarLayout = samplerVarLayoutBuilder.build(); IRStructTypeLayout::Builder layoutBuilder(&builder); @@ -91,12 +100,14 @@ namespace Slang }; void lowerCombinedTextureSamplers( + CodeGenContext* codeGenContext, IRModule* module, DiagnosticSink* sink) { SLANG_UNUSED(sink); LowerCombinedSamplerContext context; + context.codeGenTarget = codeGenContext->getTargetFormat(); // Lower combined texture sampler type into a struct type. for (auto globalInst : module->getGlobalInsts()) @@ -127,12 +138,13 @@ namespace Slang for (auto offsetAttr : varLayout->getOffsetAttrs()) { - if (offsetAttr->getResourceKind() == LayoutResourceKind::UnorderedAccess || - offsetAttr->getResourceKind() == LayoutResourceKind::ShaderResource) + LayoutResourceKind resKind = offsetAttr->getResourceKind(); + if (resKind == LayoutResourceKind::UnorderedAccess || + resKind == LayoutResourceKind::ShaderResource) resOffsetAttr = offsetAttr; - else if (offsetAttr->getResourceKind() == LayoutResourceKind::DescriptorTableSlot) + else if (resKind == LayoutResourceKind::DescriptorTableSlot) descriptorTableSlotOffsetAttr = offsetAttr; - auto info = newVarLayoutBuilder.findOrAddResourceInfo(offsetAttr->getResourceKind()); + auto info = newVarLayoutBuilder.findOrAddResourceInfo(resKind); info->offset = offsetAttr->getOffset(); info->space = offsetAttr->getSpace(); info->kind = offsetAttr->getResourceKind(); diff --git a/source/slang/slang-ir-lower-combined-texture-sampler.h b/source/slang/slang-ir-lower-combined-texture-sampler.h index ccd448786..2cc3d4f75 100644 --- a/source/slang/slang-ir-lower-combined-texture-sampler.h +++ b/source/slang/slang-ir-lower-combined-texture-sampler.h @@ -4,11 +4,13 @@ namespace Slang { + struct CodeGenContext; struct IRModule; class DiagnosticSink; // Lower combined texture sampler types to structs. void lowerCombinedTextureSamplers( + CodeGenContext* codeGenContext, IRModule* module, DiagnosticSink* sink ); diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index 57635122e..1fb8b57ab 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -896,6 +896,25 @@ struct HLSLObjectLayoutRulesImpl : ObjectLayoutRulesImpl }; HLSLObjectLayoutRulesImpl kHLSLObjectLayoutRulesImpl; +struct WGSLObjectLayoutRulesImpl : GLSLObjectLayoutRulesImpl +{ + virtual ObjectLayoutInfo GetObjectLayout(ShaderParameterKind kind, const Options& options) override + { + ObjectLayoutInfo info = GLSLObjectLayoutRulesImpl::GetObjectLayout(kind, options); + + switch (kind) + { + case ShaderParameterKind::TextureSampler: + case ShaderParameterKind::MutableTextureSampler: + info.layoutInfos.add(SimpleLayoutInfo(LayoutResourceKind::DescriptorTableSlot, 1)); + break; + } + + return info; + } +}; +WGSLObjectLayoutRulesImpl kWGSLObjectLayoutRulesImpl; + // HACK: Treating ray-tracing input/output as if it was another // case of varying input/output when it really needs to be // based on byte storage/layout. @@ -1053,11 +1072,32 @@ struct MetalLayoutRulesFamilyImpl : LayoutRulesFamilyImpl LayoutRulesImpl* getStructuredBufferRules(CompilerOptionSet& compilerOptions) override; }; +struct WGSLLayoutRulesFamilyImpl : LayoutRulesFamilyImpl +{ + virtual LayoutRulesImpl* getAnyValueRules() override; + virtual LayoutRulesImpl* getConstantBufferRules(CompilerOptionSet& compilerOptions) override; + virtual LayoutRulesImpl* getPushConstantBufferRules() override; + virtual LayoutRulesImpl* getTextureBufferRules(CompilerOptionSet& compilerOptions) override; + virtual LayoutRulesImpl* getVaryingInputRules() override; + virtual LayoutRulesImpl* getVaryingOutputRules() override; + virtual LayoutRulesImpl* getSpecializationConstantRules() override; + virtual LayoutRulesImpl* getShaderStorageBufferRules(CompilerOptionSet& compilerOptions) override; + virtual LayoutRulesImpl* getParameterBlockRules(CompilerOptionSet& compilerOptions) override; + + LayoutRulesImpl* getRayPayloadParameterRules() override; + LayoutRulesImpl* getCallablePayloadParameterRules() override; + LayoutRulesImpl* getHitAttributesParameterRules() override; + + LayoutRulesImpl* getShaderRecordConstantBufferRules() override; + LayoutRulesImpl* getStructuredBufferRules(CompilerOptionSet& compilerOptions) override; +}; + GLSLLayoutRulesFamilyImpl kGLSLLayoutRulesFamilyImpl; HLSLLayoutRulesFamilyImpl kHLSLLayoutRulesFamilyImpl; CPULayoutRulesFamilyImpl kCPULayoutRulesFamilyImpl; CUDALayoutRulesFamilyImpl kCUDALayoutRulesFamilyImpl; MetalLayoutRulesFamilyImpl kMetalLayoutRulesFamilyImpl; +WGSLLayoutRulesFamilyImpl kWGSLLayoutRulesFamilyImpl; // CPU case @@ -1816,6 +1856,82 @@ LayoutRulesImpl* MetalLayoutRulesFamilyImpl::getHitAttributesParameterRules() return nullptr; } +// WGSL Family + +LayoutRulesImpl kWGSLConstantBufferLayoutRulesImpl_ = { + &kWGSLLayoutRulesFamilyImpl, &kStd140LayoutRulesImpl, &kWGSLObjectLayoutRulesImpl, +}; + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getAnyValueRules() +{ + return &kGLSLAnyValueLayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getConstantBufferRules(CompilerOptionSet&) +{ + return &kWGSLConstantBufferLayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getParameterBlockRules(CompilerOptionSet&) +{ + return &kStd140LayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getPushConstantBufferRules() +{ + return &kGLSLPushConstantLayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getShaderRecordConstantBufferRules() +{ + return &kGLSLShaderRecordLayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getTextureBufferRules(CompilerOptionSet&) +{ + return &kStd430LayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getVaryingInputRules() +{ + return &kGLSLVaryingInputLayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getVaryingOutputRules() +{ + return &kGLSLVaryingOutputLayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getSpecializationConstantRules() +{ + return &kGLSLSpecializationConstantLayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getShaderStorageBufferRules(CompilerOptionSet&) +{ + return &kStd430LayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getRayPayloadParameterRules() +{ + return &kGLSLRayPayloadParameterLayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getCallablePayloadParameterRules() +{ + return &kGLSLCallablePayloadParameterLayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getHitAttributesParameterRules() +{ + return &kGLSLHitAttributesParameterLayoutRulesImpl_; +} + +LayoutRulesImpl* WGSLLayoutRulesFamilyImpl::getStructuredBufferRules(CompilerOptionSet&) +{ + return &kGLSLStructuredBufferLayoutRulesImpl_; +} + LayoutRulesFamilyImpl* getDefaultLayoutRulesFamilyForTarget(TargetRequest* targetReq) { @@ -1831,9 +1947,11 @@ LayoutRulesFamilyImpl* getDefaultLayoutRulesFamilyForTarget(TargetRequest* targe case CodeGenTarget::GLSL: case CodeGenTarget::SPIRV: case CodeGenTarget::SPIRVAssembly: - case CodeGenTarget::WGSL: return &kGLSLLayoutRulesFamilyImpl; + case CodeGenTarget::WGSL: + return &kWGSLLayoutRulesFamilyImpl; + case CodeGenTarget::HostHostCallable: case CodeGenTarget::ShaderHostCallable: case CodeGenTarget::HostExecutable: diff --git a/tests/wgsl/texture-sampler-less.slang b/tests/wgsl/texture-sampler-less.slang new file mode 100644 index 000000000..1a6cb5341 --- /dev/null +++ b/tests/wgsl/texture-sampler-less.slang @@ -0,0 +1,393 @@ +// WGSL supports "textureSample()" only in fragment shader +//TEST:SIMPLE(filecheck=WGSL): -stage fragment -entry fragMain -target wgsl + +// TODO: offset variants requires the offset value to be compile-time constant +// But the keyword, `constexpr`, doesn't seem to work for the combined-textures +#define TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET 0 + +//WGSL:@binding(0) {{.*}}t1D_f32v3{{.*}} : texture_1d; +//WGSL:@binding(1) {{.*}}t1D_f32v3{{.*}} : sampler; +//TEST_INPUT: TextureSampler1D(size=4, content = zero):name t1D_f32v3 +Sampler1D t1D_f32v3; + +//WGSL:@binding(2) {{.*}}t2D_f32v3{{.*}} : texture_2d; +//WGSL:@binding(3) {{.*}}t2D_f32v3{{.*}} : sampler; +//TEST_INPUT: TextureSampler2D(size=4, content = zero):name t2D_f32v3 +Sampler2D t2D_f32v3; + +//TEST_INPUT: TextureSampler3D(size=4, content = zero):name t3D_f32v3 +Sampler3D t3D_f32v3; +//TEST_INPUT: TextureSamplerCube(size=4, content = zero):name tCube_f32v3 +SamplerCube tCube_f32v3; + +//TEST_INPUT: TextureSampler1D(size=4, content = zero, arrayLength=2):name t1DArray_f32v3 +Sampler1DArray t1DArray_f32v3; +//TEST_INPUT: TextureSampler2D(size=4, content = zero, arrayLength=2):name t2DArray_f32v3 +Sampler2DArray t2DArray_f32v3; +//TEST_INPUT: TextureSamplerCube(size=4, content = zero, arrayLength=2):name tCubeArray_f32v3 +SamplerCubeArray tCubeArray_f32v3; + +//TEST_INPUT: TextureSampler1D(size=4, content = zero):name t1D_f32v4 +Sampler1D t1D_f32v4; +//TEST_INPUT: TextureSampler2D(size=4, content = zero):name t2D_f32v4 +Sampler2D t2D_f32v4; +//TEST_INPUT: TextureSampler3D(size=4, content = zero):name t3D_f32v4 +Sampler3D t3D_f32v4; +//TEST_INPUT: TextureSamplerCube(size=4, content = zero):name tCube_f32v4 +SamplerCube tCube_f32v4; + +//TEST_INPUT: TextureSampler1D(size=4, content = zero, arrayLength=2):name t1DArray_f32v4 +Sampler1DArray t1DArray_f32v4; +//TEST_INPUT: TextureSampler2D(size=4, content = zero, arrayLength=2):name t2DArray_f32v4 +Sampler2DArray t2DArray_f32v4; +//TEST_INPUT: TextureSamplerCube(size=4, content = zero, arrayLength=2):name tCubeArray_f32v4 +SamplerCubeArray tCubeArray_f32v4; + +__generic +typealias CombinedDepth2d = __TextureImpl< + T, + __Shape2D, + 0, // isArray + 0, // isMS + sampleCount, + 0, // access + 1, // isShadow + 1, // isCombined + format +>; + +__generic +typealias CombinedDepth2d_array = __TextureImpl< + T, + __Shape2D, + 1, // isArray + 0, // isMS + sampleCount, + 0, // access + 1, // isShadow + 1, // isCombined + format +>; + +__generic +typealias CombinedDepthcube = __TextureImpl< + T, + __ShapeCube, + 0, // isArray + 0, // isMS + sampleCount, + 0, // access + 1, // isShadow + 1, // isCombined + format +>; + +__generic +typealias CombinedDepthcube_array = __TextureImpl< + T, + __ShapeCube, + 1, // isArray + 0, // isMS + sampleCount, + 0, // access + 1, // isShadow + 1, // isCombined + format +>; + +//TEST_INPUT: TextureSampler2D(size=4, content = zero):name d2D +CombinedDepth2d d2D; +//TEST_INPUT: TextureSamplerCube(size=4, content = zero):name dCube +CombinedDepthcube dCube; +//TEST_INPUT: TextureSampler2D(size=4, content = zero, arrayLength=2):name d2DArray +CombinedDepth2d_array d2DArray; +//TEST_INPUT: TextureSamplerCube(size=4, content = zero, arrayLength=2):name dCubeArray +CombinedDepthcube_array dCubeArray; + +//TEST_INPUT: ubuffer(data=[0], stride=4):out,name outputBuffer +RWStructuredBuffer outputBuffer; + + +__generic +bool TEST_texture( + Sampler1D> t1D, + Sampler2D> t2D, + Sampler3D> t3D, + SamplerCube> tCube, + Sampler1DArray> t1DArray, + Sampler2DArray> t2DArray, + SamplerCubeArray> tCubeArray +) +{ + // WGSL-LABEL: TEST_texture + typealias Tvn = vector; + typealias Tv4 = vector; + + float u = 0; + float u2 = 0.5; + constexpr const float ddx = 0.0f; + constexpr const float ddy = 0.0f; + + bool result = true + // =============================== + // float CalculateLevelOfDetail() + // =============================== + // WGSL doesn't have a way to calculate mip-map level for the given coordinate + + // ======================================== + // float CalculateLevelOfDetailUnclamped() + // ======================================== + // WGSL doesn't have a way to calculate mip-map level for the given coordinate + + // =========== + // T Sample() + // https://www.w3.org/TR/WGSL/#texturesample + // =========== + + // WGSL: textureSample({{\(*}}t1D + && all(Tvn(T(0)) == t1D.Sample(u)) + + // WGSL: textureSample({{\(*}}t2D + && all(Tvn(T(0)) == t2D.Sample(float2(u, u))) + + // WGSL: textureSample({{\(*}}t3D + && all(Tvn(T(0)) == t3D.Sample(float3(u, u, u))) + + // WGSL: textureSample({{\(*}}tCube + && all(Tvn(T(0)) == tCube.Sample(normalize(float3(u, 1 - u, u)))) + + // WGSL doesn't support textureSample for 1d_array and 3d_array; only 2d and cube + + // WGSL: textureSample({{\(*}}t2DArray + && all(Tvn(T(0)) == t2DArray.Sample(float3(u, u, 0))) + + // WGSL: textureSample({{\(*}}tCubeArray + && all(Tvn(T(0)) == tCubeArray.Sample(float4(normalize(float3(u, 1 - u, u)), 0))) + +#if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + // Offset variant + + // WGSL: textureSample({{\(*}}t1D + && all(Tvn(T(0)) == t1D.Sample(u, 1)) + + // WGSL: textureSample({{\(*}}t2D + && all(Tvn(T(0)) == t2D.Sample(float2(u, u), int2(1, 1))) + + // WGSL: textureSample({{\(*}}t3D + && all(Tvn(T(0)) == t3D.Sample(float3(u, u, u), int3(1, 1, 1))) + + // WGSL doesn't support offset variant for cube and cube_array + + // WGSL: textureSample({{\(*}}t2DArray + && all(Tvn(T(0)) == t2DArray.Sample(float3(u, u, 0), int2(1, 1))) +#endif // #if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + + // =============== + // T SampleBias() + // https://www.w3.org/TR/WGSL/#texturesamplebias + // =============== + + // WGSL doesn't support Bias for 1D texture + + // WGSL: textureSampleBias({{\(*}}t2D + && all(Tvn(T(0)) == t2D.SampleBias(float2(u, u), float(-1))) + + // WGSL: textureSampleBias({{\(*}}t3D + && all(Tvn(T(0)) == t3D.SampleBias(float3(u, u, u), float(-1))) + + // WGSL: textureSampleBias({{\(*}}tCube + && all(Tvn(T(0)) == tCube.SampleBias(normalize(float3(u, 1 - u, u)), float(-1))) + + // WGSL: textureSampleBias({{\(*}}t2DArray + && all(Tvn(T(0)) == t2DArray.SampleBias(float3(u, u, 0), float(-1))) + + // WGSL: textureSampleBias({{\(*}}tCubeArray + && all(Tvn(T(0)) == tCubeArray.SampleBias(float4(normalize(float3(u, 1 - u, u)), 0), float(-1))) + +#if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + // Offset variant + + // W-GSL: textureSampleBias({{\(*}}t2D + && all(Tvn(T(0)) == t2D.SampleBias(float2(u, u), float(-1), int2(1, 1))) + + // W-GSL: textureSampleBias({{\(*}}t3D + && all(Tvn(T(0)) == t3D.SampleBias(float3(u, u, u), float(-1), int3(1, 1, 1))) + + // W-GSL: textureSampleBias({{\(*}}t2DArray + && all(Tvn(T(0)) == t2DArray.SampleBias(float3(u, u, 0), float(-1), int2(1, 1))) +#endif // #if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + + // =================================== + // T SampleLevel() + // https://www.w3.org/TR/WGSL/#texturesamplelevel + // =================================== + + // WGSL doesn't support textureSampleLevel for 1D texture + + // WGSL: textureSampleLevel({{\(*}}t2D + && all(Tvn(T(0)) == t2D.SampleLevel(float2(u, u), 0)) + + // WGSL: textureSampleLevel({{\(*}}t3D + && all(Tvn(T(0)) == t3D.SampleLevel(float3(u, u, u), 0)) + + // WGSL: textureSampleLevel({{\(*}}tCube + && all(Tvn(T(0)) == tCube.SampleLevel(normalize(float3(u, 1 - u, u)), 0)) + + // WGSL: textureSampleLevel({{\(*}}t2DArray + && all(Tvn(T(0)) == t2DArray.SampleLevel(float3(u, u, 0), 0)) + + // WGSL: textureSampleLevel({{\(*}}tCubeArray + && all(Tvn(T(0)) == tCubeArray.SampleLevel(float4(normalize(float3(u, 1 - u, u)), 0), 0)) + +#if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + // Offset variant + + // W-GSL: textureSampleLevel({{\(*}}t2D + && all(Tvn(T(0)) == t2D.SampleLevel(float2(u, u), 0, int2(1, 1))) + + // W-GSL: textureSampleLevel({{\(*}}t3D + && all(Tvn(T(0)) == t3D.SampleLevel(float3(u, u, u), 0, int3(1, 1, 1))) + + // W-GSL: textureSampleLevel({{\(*}}t2DArray + && all(Tvn(T(0)) == t2DArray.SampleLevel(float3(u, u, 0), 0, int2(1, 1))) +#endif // #if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + + // ================== + // float SampleCmp() + // https://www.w3.org/TR/WGSL/#texturesamplecompare + // ================== + + // WGSL: textureSampleCompare({{\(*}}d2D + && float(0) == d2D.SampleCmp(float2(u, u), 0) + + // WGSL: textureSampleCompare({{\(*}}d2DArray + && float(0) == d2DArray.SampleCmp(float3(u, u, 0), 0) + + // WGSL: textureSampleCompare({{\(*}}dCube + && float(0) == dCube.SampleCmp(normalize(float3(u, 1 - u, u)), 0) + + // WGSL: textureSampleCompare({{\(*}}dCubeArray + && float(0) == dCubeArray.SampleCmp(float4(normalize(float3(u, 1 - u, u)), 0), 0) + +#if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + // Offset variant + + // W-GSL: textureSampleCompare({{\(*}}d2D + && float(0) == d2D.SampleCmp(float2(u2, u), 0, int2(0, 0)) + + // W-GSL: textureSampleCompare({{\(*}}d2DArray + && float(0) == d2DArray.SampleCmp(float3(u2, u, u), 0, int2(0, 0)) +#endif // #if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + + // =================================== + // float SampleCmpLevelZero() + // https://www.w3.org/TR/WGSL/#texturesamplecomparelevel + // =================================== + + // WGSL: textureSampleCompareLevel({{\(*}}d2D + && float(0) == d2D.SampleCmpLevelZero(float2(u, u), 0) + + // WGSL: textureSampleCompareLevel({{\(*}}d2DArray + && float(0) == d2DArray.SampleCmpLevelZero(float3(u, u, 0), 0) + + // WGSL: textureSampleCompareLevel({{\(*}}dCube + && float(0) == dCube.SampleCmpLevelZero(normalize(float3(u, 1 - u, u)), 0) + + // WGSL: textureSampleCompareLevel({{\(*}}dCubeArray + && float(0) == dCubeArray.SampleCmpLevelZero(float4(normalize(float3(u, 1-u, u)), 0), 0) + +#if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + // Offset variant + + // W-GSL: textureSampleCompareLevel({{\(*}}d2D + && float(0) == d2D.SampleCmpLevelZero(float2(u2, u), 0, int2(0, 0)) + + // W-GSL: textureSampleCompareLevel({{\(*}}d2DArray + && float(0) == d2DArray.SampleCmpLevelZero(float3(u2, u, u), 0, int2(0, 0)) +#endif // #if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + + // ================================== + // vector Gather() + // https://www.w3.org/TR/WGSL/#texturegather + // ================================== + +#if 0 + && all(Tv4(T(0)) == t2D.Gather(float2(u, u))) + + && all(Tv4(T(0)) == tCube.Gather(normalize(float3(u, 1 - u, u)))) + + && all(Tv4(T(0)) == t2DArray.Gather(float3(u, u, 0))) + + && all(Tv4(T(0)) == tCubeArray.Gather(float4(normalize(float3(u, 1 - u, u)), 0))) + +#if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + // Offset variant + + && all(Tv4(T(0)) == t2D.Gather(float2(u2, u), int2(0, 0))) + + && all(Tv4(T(0)) == t2DArray.Gather(float3(u2, u, 0), int2(0, 0))) +#endif // #if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET +#endif + + // ===================================== + // T SampleGrad() + // https://www.w3.org/TR/WGSL/#texturesamplegrad + // ===================================== + + // WGSL doesn't support textureSampleGrad for 1D textures + + // WGSL: textureSampleGrad({{\(*}}t2D + && all(Tvn(T(0)) == t2D.SampleGrad(float2(u, u), float2(ddx, ddx), float2(ddy, ddy))) + + // WGSL: textureSampleGrad({{\(*}}t3D + && all(Tvn(T(0)) == t3D.SampleGrad(float3(u, u, u), float3(ddx, ddx, ddx), float3(ddy, ddy, ddy))) + + // WGSL: textureSampleGrad({{\(*}}tCube + && all(Tvn(T(0)) == tCube.SampleGrad(normalize(float3(u, 1 - u, u)), float3(ddx, ddx, ddx), float3(ddy, ddy, ddy))) + + // WGSL: textureSampleGrad({{\(*}}t2DArray + && all(Tvn(T(0)) == t2DArray.SampleGrad(float3(u, u, 0.0f), float2(ddx, ddx), float2(ddy, ddy))) + + // WGSL: textureSampleGrad({{\(*}}tCubeArray + && all(Tvn(T(0)) == tCubeArray.SampleGrad(float4(normalize(float3(u, 1 - u, u)), 0), float3(ddx, ddx, ddx), float3(ddy, ddy, ddy))) + +#if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + // Offset variant + + // W-GSL: textureSampleGrad({{\(*}}t2D + && all(Tvn(T(0)) == t2D.SampleGrad(float2(u2, u), float2(ddx, ddx), float2(ddy, ddy), int2(0, 0))) + + // W-GSL: textureSampleGrad({{\(*}}t3D + && all(Tvn(T(0)) == t3D.SampleGrad(float3(u2, u, u), float3(ddx, ddx, ddx), float3(ddy, ddy, ddy), int3(0, 0, 0))) + + // W-GSL: textureSampleGrad({{\(*}}t2DArray + && all(Tvn(T(0)) == t2DArray.SampleGrad(float3(u2, u, 0.0f), float2(ddx, ddx), float2(ddy, ddy), int2(0, 0))) +#endif // #if TEST_WHEN_CONSTEXPR_WORKS_FOR_OFFSET + ; + + return result; +} + +void fragMain() +{ + bool result = true + && TEST_texture( + t1D_f32v3, + t2D_f32v3, + t3D_f32v3, + tCube_f32v3, + t1DArray_f32v3, + t2DArray_f32v3, + tCubeArray_f32v3) + && TEST_texture( + t1D_f32v4, + t2D_f32v4, + t3D_f32v4, + tCube_f32v4, + t1DArray_f32v4, + t2DArray_f32v4, + tCubeArray_f32v4) + ; + + outputBuffer[0] = int(result); +} -- cgit v1.2.3