mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 19:24:12 +01:00
[dxbc] Set image format for UAVs when atomic operations are used
Fixes a violation of the Vulkan specification where atomic operations would be used on storage images with SpvImageFormatUnknown. Should fix driver crashes on Nvidia. TODO: Fix data types for atomic operation instructions.
This commit is contained in:
parent
c1a1ff3915
commit
fcff10aae7
@ -1952,7 +1952,7 @@ namespace dxvk {
|
|||||||
const bool isImm = ins.dstCount == 2;
|
const bool isImm = ins.dstCount == 2;
|
||||||
const bool isUav = ins.dst[ins.dstCount - 1].type == DxbcOperandType::UnorderedAccessView;
|
const bool isUav = ins.dst[ins.dstCount - 1].type == DxbcOperandType::UnorderedAccessView;
|
||||||
|
|
||||||
// Retrieve destination pointer for the atomic operation
|
// Retrieve destination pointer for the atomic operation>
|
||||||
const DxbcRegisterPointer pointer = emitGetAtomicPointer(
|
const DxbcRegisterPointer pointer = emitGetAtomicPointer(
|
||||||
ins.dst[ins.dstCount - 1], ins.src[0]);
|
ins.dst[ins.dstCount - 1], ins.src[0]);
|
||||||
|
|
||||||
@ -4226,6 +4226,14 @@ namespace dxvk {
|
|||||||
// of obtaining the final pointer are used.
|
// of obtaining the final pointer are used.
|
||||||
const bool isUav = operand.type == DxbcOperandType::UnorderedAccessView;
|
const bool isUav = operand.type == DxbcOperandType::UnorderedAccessView;
|
||||||
|
|
||||||
|
// If the resource is an UAV, we need to specify a format
|
||||||
|
// for the image type. Atomic ops are only allowed for
|
||||||
|
// 32-bit scalar integer formats.
|
||||||
|
if (isUav) {
|
||||||
|
m_module.setImageTypeFormat(resourceInfo.typeId,
|
||||||
|
getScalarImageFormat(resourceInfo.stype));
|
||||||
|
}
|
||||||
|
|
||||||
// Compute the actual address into the resource
|
// Compute the actual address into the resource
|
||||||
const DxbcRegisterValue addressValue = [&] {
|
const DxbcRegisterValue addressValue = [&] {
|
||||||
switch (resourceInfo.type) {
|
switch (resourceInfo.type) {
|
||||||
@ -5837,6 +5845,7 @@ namespace dxvk {
|
|||||||
case DxbcOperandType::Resource: {
|
case DxbcOperandType::Resource: {
|
||||||
DxbcBufferInfo result;
|
DxbcBufferInfo result;
|
||||||
result.image = m_textures.at(registerId).imageInfo;
|
result.image = m_textures.at(registerId).imageInfo;
|
||||||
|
result.stype = m_textures.at(registerId).sampledType;
|
||||||
result.type = m_textures.at(registerId).type;
|
result.type = m_textures.at(registerId).type;
|
||||||
result.typeId = m_textures.at(registerId).imageTypeId;
|
result.typeId = m_textures.at(registerId).imageTypeId;
|
||||||
result.varId = m_textures.at(registerId).varId;
|
result.varId = m_textures.at(registerId).varId;
|
||||||
@ -5848,6 +5857,7 @@ namespace dxvk {
|
|||||||
case DxbcOperandType::UnorderedAccessView: {
|
case DxbcOperandType::UnorderedAccessView: {
|
||||||
DxbcBufferInfo result;
|
DxbcBufferInfo result;
|
||||||
result.image = m_uavs.at(registerId).imageInfo;
|
result.image = m_uavs.at(registerId).imageInfo;
|
||||||
|
result.stype = m_uavs.at(registerId).sampledType;
|
||||||
result.type = m_uavs.at(registerId).type;
|
result.type = m_uavs.at(registerId).type;
|
||||||
result.typeId = m_uavs.at(registerId).imageTypeId;
|
result.typeId = m_uavs.at(registerId).imageTypeId;
|
||||||
result.varId = m_uavs.at(registerId).varId;
|
result.varId = m_uavs.at(registerId).varId;
|
||||||
@ -5859,6 +5869,7 @@ namespace dxvk {
|
|||||||
case DxbcOperandType::ThreadGroupSharedMemory: {
|
case DxbcOperandType::ThreadGroupSharedMemory: {
|
||||||
DxbcBufferInfo result;
|
DxbcBufferInfo result;
|
||||||
result.image = { spv::DimBuffer, 0, 0, 0 };
|
result.image = { spv::DimBuffer, 0, 0, 0 };
|
||||||
|
result.stype = DxbcScalarType::Uint32;
|
||||||
result.type = m_gRegs.at(registerId).type;
|
result.type = m_gRegs.at(registerId).type;
|
||||||
result.typeId = m_module.defPointerType(
|
result.typeId = m_module.defPointerType(
|
||||||
getScalarTypeId(DxbcScalarType::Uint32),
|
getScalarTypeId(DxbcScalarType::Uint32),
|
||||||
@ -5934,6 +5945,16 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
spv::ImageFormat DxbcCompiler::getScalarImageFormat(DxbcScalarType type) const {
|
||||||
|
switch (type) {
|
||||||
|
case DxbcScalarType::Float32: return spv::ImageFormatR32f;
|
||||||
|
case DxbcScalarType::Sint32: return spv::ImageFormatR32i;
|
||||||
|
case DxbcScalarType::Uint32: return spv::ImageFormatR32ui;
|
||||||
|
default: throw DxvkError("DxbcCompiler: Unhandled scalar resource type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t DxbcCompiler::getScalarTypeId(DxbcScalarType type) {
|
uint32_t DxbcCompiler::getScalarTypeId(DxbcScalarType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DxbcScalarType::Uint32: return m_module.defIntType(32, 0);
|
case DxbcScalarType::Uint32: return m_module.defIntType(32, 0);
|
||||||
|
@ -288,6 +288,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
struct DxbcBufferInfo {
|
struct DxbcBufferInfo {
|
||||||
DxbcImageInfo image;
|
DxbcImageInfo image;
|
||||||
|
DxbcScalarType stype;
|
||||||
DxbcResourceType type;
|
DxbcResourceType type;
|
||||||
uint32_t typeId;
|
uint32_t typeId;
|
||||||
uint32_t varId;
|
uint32_t varId;
|
||||||
@ -977,6 +978,9 @@ namespace dxvk {
|
|||||||
VkImageViewType getViewType(
|
VkImageViewType getViewType(
|
||||||
DxbcResourceDim dim) const;
|
DxbcResourceDim dim) const;
|
||||||
|
|
||||||
|
spv::ImageFormat getScalarImageFormat(
|
||||||
|
DxbcScalarType type) const;
|
||||||
|
|
||||||
///////////////////////////
|
///////////////////////////
|
||||||
// Type definition methods
|
// Type definition methods
|
||||||
uint32_t getScalarTypeId(
|
uint32_t getScalarTypeId(
|
||||||
|
@ -599,14 +599,18 @@ namespace dxvk {
|
|||||||
uint32_t multisample,
|
uint32_t multisample,
|
||||||
uint32_t sampled,
|
uint32_t sampled,
|
||||||
spv::ImageFormat format) {
|
spv::ImageFormat format) {
|
||||||
std::array<uint32_t, 7> args = {
|
uint32_t resultId = this->allocateId();
|
||||||
sampledType, dimensionality,
|
|
||||||
depth, arrayed, multisample,
|
|
||||||
sampled, format
|
|
||||||
};
|
|
||||||
|
|
||||||
return this->defType(spv::OpTypeImage,
|
m_typeConstDefs.putIns (spv::OpTypeImage, 9);
|
||||||
args.size(), args.data());
|
m_typeConstDefs.putWord(resultId);
|
||||||
|
m_typeConstDefs.putWord(sampledType);
|
||||||
|
m_typeConstDefs.putWord(dimensionality);
|
||||||
|
m_typeConstDefs.putWord(depth);
|
||||||
|
m_typeConstDefs.putWord(arrayed);
|
||||||
|
m_typeConstDefs.putWord(multisample);
|
||||||
|
m_typeConstDefs.putWord(sampled);
|
||||||
|
m_typeConstDefs.putWord(format);
|
||||||
|
return resultId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -616,6 +620,20 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SpirvModule::setImageTypeFormat(
|
||||||
|
uint32_t imageType,
|
||||||
|
spv::ImageFormat format) {
|
||||||
|
for (auto ins : m_typeConstDefs) {
|
||||||
|
bool match = ins.arg(1) == imageType;
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
ins.setArg(8, format);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t SpirvModule::newVar(
|
uint32_t SpirvModule::newVar(
|
||||||
uint32_t pointerType,
|
uint32_t pointerType,
|
||||||
spv::StorageClass storageClass) {
|
spv::StorageClass storageClass) {
|
||||||
|
@ -254,6 +254,10 @@ namespace dxvk {
|
|||||||
uint32_t defSampledImageType(
|
uint32_t defSampledImageType(
|
||||||
uint32_t imageType);
|
uint32_t imageType);
|
||||||
|
|
||||||
|
void setImageTypeFormat(
|
||||||
|
uint32_t imageType,
|
||||||
|
spv::ImageFormat format);
|
||||||
|
|
||||||
uint32_t newVar(
|
uint32_t newVar(
|
||||||
uint32_t pointerType,
|
uint32_t pointerType,
|
||||||
spv::StorageClass storageClass);
|
spv::StorageClass storageClass);
|
||||||
|
Loading…
Reference in New Issue
Block a user