From 46717529fa3c76eddd5f498c131e1183afb4348d Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 21 Dec 2017 17:14:11 +0100 Subject: [PATCH] [dxbc] Implemented unsigned comparators and sample_l --- src/d3d11/d3d11_context.cpp | 6 ++-- src/dxbc/dxbc_compiler.cpp | 33 ++++++++++++++++++-- src/dxbc/dxbc_defs.cpp | 8 ++++- src/spirv/spirv_module.cpp | 60 +++++++++++++++++++++++++++++++++++++ src/spirv/spirv_module.h | 20 +++++++++++++ 5 files changed, 119 insertions(+), 8 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 9b445c4e..a7ed1d3f 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -1404,10 +1404,8 @@ namespace dxvk { : nullptr; } - if (ppDepthStencilView != nullptr) { - Logger::err("D3D11DeviceContext::OMGetRenderTargets: Stencil view not supported"); - *ppDepthStencilView = nullptr; - } + if (ppDepthStencilView != nullptr) + *ppDepthStencilView = m_state.om.depthStencilView.ref(); } diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 186e593a..80843127 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -975,6 +975,16 @@ namespace dxvk { conditionType, src.at(0).id, src.at(1).id); break; + case DxbcOpcode::UGe: + condition = m_module.opUGreaterThanEqual( + conditionType, src.at(0).id, src.at(1).id); + break; + + case DxbcOpcode::ULt: + condition = m_module.opULessThan( + conditionType, src.at(0).id, src.at(1).id); + break; + default: Logger::warn(str::format( "DxbcCompiler: Unhandled instruction: ", @@ -1331,16 +1341,23 @@ namespace dxvk { : DxbcRegisterValue(); // Load explicit gradients for sample operations that require them - const bool explicitGradients = ins.op == DxbcOpcode::SampleD; + const bool hasExplicitGradients = ins.op == DxbcOpcode::SampleD; - const DxbcRegisterValue explicitGradientX = explicitGradients + const DxbcRegisterValue explicitGradientX = hasExplicitGradients ? emitRegisterLoad(ins.src[3], coordLayerMask) : DxbcRegisterValue(); - const DxbcRegisterValue explicitGradientY = explicitGradients + const DxbcRegisterValue explicitGradientY = hasExplicitGradients ? emitRegisterLoad(ins.src[4], coordLayerMask) : DxbcRegisterValue(); + // Explicit LOD value for certain sample operations + const bool hasExplicitLod = ins.op == DxbcOpcode::SampleL; + + const DxbcRegisterValue explicitLod = hasExplicitLod + ? emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false)) + : DxbcRegisterValue(); + // Determine the sampled image type based on the opcode. // FIXME while this is in line what the officla glsl compiler // does, this might actually violate the SPIR-V specification. @@ -1418,6 +1435,16 @@ namespace dxvk { imageOperands); } break; + // Sample operation with explicit LOD + case DxbcOpcode::SampleL: { + imageOperands.flags |= spv::ImageOperandsLodMask; + imageOperands.sLod = m_module.constf32(explicitLod.id); + + result.id = m_module.opImageSampleExplicitLod( + getVectorTypeId(result.type), sampledImageId, coord.id, + imageOperands); + } break; + default: Logger::warn(str::format( "DxbcCompiler: Unhandled instruction: ", diff --git a/src/dxbc/dxbc_defs.cpp b/src/dxbc/dxbc_defs.cpp index 147841f9..b74b51ae 100644 --- a/src/dxbc/dxbc_defs.cpp +++ b/src/dxbc/dxbc_defs.cpp @@ -324,7 +324,13 @@ namespace dxvk { { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, } }, /* SampleL */ - { }, + { 5, DxbcInstClass::TextureSample, { + { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, /* SampleD */ { 6, DxbcInstClass::TextureSample, { { DxbcOperandKind::DstReg, DxbcScalarType::Float32 }, diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 5fc61c60..d4230b40 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -1324,6 +1324,66 @@ namespace dxvk { } + uint32_t SpirvModule::opULessThan( + uint32_t resultType, + uint32_t vector1, + uint32_t vector2) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpULessThan, 5); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(vector1); + m_code.putWord(vector2); + return resultId; + } + + + uint32_t SpirvModule::opULessThanEqual( + uint32_t resultType, + uint32_t vector1, + uint32_t vector2) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpULessThanEqual, 5); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(vector1); + m_code.putWord(vector2); + return resultId; + } + + + uint32_t SpirvModule::opUGreaterThan( + uint32_t resultType, + uint32_t vector1, + uint32_t vector2) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpUGreaterThan, 5); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(vector1); + m_code.putWord(vector2); + return resultId; + } + + + uint32_t SpirvModule::opUGreaterThanEqual( + uint32_t resultType, + uint32_t vector1, + uint32_t vector2) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpUGreaterThanEqual, 5); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(vector1); + m_code.putWord(vector2); + return resultId; + } + + uint32_t SpirvModule::opFOrdEqual( uint32_t resultType, uint32_t vector1, diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 340ab9b0..ff833a95 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -466,6 +466,26 @@ namespace dxvk { uint32_t vector1, uint32_t vector2); + uint32_t opULessThan( + uint32_t resultType, + uint32_t vector1, + uint32_t vector2); + + uint32_t opULessThanEqual( + uint32_t resultType, + uint32_t vector1, + uint32_t vector2); + + uint32_t opUGreaterThan( + uint32_t resultType, + uint32_t vector1, + uint32_t vector2); + + uint32_t opUGreaterThanEqual( + uint32_t resultType, + uint32_t vector1, + uint32_t vector2); + uint32_t opFOrdEqual( uint32_t resultType, uint32_t vector1,