1
0
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:
Philip Rebohle 2018-03-23 01:04:04 +01:00
parent 44d8d6b8c3
commit abb90086d5
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
5 changed files with 64 additions and 29 deletions

View File

@ -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;
}
}
}

View File

@ -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;
};

View File

@ -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) {

View File

@ -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.

View File

@ -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());