mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 13:24:10 +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(
|
||||
const DxbcOptions& options,
|
||||
const DxbcProgramVersion& version) {
|
||||
const DxbcProgramVersion& version,
|
||||
DxbcAnalysisInfo& analysis)
|
||||
: m_analysis(&analysis) {
|
||||
|
||||
}
|
||||
|
||||
@ -14,9 +16,25 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxbcAnalyzer::processInstruction(
|
||||
const DxbcShaderInstruction& ins) {
|
||||
|
||||
void DxbcAnalyzer::processInstruction(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 {
|
||||
|
||||
/**
|
||||
* \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 {
|
||||
bool accessTypedRead = false;
|
||||
bool accessTypedLoad = false;
|
||||
bool accessAtomicOp = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Shader analysis info
|
||||
*/
|
||||
struct DxbcAnalysisInfo {
|
||||
std::array<DxbcUavInfo, 64> uavInfos;
|
||||
};
|
||||
@ -31,7 +41,8 @@ namespace dxvk {
|
||||
|
||||
DxbcAnalyzer(
|
||||
const DxbcOptions& options,
|
||||
const DxbcProgramVersion& version);
|
||||
const DxbcProgramVersion& version,
|
||||
DxbcAnalysisInfo& analysis);
|
||||
|
||||
~DxbcAnalyzer();
|
||||
|
||||
@ -44,7 +55,7 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
|
||||
DxbcAnalysisInfo* m_analysis = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
@ -12,11 +12,13 @@ namespace dxvk {
|
||||
const DxbcOptions& options,
|
||||
const DxbcProgramVersion& version,
|
||||
const Rc<DxbcIsgn>& isgn,
|
||||
const Rc<DxbcIsgn>& osgn)
|
||||
const Rc<DxbcIsgn>& osgn,
|
||||
const DxbcAnalysisInfo& analysis)
|
||||
: m_options (options),
|
||||
m_version (version),
|
||||
m_isgn (isgn),
|
||||
m_osgn (osgn) {
|
||||
m_osgn (osgn),
|
||||
m_analysis(&analysis) {
|
||||
// Declare an entry point ID. We'll need it during the
|
||||
// initialization phase where the execution mode is set.
|
||||
m_entryPointId = m_module.allocateId();
|
||||
@ -809,12 +811,24 @@ namespace dxvk {
|
||||
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
|
||||
// a color image or a depth image yet, but we can pick the
|
||||
// correct type when creating a sampled image object.
|
||||
const uint32_t imageTypeId = m_module.defImageType(sampledTypeId,
|
||||
typeInfo.dim, 0, typeInfo.array, typeInfo.ms, typeInfo.sampled,
|
||||
spv::ImageFormatUnknown);
|
||||
imageFormat);
|
||||
|
||||
// We'll declare the texture variable with the color type
|
||||
// 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
|
||||
const uint32_t typeId = getVectorTypeId(value.type);
|
||||
|
||||
// TODO add signed min/max
|
||||
switch (ins.op) {
|
||||
case DxbcOpcode::ImmAtomicExch:
|
||||
value.id = m_module.opAtomicExchange(typeId,
|
||||
@ -3140,13 +3153,6 @@ namespace dxvk {
|
||||
const DxbcRegisterValue texCoord = emitRegisterLoad(
|
||||
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
|
||||
DxbcRegisterValue uavValue;
|
||||
uavValue.type.ctype = uavInfo.sampledType;
|
||||
@ -4237,14 +4243,6 @@ namespace dxvk {
|
||||
// of obtaining the final pointer are used.
|
||||
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
|
||||
const DxbcRegisterValue addressValue = [&] {
|
||||
switch (resourceInfo.type) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "../spirv/spirv_module.h"
|
||||
|
||||
#include "dxbc_analysis.h"
|
||||
#include "dxbc_chunk_isgn.h"
|
||||
#include "dxbc_decoder.h"
|
||||
#include "dxbc_defs.h"
|
||||
@ -312,7 +313,8 @@ namespace dxvk {
|
||||
const DxbcOptions& options,
|
||||
const DxbcProgramVersion& version,
|
||||
const Rc<DxbcIsgn>& isgn,
|
||||
const Rc<DxbcIsgn>& osgn);
|
||||
const Rc<DxbcIsgn>& osgn,
|
||||
const DxbcAnalysisInfo& analysis);
|
||||
~DxbcCompiler();
|
||||
|
||||
/**
|
||||
@ -337,6 +339,8 @@ namespace dxvk {
|
||||
Rc<DxbcIsgn> m_isgn;
|
||||
Rc<DxbcIsgn> m_osgn;
|
||||
|
||||
const DxbcAnalysisInfo* m_analysis;
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Resource slot description for the shader. This will
|
||||
// be used to map D3D11 bindings to DXVK bindings.
|
||||
|
@ -45,12 +45,16 @@ namespace dxvk {
|
||||
if (m_shexChunk == nullptr)
|
||||
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
||||
|
||||
DxbcAnalysisInfo analysisInfo;
|
||||
|
||||
DxbcAnalyzer analyzer(options,
|
||||
m_shexChunk->version());
|
||||
m_shexChunk->version(),
|
||||
analysisInfo);
|
||||
|
||||
DxbcCompiler compiler(options,
|
||||
m_shexChunk->version(),
|
||||
m_isgnChunk, m_osgnChunk);
|
||||
m_isgnChunk, m_osgnChunk,
|
||||
analysisInfo);
|
||||
|
||||
this->runAnalyzer(analyzer, m_shexChunk->slice());
|
||||
this->runCompiler(compiler, m_shexChunk->slice());
|
||||
|
Loading…
Reference in New Issue
Block a user