diff --git a/lib/API/DX/Device.cpp b/lib/API/DX/Device.cpp index edfaccb7b..e83c0634a 100644 --- a/lib/API/DX/Device.cpp +++ b/lib/API/DX/Device.cpp @@ -236,6 +236,87 @@ static D3D12_RESOURCE_DIMENSION getDXDimension(ResourceKind RK) { llvm_unreachable("All cases handled"); } +static D3D12_TEXTURE_ADDRESS_MODE getDXAddressMode(AddressMode Mode) { + switch (Mode) { + case AddressMode::Clamp: + return D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + case AddressMode::Repeat: + return D3D12_TEXTURE_ADDRESS_MODE_WRAP; + case AddressMode::Mirror: + return D3D12_TEXTURE_ADDRESS_MODE_MIRROR; + case AddressMode::Border: + return D3D12_TEXTURE_ADDRESS_MODE_BORDER; + case AddressMode::MirrorOnce: + return D3D12_TEXTURE_ADDRESS_MODE_MIRROR_ONCE; + } + llvm_unreachable("All AddressMode cases handled"); +} + +static D3D12_COMPARISON_FUNC getDXComparisonFunc(CompareFunction Func) { + switch (Func) { + case CompareFunction::Never: + return D3D12_COMPARISON_FUNC_NEVER; + case CompareFunction::Less: + return D3D12_COMPARISON_FUNC_LESS; + case CompareFunction::Equal: + return D3D12_COMPARISON_FUNC_EQUAL; + case CompareFunction::LessEqual: + return D3D12_COMPARISON_FUNC_LESS_EQUAL; + case CompareFunction::Greater: + return D3D12_COMPARISON_FUNC_GREATER; + case CompareFunction::NotEqual: + return D3D12_COMPARISON_FUNC_NOT_EQUAL; + case CompareFunction::GreaterEqual: + return D3D12_COMPARISON_FUNC_GREATER_EQUAL; + case CompareFunction::Always: + return D3D12_COMPARISON_FUNC_ALWAYS; + } + llvm_unreachable("All CompareFunction cases handled"); +} + +// Compose a D3D12_FILTER from kind + min/mag (mip is Nearest to match VK). +static D3D12_FILTER getDXFilter(SamplerKind Kind, FilterMode MinFilter, + FilterMode MagFilter) { + const bool IsComparison = (Kind == SamplerKind::SamplerComparison); + const bool MinLinear = (MinFilter == FilterMode::Linear); + const bool MagLinear = (MagFilter == FilterMode::Linear); + D3D12_FILTER F; + if (!MinLinear && !MagLinear) + F = D3D12_FILTER_MIN_MAG_MIP_POINT; + else if (!MinLinear && MagLinear) + F = D3D12_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; + else if (MinLinear && !MagLinear) + F = D3D12_FILTER_MIN_LINEAR_MAG_MIP_POINT; + else + F = D3D12_FILTER_MIN_MAG_LINEAR_MIP_POINT; + if (IsComparison) { + F = static_cast(static_cast(F) | + D3D12_FILTER_REDUCTION_TYPE_COMPARISON + << D3D12_FILTER_REDUCTION_TYPE_SHIFT); + } + return F; +} + +static D3D12_SAMPLER_DESC getDXSamplerDesc(const Sampler &S) { + D3D12_SAMPLER_DESC Desc = {}; + Desc.Filter = getDXFilter(S.Kind, S.MinFilter, S.MagFilter); + Desc.AddressU = getDXAddressMode(S.Address); + Desc.AddressV = getDXAddressMode(S.Address); + Desc.AddressW = getDXAddressMode(S.Address); + Desc.MipLODBias = S.MipLODBias; + Desc.MaxAnisotropy = 1; + Desc.ComparisonFunc = (S.Kind == SamplerKind::SamplerComparison) + ? getDXComparisonFunc(S.ComparisonOp) + : D3D12_COMPARISON_FUNC_NEVER; + Desc.BorderColor[0] = 0.0f; + Desc.BorderColor[1] = 0.0f; + Desc.BorderColor[2] = 0.0f; + Desc.BorderColor[3] = 0.0f; + Desc.MinLOD = S.MinLOD; + Desc.MaxLOD = S.MaxLOD; + return Desc; +} + static llvm::Expected getResourceDescription(const Resource &R) { const D3D12_RESOURCE_DIMENSION Dimension = getDXDimension(R.Kind); @@ -973,6 +1054,7 @@ class DXDevice : public offloadtest::Device { struct InvocationState { ComPtr DescHeap; + ComPtr SamplerHeap; std::unique_ptr CB; std::unique_ptr Pipeline; @@ -1050,36 +1132,65 @@ class DXDevice : public offloadtest::Device { new D3D12_DESCRIPTOR_RANGE[DescriptorCount]); uint32_t RangeIdx = 0; for (const auto &Set : BndDesc.DescriptorSetDescs) { - uint32_t DescriptorIdx = 0; - const uint32_t StartRangeIdx = RangeIdx; + // Split CBV/SRV/UAV and SAMPLER into separate D3D12 descriptor tables + // (different heap types). Walk twice so Ranges stays contiguous per + // root parameter. + uint32_t ResourceCount = 0; + uint32_t SamplerCount = 0; + const uint32_t ResourceStart = RangeIdx; for (const auto &Binding : Set.ResourceBindings) { + if (getDescriptorKind(Binding.Kind) == DescriptorKind::SAMPLER) + continue; + D3D12_DESCRIPTOR_RANGE_TYPE RangeType; switch (getDescriptorKind(Binding.Kind)) { case DescriptorKind::SRV: - Ranges.get()[RangeIdx].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; break; case DescriptorKind::UAV: - Ranges.get()[RangeIdx].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; break; case DescriptorKind::CBV: - Ranges.get()[RangeIdx].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; break; case DescriptorKind::SAMPLER: - llvm_unreachable("Not implemented yet."); // Requires a separate heap + llvm_unreachable("SAMPLER handled in the sampler pass below"); } + Ranges.get()[RangeIdx].RangeType = RangeType; Ranges.get()[RangeIdx].NumDescriptors = Binding.DescriptorCount; Ranges.get()[RangeIdx].BaseShaderRegister = Binding.DXBinding.Register; Ranges.get()[RangeIdx].RegisterSpace = Binding.DXBinding.Space; Ranges.get()[RangeIdx].OffsetInDescriptorsFromTableStart = - DescriptorIdx; - RangeIdx++; - DescriptorIdx += Binding.DescriptorCount; + ResourceCount; + ResourceCount += Binding.DescriptorCount; + ++RangeIdx; + } + if (ResourceCount > 0) { + RootParams.push_back(D3D12_ROOT_PARAMETER{ + D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, + {D3D12_ROOT_DESCRIPTOR_TABLE{RangeIdx - ResourceStart, + &Ranges.get()[ResourceStart]}}, + D3D12_SHADER_VISIBILITY_ALL}); + } + + const uint32_t SamplerStart = RangeIdx; + for (const auto &Binding : Set.ResourceBindings) { + if (getDescriptorKind(Binding.Kind) != DescriptorKind::SAMPLER) + continue; + Ranges.get()[RangeIdx].RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; + Ranges.get()[RangeIdx].NumDescriptors = Binding.DescriptorCount; + Ranges.get()[RangeIdx].BaseShaderRegister = Binding.DXBinding.Register; + Ranges.get()[RangeIdx].RegisterSpace = Binding.DXBinding.Space; + Ranges.get()[RangeIdx].OffsetInDescriptorsFromTableStart = SamplerCount; + SamplerCount += Binding.DescriptorCount; + ++RangeIdx; + } + if (SamplerCount > 0) { + RootParams.push_back(D3D12_ROOT_PARAMETER{ + D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, + {D3D12_ROOT_DESCRIPTOR_TABLE{RangeIdx - SamplerStart, + &Ranges.get()[SamplerStart]}}, + D3D12_SHADER_VISIBILITY_ALL}); } - RootParams.push_back(D3D12_ROOT_PARAMETER{ - D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, - {D3D12_ROOT_DESCRIPTOR_TABLE{ - static_cast(Set.ResourceBindings.size()), - &Ranges.get()[StartRangeIdx]}}, - D3D12_SHADER_VISIBILITY_ALL}); } CD3DX12_ROOT_SIGNATURE_DESC Desc; @@ -1538,14 +1649,37 @@ class DXDevice : public offloadtest::Device { llvm::Error createDescriptorHeap(Pipeline &P, InvocationState &State) { if (P.getDescriptorCount() == 0) return llvm::Error::success(); - const D3D12_DESCRIPTOR_HEAP_DESC HeapDesc = { - D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, - P.getDescriptorCountWithFlattenedArrays(), - D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, 0}; - if (auto Err = HR::toError(Device->CreateDescriptorHeap( - &HeapDesc, IID_PPV_ARGS(&State.DescHeap)), - "Failed to create descriptor heap.")) - return Err; + // Count CBV/SRV/UAV bindings separately; samplers live in their own heap. + uint32_t ResourceCount = 0; + uint32_t SamplerCount = 0; + for (const auto &Set : P.Sets) + for (const auto &R : Set.Resources) { + if (getDescriptorKind(R.Kind) == DescriptorKind::SAMPLER) + SamplerCount += R.getArraySize(); + else + ResourceCount += R.getArraySize(); + } + + if (ResourceCount > 0) { + const D3D12_DESCRIPTOR_HEAP_DESC HeapDesc = { + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, ResourceCount, + D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, 0}; + if (auto Err = HR::toError(Device->CreateDescriptorHeap( + &HeapDesc, IID_PPV_ARGS(&State.DescHeap)), + "Failed to create descriptor heap.")) + return Err; + } + + if (SamplerCount > 0) { + const D3D12_DESCRIPTOR_HEAP_DESC SamplerHeapDesc = { + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, SamplerCount, + D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, 0}; + if (auto Err = HR::toError( + Device->CreateDescriptorHeap(&SamplerHeapDesc, + IID_PPV_ARGS(&State.SamplerHeap)), + "Failed to create sampler descriptor heap.")) + return Err; + } return llvm::Error::success(); } @@ -1975,9 +2109,10 @@ class DXDevice : public offloadtest::Device { break; } case DescriptorKind::SAMPLER: - return llvm::createStringError( - std::errc::not_supported, - "Samplers are not yet implemented for DirectX."); + // Samplers have no backing GPU buffer; placeholder bundle keeps + // DescTables aligned with P.Sets[i].Resources. + Resources.push_back(std::make_pair(&R, ResourceBundle{})); + break; } return llvm::Error::success(); }; @@ -1990,8 +2125,11 @@ class DXDevice : public offloadtest::Device { return Err; } - // Bind descriptors in descriptor tables. + // CBV/SRV/UAV descriptors live in IS.DescHeap; samplers in IS.SamplerHeap. uint32_t HeapIndex = 0; + uint32_t SamplerHeapIndex = 0; + const uint32_t SamplerInc = Device->GetDescriptorHandleIncrementSize( + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); for (auto &T : IS.DescTables) { for (auto &R : T.Resources) { switch (getDescriptorKind(R.first->Kind)) { @@ -2004,8 +2142,18 @@ class DXDevice : public offloadtest::Device { case DescriptorKind::CBV: HeapIndex = bindCBV(*(R.first), IS, HeapIndex, R.second); break; - case DescriptorKind::SAMPLER: - llvm_unreachable("Not implemented yet."); + case DescriptorKind::SAMPLER: { + assert(IS.SamplerHeap && "missing sampler heap"); + assert(R.first->SamplerPtr && "missing Sampler description"); + D3D12_CPU_DESCRIPTOR_HANDLE Handle = + IS.SamplerHeap->GetCPUDescriptorHandleForHeapStart(); + Handle.ptr += SamplerHeapIndex * SamplerInc; + const D3D12_SAMPLER_DESC Desc = + getDXSamplerDesc(*R.first->SamplerPtr); + Device->CreateSampler(&Desc, Handle); + ++SamplerHeapIndex; + break; + } } } } @@ -2074,10 +2222,16 @@ class DXDevice : public offloadtest::Device { llvm::Error createComputeCommands(Pipeline &P, InvocationState &IS) { CD3DX12_GPU_DESCRIPTOR_HANDLE Handle; - if (IS.DescHeap) { - ID3D12DescriptorHeap *const Heaps[] = {IS.DescHeap.Get()}; - IS.CB->CmdList->SetDescriptorHeaps(1, Heaps); - Handle = IS.DescHeap->GetGPUDescriptorHandleForHeapStart(); + if (IS.DescHeap || IS.SamplerHeap) { + llvm::SmallVector Heaps; + if (IS.DescHeap) + Heaps.push_back(IS.DescHeap.Get()); + if (IS.SamplerHeap) + Heaps.push_back(IS.SamplerHeap.Get()); + IS.CB->CmdList->SetDescriptorHeaps(static_cast(Heaps.size()), + Heaps.data()); + if (IS.DescHeap) + Handle = IS.DescHeap->GetGPUDescriptorHandleForHeapStart(); } const DXPipelineState &DXPipeline = llvm::cast(*IS.Pipeline.get()); @@ -2085,6 +2239,8 @@ class DXDevice : public offloadtest::Device { const uint32_t Inc = Device->GetDescriptorHandleIncrementSize( D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + const uint32_t SamplerInc = Device->GetDescriptorHandleIncrementSize( + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); if (P.Settings.DX.RootParams.size() > 0) { uint32_t ConstantOffset = 0u; @@ -2107,11 +2263,18 @@ class DXDevice : public offloadtest::Device { ConstantOffset += NumValues; break; } - case dx::RootParamKind::DescriptorTable: + case dx::RootParamKind::DescriptorTable: { IS.CB->CmdList->SetComputeRootDescriptorTable(RootParamIndex++, Handle); - Handle.Offset(P.Sets[DescriptorTableIndex++].Resources.size(), Inc); + // Samplers live in a separate heap and don't contribute to the + // CBV/SRV/UAV handle offset. + uint32_t ResourceCount = 0; + for (const auto &R : P.Sets[DescriptorTableIndex++].Resources) + if (getDescriptorKind(R.Kind) != DescriptorKind::SAMPLER) + ResourceCount += R.getArraySize(); + Handle.Offset(ResourceCount, Inc); break; + } case dx::RootParamKind::RootDescriptor: assert(RootDescIt != IS.RootResources.end()); if (RootDescIt->first->getArraySize() != 1) @@ -2135,19 +2298,41 @@ class DXDevice : public offloadtest::Device { RootDescIt->second.back().Buffer->GetGPUVirtualAddress()); break; case DescriptorKind::SAMPLER: - llvm_unreachable("Not implemented yet."); + llvm_unreachable("Samplers cannot be bound as root descriptors."); } ++RootDescIt; break; } } } else { - // If no explicit root parameters are provided, fall back to using the - // descriptor set layout. This is to make it easier to write tests that - // don't need complicated root signatures. + // If no explicit root parameters are provided, fall back to the + // descriptor set layout. Each set with mixed CBV/SRV/UAV and SAMPLER + // resources contributes two root parameters: one for the resource table, + // then one for the sampler table (matching the order produced by + // createRootSignatureFromBindingsDesc). + CD3DX12_GPU_DESCRIPTOR_HANDLE SamplerHandle; + if (IS.SamplerHeap) + SamplerHandle = IS.SamplerHeap->GetGPUDescriptorHandleForHeapStart(); + uint32_t RootParamIndex = 0u; for (uint32_t Idx = 0u; Idx < P.Sets.size(); ++Idx) { - IS.CB->CmdList->SetComputeRootDescriptorTable(Idx, Handle); - Handle.Offset(P.Sets[Idx].Resources.size(), Inc); + uint32_t ResourceCount = 0; + uint32_t SamplerCount = 0; + for (const auto &R : P.Sets[Idx].Resources) { + if (getDescriptorKind(R.Kind) == DescriptorKind::SAMPLER) + SamplerCount += R.getArraySize(); + else + ResourceCount += R.getArraySize(); + } + if (ResourceCount > 0) { + IS.CB->CmdList->SetComputeRootDescriptorTable(RootParamIndex++, + Handle); + Handle.Offset(ResourceCount, Inc); + } + if (SamplerCount > 0) { + IS.CB->CmdList->SetComputeRootDescriptorTable(RootParamIndex++, + SamplerHandle); + SamplerHandle.Offset(SamplerCount, SamplerInc); + } } } @@ -2319,11 +2504,46 @@ class DXDevice : public offloadtest::Device { const DXPipelineState &DXPipeline = llvm::cast(*IS.Pipeline.get()); IS.CB->CmdList->SetGraphicsRootSignature(DXPipeline.RootSig.Get()); - if (IS.DescHeap) { - ID3D12DescriptorHeap *const Heaps[] = {IS.DescHeap.Get()}; - IS.CB->CmdList->SetDescriptorHeaps(1, Heaps); - IS.CB->CmdList->SetGraphicsRootDescriptorTable( - 0, IS.DescHeap->GetGPUDescriptorHandleForHeapStart()); + if (IS.DescHeap || IS.SamplerHeap) { + llvm::SmallVector Heaps; + if (IS.DescHeap) + Heaps.push_back(IS.DescHeap.Get()); + if (IS.SamplerHeap) + Heaps.push_back(IS.SamplerHeap.Get()); + IS.CB->CmdList->SetDescriptorHeaps(static_cast(Heaps.size()), + Heaps.data()); + + const uint32_t Inc = Device->GetDescriptorHandleIncrementSize( + D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + const uint32_t SamplerInc = Device->GetDescriptorHandleIncrementSize( + D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + CD3DX12_GPU_DESCRIPTOR_HANDLE ResHandle; + if (IS.DescHeap) + ResHandle = IS.DescHeap->GetGPUDescriptorHandleForHeapStart(); + CD3DX12_GPU_DESCRIPTOR_HANDLE SamplerHandle; + if (IS.SamplerHeap) + SamplerHandle = IS.SamplerHeap->GetGPUDescriptorHandleForHeapStart(); + uint32_t RootParamIndex = 0u; + for (uint32_t Idx = 0u; Idx < P.Sets.size(); ++Idx) { + uint32_t ResourceCount = 0; + uint32_t SamplerCount = 0; + for (const auto &R : P.Sets[Idx].Resources) { + if (getDescriptorKind(R.Kind) == DescriptorKind::SAMPLER) + SamplerCount += R.getArraySize(); + else + ResourceCount += R.getArraySize(); + } + if (ResourceCount > 0) { + IS.CB->CmdList->SetGraphicsRootDescriptorTable(RootParamIndex++, + ResHandle); + ResHandle.Offset(ResourceCount, Inc); + } + if (SamplerCount > 0) { + IS.CB->CmdList->SetGraphicsRootDescriptorTable(RootParamIndex++, + SamplerHandle); + SamplerHandle.Offset(SamplerCount, SamplerInc); + } + } } RenderPassBeginDesc BeginDesc = {}; diff --git a/test/Feature/Textures/Texture2D.Gather.test.yaml b/test/Feature/Textures/Texture2D.Gather.test.yaml index 538471766..0f88367c8 100644 --- a/test/Feature/Textures/Texture2D.Gather.test.yaml +++ b/test/Feature/Textures/Texture2D.Gather.test.yaml @@ -118,7 +118,7 @@ Results: #--- end # Unimplemented: Clang + DX: https://github.com/llvm/llvm-project/issues/101558 -# XFAIL: DirectX || Metal +# XFAIL: (Clang && DirectX) || Metal # RUN: split-file %s %t # RUN: %dxc_target -T cs_6_0 -Fo %t.o %t/source.hlsl diff --git a/test/Feature/Textures/Texture2D.Sampler.address.test.yaml b/test/Feature/Textures/Texture2D.Sampler.address.test.yaml index 844b8f5e7..4d8e9bea5 100644 --- a/test/Feature/Textures/Texture2D.Sampler.address.test.yaml +++ b/test/Feature/Textures/Texture2D.Sampler.address.test.yaml @@ -160,7 +160,7 @@ Results: #--- end # Unimplemented: https://github.com/llvm/offload-test-suite/issues/664 -# XFAIL: DirectX || Metal +# XFAIL: (Clang && DirectX) || Metal # RUN: split-file %s %t # RUN: %dxc_target -T vs_6_0 -E mainVS -Fo %t-vs.o %t/vertex.hlsl diff --git a/test/Feature/Textures/Texture2D.Sampler.compute.test.yaml b/test/Feature/Textures/Texture2D.Sampler.compute.test.yaml new file mode 100644 index 000000000..5bf972806 --- /dev/null +++ b/test/Feature/Textures/Texture2D.Sampler.compute.test.yaml @@ -0,0 +1,81 @@ +#--- source.hlsl +[[vk::binding(0, 0)]] Texture2D Tex : register(t0); +[[vk::binding(1, 0)]] SamplerState Samp : register(s0); +[[vk::binding(2, 0)]] RWBuffer Out : register(u0); + +[numthreads(1, 1, 1)] +void main() { + // 2x2 texture: (Red, Green) over (Blue, White). + // With nearest sampling the pixel centers are at + // (0.25, 0.25), (0.75, 0.25), (0.25, 0.75), (0.75, 0.75). + Out[0] = Tex.SampleLevel(Samp, float2(0.25, 0.25), 0); // Red + Out[1] = Tex.SampleLevel(Samp, float2(0.75, 0.25), 0); // Green + Out[2] = Tex.SampleLevel(Samp, float2(0.25, 0.75), 0); // Blue + Out[3] = Tex.SampleLevel(Samp, float2(0.75, 0.75), 0); // White +} + +//--- pipeline.yaml +--- +Shaders: + - Stage: Compute + Entry: main + +Buffers: + - Name: Tex + Format: Float32 + Channels: 4 + OutputProps: { Width: 2, Height: 2, Depth: 1 } + Data: [ 1.0, 0.0, 0.0, 1.0, # (0,0) Red + 0.0, 1.0, 0.0, 1.0, # (1,0) Green + 0.0, 0.0, 1.0, 1.0, # (0,1) Blue + 1.0, 1.0, 1.0, 1.0 ] # (1,1) White + + - Name: Out + Format: Float32 + Channels: 4 + FillSize: 64 # 4 * sizeof(float4) + + - Name: Expected + Format: Float32 + Channels: 4 + Data: [ 1.0, 0.0, 0.0, 1.0, + 0.0, 1.0, 0.0, 1.0, + 0.0, 0.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0 ] + +Samplers: + - Name: Samp + Address: Clamp + MinFilter: Nearest + MagFilter: Nearest + +DescriptorSets: + - Resources: + - Name: Tex + Kind: Texture2D + DirectXBinding: { Register: 0, Space: 0 } + VulkanBinding: { Binding: 0 } + - Name: Samp + Kind: Sampler + DirectXBinding: { Register: 0, Space: 0 } + VulkanBinding: { Binding: 1 } + - Name: Out + Kind: RWBuffer + DirectXBinding: { Register: 0, Space: 0 } + VulkanBinding: { Binding: 2 } + +Results: + - Result: SamplerComputeTest + Rule: BufferFloatULP + Actual: Out + Expected: Expected + ULPT: 0 +... +#--- end + +# XFAIL: Clang && DirectX +# XFAIL: Metal + +# RUN: split-file %s %t +# RUN: %dxc_target -T cs_6_0 -Fo %t.o %t/source.hlsl +# RUN: %offloader %t/pipeline.yaml %t.o diff --git a/test/Feature/Textures/Texture2D.Sampler.filter.test.yaml b/test/Feature/Textures/Texture2D.Sampler.filter.test.yaml index 5dfd8255b..bee13be7e 100644 --- a/test/Feature/Textures/Texture2D.Sampler.filter.test.yaml +++ b/test/Feature/Textures/Texture2D.Sampler.filter.test.yaml @@ -131,7 +131,7 @@ Results: #--- end # Unimplemented: https://github.com/llvm/offload-test-suite/issues/664 -# XFAIL: DirectX || Metal +# XFAIL: (Clang && DirectX) || Metal # RUN: split-file %s %t # RUN: %dxc_target -T vs_6_0 -E mainVS -Fo %t-vs.o %t/vertex.hlsl