2018-03-22 20:01:57 +01:00
|
|
|
#include "dxbc_analysis.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
DxbcAnalyzer::DxbcAnalyzer(
|
2018-06-23 17:14:35 +02:00
|
|
|
const DxbcModuleInfo& moduleInfo,
|
2018-10-08 09:34:56 +02:00
|
|
|
const DxbcProgramInfo& programInfo,
|
2018-03-23 19:48:07 +01:00
|
|
|
const Rc<DxbcIsgn>& isgn,
|
|
|
|
const Rc<DxbcIsgn>& osgn,
|
2019-01-26 14:52:29 +01:00
|
|
|
const Rc<DxbcIsgn>& psgn,
|
2018-03-23 01:04:04 +01:00
|
|
|
DxbcAnalysisInfo& analysis)
|
2018-03-23 19:48:07 +01:00
|
|
|
: m_isgn (isgn),
|
|
|
|
m_osgn (osgn),
|
2019-01-26 14:52:29 +01:00
|
|
|
m_psgn (psgn),
|
2018-03-23 19:48:07 +01:00
|
|
|
m_analysis(&analysis) {
|
|
|
|
// Get number of clipping and culling planes from the
|
|
|
|
// input and output signatures. We will need this to
|
|
|
|
// declare the shader input and output interfaces.
|
|
|
|
m_analysis->clipCullIn = getClipCullInfo(m_isgn);
|
|
|
|
m_analysis->clipCullOut = getClipCullInfo(m_osgn);
|
2018-03-22 20:01:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DxbcAnalyzer::~DxbcAnalyzer() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-23 01:04:04 +01:00
|
|
|
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;
|
2021-09-09 15:39:35 +02:00
|
|
|
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
|
2018-03-23 01:04:04 +01:00
|
|
|
}
|
|
|
|
} break;
|
2018-05-26 17:08:08 +02:00
|
|
|
|
|
|
|
case DxbcInstClass::TextureSample:
|
2021-02-21 14:24:54 +01:00
|
|
|
case DxbcInstClass::TextureGather:
|
|
|
|
case DxbcInstClass::TextureQueryLod:
|
2018-05-26 17:08:08 +02:00
|
|
|
case DxbcInstClass::VectorDeriv: {
|
|
|
|
m_analysis->usesDerivatives = true;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case DxbcInstClass::ControlFlow: {
|
|
|
|
if (ins.op == DxbcOpcode::Discard)
|
|
|
|
m_analysis->usesKill = true;
|
|
|
|
} break;
|
|
|
|
|
2021-09-09 15:39:35 +02:00
|
|
|
case DxbcInstClass::BufferLoad: {
|
|
|
|
uint32_t operandId = ins.op == DxbcOpcode::LdStructured ? 2 : 1;
|
2022-08-22 05:11:59 +02:00
|
|
|
bool sparseFeedback = ins.dstCount == 2;
|
2021-09-09 15:39:35 +02:00
|
|
|
|
|
|
|
if (ins.src[operandId].type == DxbcOperandType::UnorderedAccessView) {
|
|
|
|
const uint32_t registerId = ins.src[operandId].idx[0].offset;
|
|
|
|
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT;
|
2022-08-22 05:11:59 +02:00
|
|
|
m_analysis->uavInfos[registerId].sparseFeedback |= sparseFeedback;
|
|
|
|
} else if (ins.src[operandId].type == DxbcOperandType::Resource) {
|
|
|
|
const uint32_t registerId = ins.src[operandId].idx[0].offset;
|
|
|
|
m_analysis->srvInfos[registerId].sparseFeedback |= sparseFeedback;
|
2021-09-09 15:39:35 +02:00
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case DxbcInstClass::BufferStore: {
|
|
|
|
if (ins.dst[0].type == DxbcOperandType::UnorderedAccessView) {
|
|
|
|
const uint32_t registerId = ins.dst[0].idx[0].offset;
|
|
|
|
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_WRITE_BIT;
|
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2018-03-23 01:04:04 +01:00
|
|
|
case DxbcInstClass::TypedUavLoad: {
|
|
|
|
const uint32_t registerId = ins.src[1].idx[0].offset;
|
|
|
|
m_analysis->uavInfos[registerId].accessTypedLoad = true;
|
2021-09-09 15:39:35 +02:00
|
|
|
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_READ_BIT;
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case DxbcInstClass::TypedUavStore: {
|
|
|
|
const uint32_t registerId = ins.dst[0].idx[0].offset;
|
|
|
|
m_analysis->uavInfos[registerId].accessFlags |= VK_ACCESS_SHADER_WRITE_BIT;
|
2018-03-23 01:04:04 +01:00
|
|
|
} break;
|
|
|
|
|
|
|
|
default:
|
2022-03-24 12:43:39 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < ins.dstCount; i++) {
|
|
|
|
if (ins.dst[0].type == DxbcOperandType::IndexableTemp) {
|
|
|
|
uint32_t index = ins.dst[0].idx[0].offset;
|
|
|
|
m_analysis->xRegMasks[index] |= ins.dst[0].mask;
|
|
|
|
}
|
2018-03-23 01:04:04 +01:00
|
|
|
}
|
2018-03-22 20:01:57 +01:00
|
|
|
}
|
|
|
|
|
2018-03-23 19:48:07 +01:00
|
|
|
|
|
|
|
DxbcClipCullInfo DxbcAnalyzer::getClipCullInfo(const Rc<DxbcIsgn>& sgn) const {
|
|
|
|
DxbcClipCullInfo result;
|
|
|
|
|
2018-03-23 21:38:21 +01:00
|
|
|
if (sgn != nullptr) {
|
|
|
|
for (auto e = sgn->begin(); e != sgn->end(); e++) {
|
|
|
|
const uint32_t componentCount = e->componentMask.popCount();
|
|
|
|
|
|
|
|
if (e->systemValue == DxbcSystemValue::ClipDistance)
|
|
|
|
result.numClipPlanes += componentCount;
|
|
|
|
if (e->systemValue == DxbcSystemValue::CullDistance)
|
|
|
|
result.numCullPlanes += componentCount;
|
|
|
|
}
|
2018-03-23 19:48:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-10-08 09:34:56 +02:00
|
|
|
}
|