diff options
| author | Yong He <yonghe@outlook.com> | 2025-01-24 21:39:13 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-24 21:39:13 -0800 |
| commit | 3ecbeacd3b02e2a8c1b9796df1caced0aa34224f (patch) | |
| tree | 6e8ddd208082ca042a7ebac2f5125337b4216a13 /source | |
| parent | a7958afa5ace2c92e10e1765a5bc33c891d09079 (diff) | |
Fix depth texture sampling on Metal. (#6168)
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/hlsl.meta.slang | 174 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-emit-metal.cpp | 16 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-metal-legalize.cpp | 12 | ||||
| -rw-r--r-- | source/slang/slang-ir.cpp | 1 |
6 files changed, 130 insertions, 77 deletions
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 97e2c7be5..ba5c95a0c 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -855,6 +855,10 @@ float __glsl_texture_level_offset_1d_shadow<TTexture, TCoord, TOffset>(TTexture } } +__intrinsic_op($(kIROp_MetalCastToDepthTexture)) +__generic<T:ITexelElement, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let access:int, let isShadow:int, let isCombined:int, let format:int> +_Texture<T,Shape,isArray,isMS,sampleCount,access,1,isCombined,format> __metal_asDepthTexture(_Texture<T,Shape,isArray,isMS,sampleCount,access,isShadow,isCombined,format> tex); + //@public: __generic<T:ITexelElement, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let isShadow:int, let format:int> @@ -1676,6 +1680,96 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,access,isShadow,0,format> } } } +__generic<T:ITexelElement, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let format:int> +float __metal_SampleCmp(_Texture<T,Shape,isArray,isMS,sampleCount,0,1,0,format> t, SamplerComparisonState s, vector<float, Shape.dimensions+isArray> location, float compareValue) +{ + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3)"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "$0.sample_compare($1, ($2).xyz, uint(($2).w), $3)"; + } + } + else + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_2D): + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm ".sample_compare"; + } + } + __intrinsic_asm "<invalid intrinsic>"; +} +__generic<T:ITexelElement, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let format:int> +float __metal_SampleCmp(_Texture<T,Shape,isArray,isMS,sampleCount,0,1,0,format> t, SamplerComparisonState s, vector<float, Shape.dimensions+isArray> location, float compareValue, constexpr vector<int, Shape.planeDimensions> offset) +{ + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3, $4)"; + } + } + else + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "$0.sample_compare($1, $2, $3, $4)"; + } + } + __intrinsic_asm "<invalid intrinsic>"; +} + +__generic<T:ITexelElement, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let format:int> +float __metal_SampleCmpLevel(_Texture<T,Shape,isArray,isMS,sampleCount,0,1,0,format> t, SamplerComparisonState s, vector<float, Shape.dimensions+isArray> location, float compareValue, float level) +{ + if (isArray == 1) + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_2D): + __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3, level($4))"; + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "$0.sample_compare($1, ($2).xyz, uint(($2).w), $3, level($4))"; + } + } + else + { + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_2D): + case $(SLANG_TEXTURE_CUBE): + __intrinsic_asm "$0.sample_compare($1, $2, $3, level($4))"; + } + } + __intrinsic_asm "<invalid intrinsic>"; +} +__generic<T:ITexelElement, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let format:int> +float __metal_SampleCmpLevel(_Texture<T,Shape,isArray,isMS,sampleCount,0,1,0,format> t, SamplerComparisonState s, vector<float, Shape.dimensions+isArray> location, float compareValue, float level, constexpr vector<int, Shape.planeDimensions> offset) +{ + switch (Shape.flavor) + { + case $(SLANG_TEXTURE_2D): + if (isArray == 1) + { + // T sample_compare(sampler s, float2 coord, uint array, float compare_value, lod_options options, int2 offset = int2(0)) const + __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3, level($4), $5)"; + } + else + { + // T sample_compare(sampler s, float2 coord, float compare_value, lod_options options, int2 offset = int2(0)) const + __intrinsic_asm "$0.sample_compare($1, $2, $3, level($4), $5)"; + } + break; + } + __intrinsic_asm "<invalid intrinsic>"; +} __generic<T:ITexelElement, Shape: __ITextureShape, let isArray:int, let isMS:int, let sampleCount:int, let isShadow:int, let format:int> extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> @@ -2082,26 +2176,7 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> , "HLSL supports only float and half type textures"); __intrinsic_asm ".SampleCmp"; case metal: - if (isArray == 1) - { - switch (Shape.flavor) - { - case $(SLANG_TEXTURE_2D): - __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3)"; - case $(SLANG_TEXTURE_CUBE): - __intrinsic_asm "$0.sample_compare($1, ($2).xyz, uint(($2).w), $3)"; - } - } - else - { - switch (Shape.flavor) - { - case $(SLANG_TEXTURE_2D): - case $(SLANG_TEXTURE_CUBE): - __intrinsic_asm ".sample_compare"; - } - } - __intrinsic_asm "<invalid intrinsic>"; + return __metal_SampleCmp(__metal_asDepthTexture(this), s, location, compareValue); case spirv: return spirv_asm { @@ -2183,23 +2258,7 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> , "HLSL supports only float and half type textures"); __intrinsic_asm ".SampleCmp"; case metal: - if (isArray == 1) - { - switch (Shape.flavor) - { - case $(SLANG_TEXTURE_2D): - __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3, $4)"; - } - } - else - { - switch (Shape.flavor) - { - case $(SLANG_TEXTURE_2D): - __intrinsic_asm ".sample_compare"; - } - } - __intrinsic_asm "<invalid intrinsic>"; + return __metal_SampleCmp(__metal_asDepthTexture(this), s, location, compareValue, offset); case spirv: return spirv_asm { @@ -2311,26 +2370,7 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> , "HLSL supports only float and half type textures"); __intrinsic_asm ".SampleCmpLevel"; case metal: - if (isArray == 1) - { - switch (Shape.flavor) - { - case $(SLANG_TEXTURE_2D): - __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3, level($4))"; - case $(SLANG_TEXTURE_CUBE): - __intrinsic_asm "$0.sample_compare($1, ($2).xyz, uint(($2).w), $3, level($4))"; - } - } - else - { - switch (Shape.flavor) - { - case $(SLANG_TEXTURE_2D): - case $(SLANG_TEXTURE_CUBE): - __intrinsic_asm "$0.sample_compare($1, $2, $3, level($4))"; - } - } - __intrinsic_asm "<invalid intrinsic>"; + return __metal_SampleCmpLevel(__metal_asDepthTexture(this), s, location, compareValue, level); case spirv: return spirv_asm { @@ -2362,25 +2402,7 @@ extension _Texture<T,Shape,isArray,isMS,sampleCount,0,isShadow,0,format> , "HLSL supports only float and half type textures"); __intrinsic_asm ".SampleCmpLevel"; case metal: - if (isShadow == 1) - { - switch (Shape.flavor) - { - case $(SLANG_TEXTURE_2D): - if (isArray == 1) - { - // T sample_compare(sampler s, float2 coord, uint array, float compare_value, lod_options options, int2 offset = int2(0)) const - __intrinsic_asm "$0.sample_compare($1, ($2).xy, uint(($2).z), $3, level($4), $5)"; - } - else - { - // T sample_compare(sampler s, float2 coord, float compare_value, lod_options options, int2 offset = int2(0)) const - __intrinsic_asm "$0.sample_compare($1, $2, $3, level($4), $5)"; - } - break; - } - } - __intrinsic_asm "<invalid intrinsic>"; + return __metal_SampleCmpLevel(__metal_asDepthTexture(this), s, location, compareValue, level, offset); case spirv: return spirv_asm { diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index ac548e354..98bddad9b 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -1413,6 +1413,7 @@ bool CLikeSourceEmitter::shouldFoldInstIntoUseSites(IRInst* inst) // or statement). case kIROp_UpdateElement: case kIROp_DefaultConstruct: + case kIROp_MetalCastToDepthTexture: return false; // Always fold these in, because they are trivial @@ -3129,6 +3130,7 @@ void CLikeSourceEmitter::_emitInst(IRInst* inst) case kIROp_AtomicCompareExchange: case kIROp_StructuredBufferGetDimensions: case kIROp_MetalAtomicCast: + case kIROp_MetalCastToDepthTexture: emitInstStmt(inst); break; diff --git a/source/slang/slang-emit-metal.cpp b/source/slang/slang-emit-metal.cpp index 5e4381d21..166f02535 100644 --- a/source/slang/slang-emit-metal.cpp +++ b/source/slang/slang-emit-metal.cpp @@ -636,6 +636,22 @@ bool MetalSourceEmitter::tryEmitInstStmtImpl(IRInst* inst) m_writer->emit(");\n"); return true; } + case kIROp_MetalCastToDepthTexture: + { + emitType(inst->getDataType(), getName(inst)); + m_writer->emit(";\n{\n"); + m_writer->indent(); + m_writer->emit("auto _slang_ordinary_texture = "); + emitOperand(inst->getOperand(0), getInfo(EmitOp::General)); + m_writer->emit(";\n"); + m_writer->emit(getName(inst)); + m_writer->emit(" = *("); + emitType(inst->getDataType()); + m_writer->emit(" thread*)(&_slang_ordinary_texture);\n"); + m_writer->dedent(); + m_writer->emit("}\n"); + return true; + } } return false; } diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index 179e3a5f4..591ffabf0 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -555,6 +555,8 @@ INST(MetalSetVertex, metalSetVertex, 2, 0) INST(MetalSetPrimitive, metalSetPrimitive, 2, 0) INST(MetalSetIndices, metalSetIndices, 2, 0) +INST(MetalCastToDepthTexture, MetalCastToDepthTexture, 1, 0) + // Construct a vector from a scalar // // %dst = MakeVectorFromScalar %T %N %val diff --git a/source/slang/slang-ir-metal-legalize.cpp b/source/slang/slang-ir-metal-legalize.cpp index 0d58bdd14..e9f693622 100644 --- a/source/slang/slang-ir-metal-legalize.cpp +++ b/source/slang/slang-ir-metal-legalize.cpp @@ -206,7 +206,17 @@ static void processInst(IRInst* inst) case kIROp_Leq: legalizeBinaryOp(inst); break; - + case kIROp_MetalCastToDepthTexture: + { + // If the operand is already a depth texture, don't do anything. + auto textureType = as<IRTextureTypeBase>(inst->getOperand(0)->getDataType()); + if (textureType && getIntVal(textureType->getIsShadowInst()) == 1) + { + inst->replaceUsesWith(inst->getOperand(0)); + inst->removeAndDeallocate(); + } + break; + } default: for (auto child : inst->getModifiableChildren()) { diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index ac51ae451..a328057ac 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -8248,6 +8248,7 @@ bool IRInst::mightHaveSideEffects(SideEffectAnalysisOptions options) case kIROp_GetArrayLength: case kIROp_ResolveVaryingInputRef: case kIROp_GetPerVertexInputArray: + case kIROp_MetalCastToDepthTexture: return false; case kIROp_ForwardDifferentiate: |
