1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-21 22:54:16 +01:00

[dxbc] Fixed sampler types for depth-compare operations

This commit is contained in:
Philip Rebohle 2017-12-20 13:41:04 +01:00
parent 2ed2d892d6
commit b4e10b7f06
2 changed files with 67 additions and 74 deletions

View File

@ -494,67 +494,52 @@ namespace dxvk {
Logger::warn("DxbcCompiler: dcl_resource: Ignoring resource return types"); Logger::warn("DxbcCompiler: dcl_resource: Ignoring resource return types");
// Declare the actual sampled type // Declare the actual sampled type
uint32_t sampledTypeId = 0; const DxbcScalarType sampledType = [xType] {
switch (xType) {
case DxbcResourceReturnType::Float: return DxbcScalarType::Float32;
case DxbcResourceReturnType::Sint: return DxbcScalarType::Sint32;
case DxbcResourceReturnType::Uint: return DxbcScalarType::Uint32;
default: throw DxvkError(str::format("DxbcCompiler: Invalid sampled type: ", xType));
}
}();
switch (xType) { const uint32_t sampledTypeId = getScalarTypeId(sampledType);
case DxbcResourceReturnType::Float: sampledTypeId = m_module.defFloatType(32); break;
case DxbcResourceReturnType::Sint: sampledTypeId = m_module.defIntType (32, 1); break;
case DxbcResourceReturnType::Uint: sampledTypeId = m_module.defIntType (32, 0); break;
default: throw DxvkError(str::format("DxbcCompiler: Invalid sampled type: ", xType));
}
// Declare the resource type // Declare the resource type
uint32_t textureTypeId = 0; struct ImageTypeInfo {
spv::Dim dim;
uint32_t array;
uint32_t ms;
uint32_t sampled;
};
switch (resourceType) { const ImageTypeInfo typeInfo = [resourceType] () -> ImageTypeInfo {
case DxbcResourceDim::Texture1D: switch (resourceType) {
textureTypeId = m_module.defImageType( case DxbcResourceDim::Texture1D: return { spv::Dim1D, 0, 0, 1 };
sampledTypeId, spv::Dim1D, 0, 0, 0, 1, case DxbcResourceDim::Texture1DArr: return { spv::Dim1D, 1, 0, 1 };
spv::ImageFormatUnknown); case DxbcResourceDim::Texture2D: return { spv::Dim2D, 0, 0, 1 };
break; case DxbcResourceDim::Texture2DArr: return { spv::Dim2D, 1, 0, 1 };
case DxbcResourceDim::Texture3D: return { spv::Dim3D, 0, 0, 1 };
case DxbcResourceDim::Texture1DArr: case DxbcResourceDim::TextureCube: return { spv::Dim3D, 0, 0, 1 };
textureTypeId = m_module.defImageType( case DxbcResourceDim::TextureCubeArr: return { spv::Dim3D, 1, 0, 1 };
sampledTypeId, spv::Dim1D, 0, 1, 0, 1, default: throw DxvkError(str::format("DxbcCompiler: Unsupported resource type: ", resourceType));
spv::ImageFormatUnknown); }
break; }();
case DxbcResourceDim::Texture2D:
textureTypeId = m_module.defImageType(
sampledTypeId, spv::Dim2D, 0, 0, 0, 1,
spv::ImageFormatUnknown);
break;
case DxbcResourceDim::Texture2DArr:
textureTypeId = m_module.defImageType(
sampledTypeId, spv::Dim2D, 0, 1, 0, 1,
spv::ImageFormatUnknown);
break;
case DxbcResourceDim::Texture3D:
textureTypeId = m_module.defImageType(
sampledTypeId, spv::Dim3D, 0, 0, 0, 1,
spv::ImageFormatUnknown);
break;
case DxbcResourceDim::TextureCube:
textureTypeId = m_module.defImageType(
sampledTypeId, spv::DimCube, 0, 0, 0, 1,
spv::ImageFormatUnknown);
break;
case DxbcResourceDim::TextureCubeArr:
textureTypeId = m_module.defImageType(
sampledTypeId, spv::DimCube, 0, 1, 0, 1,
spv::ImageFormatUnknown);
break;
default:
throw DxvkError(str::format("DxbcCompiler: Unsupported resource type: ", resourceType));
}
// We do not know whether the image is going to be used as a color
// image or a depth image yet, so we'll declare types for both.
const uint32_t colorTypeId = m_module.defImageType(sampledTypeId,
typeInfo.dim, 0, typeInfo.array, typeInfo.ms, typeInfo.sampled,
spv::ImageFormatUnknown);
const uint32_t depthTypeId = m_module.defImageType(sampledTypeId,
typeInfo.dim, 1, typeInfo.array, typeInfo.ms, typeInfo.sampled,
spv::ImageFormatUnknown);
// We'll declare the texture variable with the color type
// and decide which one to use when the texture is sampled.
const uint32_t resourcePtrType = m_module.defPointerType( const uint32_t resourcePtrType = m_module.defPointerType(
textureTypeId, spv::StorageClassUniformConstant); colorTypeId, spv::StorageClassUniformConstant);
const uint32_t varId = m_module.newVar(resourcePtrType, const uint32_t varId = m_module.newVar(resourcePtrType,
spv::StorageClassUniformConstant); spv::StorageClassUniformConstant);
@ -563,8 +548,10 @@ namespace dxvk {
str::format("t", registerId).c_str()); str::format("t", registerId).c_str());
m_textures.at(registerId).varId = varId; m_textures.at(registerId).varId = varId;
m_textures.at(registerId).sampledType = sampledType;
m_textures.at(registerId).sampledTypeId = sampledTypeId; m_textures.at(registerId).sampledTypeId = sampledTypeId;
m_textures.at(registerId).textureTypeId = textureTypeId; m_textures.at(registerId).colorTypeId = colorTypeId;
m_textures.at(registerId).depthTypeId = depthTypeId;
// Compute the DXVK binding slot index for the resource. // Compute the DXVK binding slot index for the resource.
// D3D11 needs to bind the actual resource to this slot. // D3D11 needs to bind the actual resource to this slot.
@ -1227,42 +1214,46 @@ namespace dxvk {
const DxbcRegisterValue coord = emitRegisterLoad( const DxbcRegisterValue coord = emitRegisterLoad(
texCoordReg, DxbcRegMask(true, true, true, true)); texCoordReg, DxbcRegMask(true, true, true, true));
// Load reference value for depth-compare operations // Determine whether this is a depth-compare op
DxbcRegisterValue referenceValue; const bool isDepthCompare = ins.op == DxbcOpcode::SampleC
|| ins.op == DxbcOpcode::SampleClz;
if (ins.op == DxbcOpcode::SampleC || ins.op == DxbcOpcode::SampleClz) // Load reference value for depth-compare operations
referenceValue = emitRegisterLoad(ins.src[3], DxbcRegMask(true, false, false, false)); const DxbcRegisterValue referenceValue = isDepthCompare
? 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.
const uint32_t sampledImageType = isDepthCompare
? m_module.defSampledImageType(m_textures.at(textureId).depthTypeId)
: m_module.defSampledImageType(m_textures.at(textureId).colorTypeId);
// Combine the texture and the sampler into a sampled image // Combine the texture and the sampler into a sampled image
const uint32_t sampledImageType = m_module.defSampledImageType(
m_textures.at(textureId).textureTypeId);
const uint32_t sampledImageId = m_module.opSampledImage( const uint32_t sampledImageId = m_module.opSampledImage(
sampledImageType, sampledImageType,
m_module.opLoad( m_module.opLoad(
m_textures.at(textureId).textureTypeId, m_textures.at(textureId).colorTypeId,
m_textures.at(textureId).varId), m_textures.at(textureId).varId),
m_module.opLoad( m_module.opLoad(
m_samplers.at(samplerId).typeId, m_samplers.at(samplerId).typeId,
m_samplers.at(samplerId).varId)); m_samplers.at(samplerId).varId));
// Sampling an image in SPIR-V always returns a four-component // Sampling an image always returns a four-component
// vector, so we need to declare the corresponding type here // vector, whereas depth-compare ops return a scalar.
// TODO infer sampled types properly
DxbcRegisterValue result; DxbcRegisterValue result;
result.type.ctype = m_textures.at(textureId).sampledType;
result.type.ccount = isDepthCompare ? 1 : 4;
switch (ins.op) { switch (ins.op) {
case DxbcOpcode::Sample: { case DxbcOpcode::Sample: {
result.type.ctype = DxbcScalarType::Float32;
result.type.ccount = 4;
result.id = m_module.opImageSampleImplicitLod( result.id = m_module.opImageSampleImplicitLod(
getVectorTypeId(result.type), getVectorTypeId(result.type),
sampledImageId, coord.id); sampledImageId, coord.id);
} break; } break;
case DxbcOpcode::SampleClz: { case DxbcOpcode::SampleClz: {
result.type.ctype = DxbcScalarType::Float32;
result.type.ccount = 1;
result.id = m_module.opImageSampleDrefExplicitLod( result.id = m_module.opImageSampleDrefExplicitLod(
getVectorTypeId(result.type), getVectorTypeId(result.type),
sampledImageId, coord.id, sampledImageId, coord.id,

View File

@ -58,9 +58,11 @@ namespace dxvk {
* and associated type IDs. * and associated type IDs.
*/ */
struct DxbcShaderResource { struct DxbcShaderResource {
uint32_t varId = 0; uint32_t varId = 0;
uint32_t sampledTypeId = 0; DxbcScalarType sampledType = DxbcScalarType::Float32;
uint32_t textureTypeId = 0; uint32_t sampledTypeId = 0;
uint32_t colorTypeId = 0;
uint32_t depthTypeId = 0;
}; };
/** /**