diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 15dec2136..076d4e758 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -88,6 +88,9 @@ namespace dxvk { case DxbcInstClass::TextureQuery: return this->emitTextureQuery(ins); + case DxbcInstClass::TextureQueryMs: + return this->emitTextureQueryMs(ins); + case DxbcInstClass::TextureFetch: return this->emitTextureFetch(ins); @@ -2280,6 +2283,25 @@ namespace dxvk { } + void DxbcCompiler::emitTextureQueryMs(const DxbcShaderInstruction& ins) { + // sampleinfo has two operands: + // (dst0) The destination register + // (src0) Resource to query + // TODO Check if resource is bound + DxbcRegisterValue sampleCount = emitQueryTextureSamples(ins.src[0]); + + if (ins.controls.resinfoType != DxbcResinfoType::Uint) { + sampleCount.type.ctype = DxbcScalarType::Float32; + sampleCount.type.ccount = 1; + sampleCount.id = m_module.opConvertUtoF( + getVectorTypeId(sampleCount.type), + sampleCount.id); + } + + emitRegisterStore(ins.dst[0], sampleCount); + } + + void DxbcCompiler::emitTextureFetch(const DxbcShaderInstruction& ins) { // ld has three operands: // (dst0) The destination register @@ -2502,9 +2524,11 @@ namespace dxvk { DxbcRegisterValue result; result.type.ctype = m_textures.at(textureId).sampledType; result.type.ccount = 4; + switch (ins.op) { // Simple image gather operation - case DxbcOpcode::Gather4: { + case DxbcOpcode::Gather4: + case DxbcOpcode::Gather4Po: { result.id = m_module.opImageGather( getVectorTypeId(result.type), sampledImageId, coord.id, m_module.constu32(samplerReg.swizzle[0]), @@ -2512,7 +2536,8 @@ namespace dxvk { } break; // Depth-compare operation - case DxbcOpcode::Gather4C: { + case DxbcOpcode::Gather4C: + case DxbcOpcode::Gather4PoC: { result.id = m_module.opImageDrefGather( getVectorTypeId(result.type), sampledImageId, coord.id, referenceValue.id, imageOperands); @@ -3924,6 +3949,20 @@ namespace dxvk { } + DxbcRegisterValue DxbcCompiler::emitQueryTextureSamples( + const DxbcRegister& resource) { + const DxbcBufferInfo info = getBufferInfo(resource); + + DxbcRegisterValue result; + result.type.ctype = DxbcScalarType::Uint32; + result.type.ccount = 1; + result.id = m_module.opImageQuerySamples( + getVectorTypeId(result.type), + m_module.opLoad(info.typeId, info.varId)); + return result; + } + + DxbcRegisterValue DxbcCompiler::emitQueryTextureSize( const DxbcRegister& resource, DxbcRegisterValue lod) { diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index b9a1579cc..0e8c3e9b9 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -524,6 +524,9 @@ namespace dxvk { void emitTextureQuery( const DxbcShaderInstruction& ins); + void emitTextureQueryMs( + const DxbcShaderInstruction& ins); + void emitTextureFetch( const DxbcShaderInstruction& ins); @@ -703,6 +706,9 @@ namespace dxvk { DxbcRegisterValue emitQueryTextureLods( const DxbcRegister& resource); + DxbcRegisterValue emitQueryTextureSamples( + const DxbcRegister& resource); + DxbcRegisterValue emitQueryTextureSize( const DxbcRegister& resource, DxbcRegisterValue lod); diff --git a/src/dxbc/dxbc_defs.cpp b/src/dxbc/dxbc_defs.cpp index 876a93984..15849d329 100644 --- a/src/dxbc/dxbc_defs.cpp +++ b/src/dxbc/dxbc_defs.cpp @@ -547,7 +547,10 @@ namespace dxvk { /* SamplePos */ { }, /* SampleInfo */ - { }, + { 2, DxbcInstClass::TextureQueryMs, { + { DxbcOperandKind::DstReg, DxbcScalarType::Uint32 }, + { DxbcOperandKind::SrcReg, DxbcScalarType::Float32 }, + } }, /* Reserved1 */ { }, /* HsDecls */ diff --git a/src/dxbc/dxbc_defs.h b/src/dxbc/dxbc_defs.h index 61cf93927..360614288 100644 --- a/src/dxbc/dxbc_defs.h +++ b/src/dxbc/dxbc_defs.h @@ -42,6 +42,7 @@ namespace dxvk { BufferStore, ///< Structured or raw buffer store ConvertFloat16, ///< 16-bit float packing/unpacking TextureQuery, ///< Texture query instruction + TextureQueryMs, ///< Multisample texture query TextureFetch, ///< Texture fetch instruction TextureGather, ///< Texture gather instruction TextureSample, ///< Texture sampling instruction diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 7875a22e2..14a8e26b9 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -2400,6 +2400,19 @@ namespace dxvk { } + uint32_t SpirvModule::opImageQuerySamples( + uint32_t resultType, + uint32_t image) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpImageQuerySamples, 4); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(image); + return resultId; + } + + uint32_t SpirvModule::opImageFetch( uint32_t resultType, uint32_t image, diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 60f735626..d4d02935f 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -840,6 +840,10 @@ namespace dxvk { uint32_t resultType, uint32_t image); + uint32_t opImageQuerySamples( + uint32_t resultType, + uint32_t image); + uint32_t opImageFetch( uint32_t resultType, uint32_t image,