mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 22:24:15 +01:00
[dxvk] Use analyzer to determine UAV image type
This commit is contained in:
parent
44d8d6b8c3
commit
abb90086d5
@ -4,7 +4,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxbcAnalyzer::DxbcAnalyzer(
|
DxbcAnalyzer::DxbcAnalyzer(
|
||||||
const DxbcOptions& options,
|
const DxbcOptions& options,
|
||||||
const DxbcProgramVersion& version) {
|
const DxbcProgramVersion& version,
|
||||||
|
DxbcAnalysisInfo& analysis)
|
||||||
|
: m_analysis(&analysis) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,9 +16,25 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxbcAnalyzer::processInstruction(
|
void DxbcAnalyzer::processInstruction(const DxbcShaderInstruction& ins) {
|
||||||
const DxbcShaderInstruction& ins) {
|
switch (ins.opClass) {
|
||||||
|
case DxbcInstClass::Atomic: {
|
||||||
|
const uint32_t operandId = ins.dstCount - 1;
|
||||||
|
|
||||||
|
if (ins.dst[operandId].type == DxbcOperandType::UnorderedAccessView) {
|
||||||
|
const uint32_t registerId = ins.dst[operandId].idx[0].offset;
|
||||||
|
m_analysis->uavInfos[registerId].accessAtomicOp = true;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DxbcInstClass::TypedUavLoad: {
|
||||||
|
const uint32_t registerId = ins.src[1].idx[0].offset;
|
||||||
|
m_analysis->uavInfos[registerId].accessTypedLoad = true;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -9,11 +9,21 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Info about unordered access views
|
||||||
|
*
|
||||||
|
* Stores whether an UAV is accessed with typed
|
||||||
|
* read or atomic instructions. This information
|
||||||
|
* will be used to generate image types.
|
||||||
|
*/
|
||||||
struct DxbcUavInfo {
|
struct DxbcUavInfo {
|
||||||
bool accessTypedRead = false;
|
bool accessTypedLoad = false;
|
||||||
bool accessAtomicOp = false;
|
bool accessAtomicOp = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Shader analysis info
|
||||||
|
*/
|
||||||
struct DxbcAnalysisInfo {
|
struct DxbcAnalysisInfo {
|
||||||
std::array<DxbcUavInfo, 64> uavInfos;
|
std::array<DxbcUavInfo, 64> uavInfos;
|
||||||
};
|
};
|
||||||
@ -31,7 +41,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxbcAnalyzer(
|
DxbcAnalyzer(
|
||||||
const DxbcOptions& options,
|
const DxbcOptions& options,
|
||||||
const DxbcProgramVersion& version);
|
const DxbcProgramVersion& version,
|
||||||
|
DxbcAnalysisInfo& analysis);
|
||||||
|
|
||||||
~DxbcAnalyzer();
|
~DxbcAnalyzer();
|
||||||
|
|
||||||
@ -44,7 +55,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
DxbcAnalysisInfo* m_analysis = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,11 +12,13 @@ namespace dxvk {
|
|||||||
const DxbcOptions& options,
|
const DxbcOptions& options,
|
||||||
const DxbcProgramVersion& version,
|
const DxbcProgramVersion& version,
|
||||||
const Rc<DxbcIsgn>& isgn,
|
const Rc<DxbcIsgn>& isgn,
|
||||||
const Rc<DxbcIsgn>& osgn)
|
const Rc<DxbcIsgn>& osgn,
|
||||||
|
const DxbcAnalysisInfo& analysis)
|
||||||
: m_options (options),
|
: m_options (options),
|
||||||
m_version (version),
|
m_version (version),
|
||||||
m_isgn (isgn),
|
m_isgn (isgn),
|
||||||
m_osgn (osgn) {
|
m_osgn (osgn),
|
||||||
|
m_analysis(&analysis) {
|
||||||
// Declare an entry point ID. We'll need it during the
|
// Declare an entry point ID. We'll need it during the
|
||||||
// initialization phase where the execution mode is set.
|
// initialization phase where the execution mode is set.
|
||||||
m_entryPointId = m_module.allocateId();
|
m_entryPointId = m_module.allocateId();
|
||||||
@ -809,12 +811,24 @@ namespace dxvk {
|
|||||||
default: break; // No additional capabilities required
|
default: break; // No additional capabilities required
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the read-without-format capability is not set and this
|
||||||
|
// image is access via a typed load, or if atomic operations
|
||||||
|
// are used,, we must define the image format explicitly.
|
||||||
|
spv::ImageFormat imageFormat = spv::ImageFormatUnknown;
|
||||||
|
|
||||||
|
if (isUav) {
|
||||||
|
if ((m_analysis->uavInfos[registerId].accessAtomicOp)
|
||||||
|
|| (m_analysis->uavInfos[registerId].accessTypedLoad
|
||||||
|
&& !m_options.useStorageImageReadWithoutFormat))
|
||||||
|
imageFormat = getScalarImageFormat(sampledType);
|
||||||
|
}
|
||||||
|
|
||||||
// We do not know whether the image is going to be used as
|
// We do not know whether the image is going to be used as
|
||||||
// a color image or a depth image yet, but we can pick the
|
// a color image or a depth image yet, but we can pick the
|
||||||
// correct type when creating a sampled image object.
|
// correct type when creating a sampled image object.
|
||||||
const uint32_t imageTypeId = m_module.defImageType(sampledTypeId,
|
const uint32_t imageTypeId = m_module.defImageType(sampledTypeId,
|
||||||
typeInfo.dim, 0, typeInfo.array, typeInfo.ms, typeInfo.sampled,
|
typeInfo.dim, 0, typeInfo.array, typeInfo.ms, typeInfo.sampled,
|
||||||
spv::ImageFormatUnknown);
|
imageFormat);
|
||||||
|
|
||||||
// We'll declare the texture variable with the color type
|
// We'll declare the texture variable with the color type
|
||||||
// and decide which one to use when the texture is sampled.
|
// and decide which one to use when the texture is sampled.
|
||||||
@ -1989,7 +2003,6 @@ namespace dxvk {
|
|||||||
// The result type, which is a scalar integer
|
// The result type, which is a scalar integer
|
||||||
const uint32_t typeId = getVectorTypeId(value.type);
|
const uint32_t typeId = getVectorTypeId(value.type);
|
||||||
|
|
||||||
// TODO add signed min/max
|
|
||||||
switch (ins.op) {
|
switch (ins.op) {
|
||||||
case DxbcOpcode::ImmAtomicExch:
|
case DxbcOpcode::ImmAtomicExch:
|
||||||
value.id = m_module.opAtomicExchange(typeId,
|
value.id = m_module.opAtomicExchange(typeId,
|
||||||
@ -3140,13 +3153,6 @@ namespace dxvk {
|
|||||||
const DxbcRegisterValue texCoord = emitRegisterLoad(
|
const DxbcRegisterValue texCoord = emitRegisterLoad(
|
||||||
ins.src[0], getTexCoordMask(uavInfo.imageInfo));
|
ins.src[0], getTexCoordMask(uavInfo.imageInfo));
|
||||||
|
|
||||||
// If the read-without-format capability is not
|
|
||||||
// set. we must define the image format explicitly.
|
|
||||||
if (!m_options.useStorageImageReadWithoutFormat) {
|
|
||||||
m_module.setImageTypeFormat(uavInfo.imageTypeId,
|
|
||||||
getScalarImageFormat(uavInfo.sampledType));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load source value from the UAV
|
// Load source value from the UAV
|
||||||
DxbcRegisterValue uavValue;
|
DxbcRegisterValue uavValue;
|
||||||
uavValue.type.ctype = uavInfo.sampledType;
|
uavValue.type.ctype = uavInfo.sampledType;
|
||||||
@ -4237,14 +4243,6 @@ 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) {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "../spirv/spirv_module.h"
|
#include "../spirv/spirv_module.h"
|
||||||
|
|
||||||
|
#include "dxbc_analysis.h"
|
||||||
#include "dxbc_chunk_isgn.h"
|
#include "dxbc_chunk_isgn.h"
|
||||||
#include "dxbc_decoder.h"
|
#include "dxbc_decoder.h"
|
||||||
#include "dxbc_defs.h"
|
#include "dxbc_defs.h"
|
||||||
@ -312,7 +313,8 @@ namespace dxvk {
|
|||||||
const DxbcOptions& options,
|
const DxbcOptions& options,
|
||||||
const DxbcProgramVersion& version,
|
const DxbcProgramVersion& version,
|
||||||
const Rc<DxbcIsgn>& isgn,
|
const Rc<DxbcIsgn>& isgn,
|
||||||
const Rc<DxbcIsgn>& osgn);
|
const Rc<DxbcIsgn>& osgn,
|
||||||
|
const DxbcAnalysisInfo& analysis);
|
||||||
~DxbcCompiler();
|
~DxbcCompiler();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -337,6 +339,8 @@ namespace dxvk {
|
|||||||
Rc<DxbcIsgn> m_isgn;
|
Rc<DxbcIsgn> m_isgn;
|
||||||
Rc<DxbcIsgn> m_osgn;
|
Rc<DxbcIsgn> m_osgn;
|
||||||
|
|
||||||
|
const DxbcAnalysisInfo* m_analysis;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// Resource slot description for the shader. This will
|
// Resource slot description for the shader. This will
|
||||||
// be used to map D3D11 bindings to DXVK bindings.
|
// be used to map D3D11 bindings to DXVK bindings.
|
||||||
|
@ -45,12 +45,16 @@ namespace dxvk {
|
|||||||
if (m_shexChunk == nullptr)
|
if (m_shexChunk == nullptr)
|
||||||
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
||||||
|
|
||||||
|
DxbcAnalysisInfo analysisInfo;
|
||||||
|
|
||||||
DxbcAnalyzer analyzer(options,
|
DxbcAnalyzer analyzer(options,
|
||||||
m_shexChunk->version());
|
m_shexChunk->version(),
|
||||||
|
analysisInfo);
|
||||||
|
|
||||||
DxbcCompiler compiler(options,
|
DxbcCompiler compiler(options,
|
||||||
m_shexChunk->version(),
|
m_shexChunk->version(),
|
||||||
m_isgnChunk, m_osgnChunk);
|
m_isgnChunk, m_osgnChunk,
|
||||||
|
analysisInfo);
|
||||||
|
|
||||||
this->runAnalyzer(analyzer, m_shexChunk->slice());
|
this->runAnalyzer(analyzer, m_shexChunk->slice());
|
||||||
this->runCompiler(compiler, m_shexChunk->slice());
|
this->runCompiler(compiler, m_shexChunk->slice());
|
||||||
|
Loading…
Reference in New Issue
Block a user