mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-04-05 16:40:17 +02:00
[dxbc] Gather binding info during shader compilation
This commit is contained in:
parent
5f16faaae0
commit
75599780f2
@ -108,6 +108,47 @@ namespace dxvk {
|
|||||||
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
|
m_analysis->uavInfos[registerId].nonInvariantAccess = true;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case DxbcInstClass::Declaration: {
|
||||||
|
switch (ins.op) {
|
||||||
|
case DxbcOpcode::DclConstantBuffer: {
|
||||||
|
uint32_t registerId = ins.dst[0].idx[0].offset;
|
||||||
|
|
||||||
|
if (registerId < DxbcConstBufBindingCount)
|
||||||
|
m_analysis->bindings.cbvMask |= 1u << registerId;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DxbcOpcode::DclSampler: {
|
||||||
|
uint32_t registerId = ins.dst[0].idx[0].offset;
|
||||||
|
|
||||||
|
if (registerId < DxbcSamplerBindingCount)
|
||||||
|
m_analysis->bindings.samplerMask |= 1u << registerId;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DxbcOpcode::DclResource:
|
||||||
|
case DxbcOpcode::DclResourceRaw:
|
||||||
|
case DxbcOpcode::DclResourceStructured: {
|
||||||
|
uint32_t registerId = ins.dst[0].idx[0].offset;
|
||||||
|
|
||||||
|
uint32_t idx = registerId / 64u;
|
||||||
|
uint32_t bit = registerId % 64u;
|
||||||
|
|
||||||
|
if (registerId < DxbcResourceBindingCount)
|
||||||
|
m_analysis->bindings.srvMask[idx] |= uint64_t(1u) << bit;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case DxbcOpcode::DclUavTyped:
|
||||||
|
case DxbcOpcode::DclUavRaw:
|
||||||
|
case DxbcOpcode::DclUavStructured: {
|
||||||
|
uint32_t registerId = ins.dst[0].idx[0].offset;
|
||||||
|
|
||||||
|
if (registerId < DxbcUavBindingCount)
|
||||||
|
m_analysis->bindings.uavMask |= uint64_t(1u) << registerId;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxbcClipCullInfo clipCullIn;
|
DxbcClipCullInfo clipCullIn;
|
||||||
DxbcClipCullInfo clipCullOut;
|
DxbcClipCullInfo clipCullOut;
|
||||||
|
|
||||||
|
DxbcBindingMask bindings = { };
|
||||||
|
|
||||||
bool usesDerivatives = false;
|
bool usesDerivatives = false;
|
||||||
bool usesKill = false;
|
bool usesKill = false;
|
||||||
|
@ -10,9 +10,8 @@ namespace dxvk {
|
|||||||
case DxbcProgramType::HullShader : return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
case DxbcProgramType::HullShader : return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
||||||
case DxbcProgramType::DomainShader : return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
|
case DxbcProgramType::DomainShader : return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
|
||||||
case DxbcProgramType::ComputeShader : return VK_SHADER_STAGE_COMPUTE_BIT;
|
case DxbcProgramType::ComputeShader : return VK_SHADER_STAGE_COMPUTE_BIT;
|
||||||
|
default: throw DxvkError("DxbcProgramInfo::shaderStage: Unsupported program type");
|
||||||
}
|
}
|
||||||
|
|
||||||
throw DxvkError("DxbcProgramInfo::shaderStage: Unsupported program type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -24,9 +23,8 @@ namespace dxvk {
|
|||||||
case DxbcProgramType::HullShader : return spv::ExecutionModelTessellationControl;
|
case DxbcProgramType::HullShader : return spv::ExecutionModelTessellationControl;
|
||||||
case DxbcProgramType::DomainShader : return spv::ExecutionModelTessellationEvaluation;
|
case DxbcProgramType::DomainShader : return spv::ExecutionModelTessellationEvaluation;
|
||||||
case DxbcProgramType::ComputeShader : return spv::ExecutionModelGLCompute;
|
case DxbcProgramType::ComputeShader : return spv::ExecutionModelGLCompute;
|
||||||
|
default: throw DxvkError("DxbcProgramInfo::executionModel: Unsupported program type");
|
||||||
}
|
}
|
||||||
|
|
||||||
throw DxvkError("DxbcProgramInfo::executionModel: Unsupported program type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,11 @@ namespace dxvk {
|
|||||||
HullShader = 3,
|
HullShader = 3,
|
||||||
DomainShader = 4,
|
DomainShader = 4,
|
||||||
ComputeShader = 5,
|
ComputeShader = 5,
|
||||||
|
|
||||||
|
Count
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using DxbcProgramTypeFlags = Flags<DxbcProgramType>;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -237,6 +237,7 @@ namespace dxvk {
|
|||||||
case DxbcProgramType::GeometryShader: this->emitGsFinalize(); break;
|
case DxbcProgramType::GeometryShader: this->emitGsFinalize(); break;
|
||||||
case DxbcProgramType::PixelShader: this->emitPsFinalize(); break;
|
case DxbcProgramType::PixelShader: this->emitPsFinalize(); break;
|
||||||
case DxbcProgramType::ComputeShader: this->emitCsFinalize(); break;
|
case DxbcProgramType::ComputeShader: this->emitCsFinalize(); break;
|
||||||
|
default: throw DxvkError("Invalid shader stage");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit float control mode if the extension is supported
|
// Emit float control mode if the extension is supported
|
||||||
@ -6138,7 +6139,7 @@ namespace dxvk {
|
|||||||
case DxbcProgramType::HullShader: emitHsSystemValueStore(sv, mask, value); break;
|
case DxbcProgramType::HullShader: emitHsSystemValueStore(sv, mask, value); break;
|
||||||
case DxbcProgramType::DomainShader: emitDsSystemValueStore(sv, mask, value); break;
|
case DxbcProgramType::DomainShader: emitDsSystemValueStore(sv, mask, value); break;
|
||||||
case DxbcProgramType::PixelShader: emitPsSystemValueStore(sv, mask, value); break;
|
case DxbcProgramType::PixelShader: emitPsSystemValueStore(sv, mask, value); break;
|
||||||
case DxbcProgramType::ComputeShader: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6822,6 +6823,7 @@ namespace dxvk {
|
|||||||
case DxbcProgramType::GeometryShader: emitGsInit(); break;
|
case DxbcProgramType::GeometryShader: emitGsInit(); break;
|
||||||
case DxbcProgramType::PixelShader: emitPsInit(); break;
|
case DxbcProgramType::PixelShader: emitPsInit(); break;
|
||||||
case DxbcProgramType::ComputeShader: emitCsInit(); break;
|
case DxbcProgramType::ComputeShader: emitCsInit(); break;
|
||||||
|
default: throw DxvkError("Invalid shader stage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
Rc<DxvkShader> DxbcModule::compile(
|
Rc<DxvkShader> DxbcModule::compile(
|
||||||
const DxbcModuleInfo& moduleInfo,
|
const DxbcModuleInfo& moduleInfo,
|
||||||
const std::string& fileName) const {
|
const std::string& fileName) {
|
||||||
if (m_shexChunk == nullptr)
|
if (m_shexChunk == nullptr)
|
||||||
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
throw DxvkError("DxbcModule::compile: No SHDR/SHEX chunk");
|
||||||
|
|
||||||
@ -54,6 +54,8 @@ namespace dxvk {
|
|||||||
m_psgnChunk, analysisInfo);
|
m_psgnChunk, analysisInfo);
|
||||||
|
|
||||||
this->runAnalyzer(analyzer, m_shexChunk->slice());
|
this->runAnalyzer(analyzer, m_shexChunk->slice());
|
||||||
|
|
||||||
|
m_bindings = std::make_optional(analysisInfo.bindings);
|
||||||
|
|
||||||
DxbcCompiler compiler(
|
DxbcCompiler compiler(
|
||||||
fileName, moduleInfo,
|
fileName, moduleInfo,
|
||||||
@ -62,7 +64,7 @@ namespace dxvk {
|
|||||||
m_psgnChunk, analysisInfo);
|
m_psgnChunk, analysisInfo);
|
||||||
|
|
||||||
this->runCompiler(compiler, m_shexChunk->slice());
|
this->runCompiler(compiler, m_shexChunk->slice());
|
||||||
|
|
||||||
return compiler.finalize();
|
return compiler.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "dxbc_header.h"
|
#include "dxbc_header.h"
|
||||||
#include "dxbc_modinfo.h"
|
#include "dxbc_modinfo.h"
|
||||||
#include "dxbc_reader.h"
|
#include "dxbc_reader.h"
|
||||||
|
#include "dxbc_util.h"
|
||||||
|
|
||||||
// References used for figuring out DXBC:
|
// References used for figuring out DXBC:
|
||||||
// - https://github.com/tgjones/slimshader-cpp
|
// - https://github.com/tgjones/slimshader-cpp
|
||||||
@ -41,7 +42,16 @@ namespace dxvk {
|
|||||||
|
|
||||||
return m_shexChunk->programInfo();
|
return m_shexChunk->programInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Queries shader binding mask
|
||||||
|
*
|
||||||
|
* Only valid after successfully compiling the shader.
|
||||||
|
*/
|
||||||
|
std::optional<DxbcBindingMask> bindings() const {
|
||||||
|
return m_bindings;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Input and output signature chunks
|
* \brief Input and output signature chunks
|
||||||
*
|
*
|
||||||
@ -50,7 +60,7 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
Rc<DxbcIsgn> isgn() const { return m_isgnChunk; }
|
Rc<DxbcIsgn> isgn() const { return m_isgnChunk; }
|
||||||
Rc<DxbcIsgn> osgn() const { return m_osgnChunk; }
|
Rc<DxbcIsgn> osgn() const { return m_osgnChunk; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Compiles DXBC shader to SPIR-V module
|
* \brief Compiles DXBC shader to SPIR-V module
|
||||||
*
|
*
|
||||||
@ -61,7 +71,7 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
Rc<DxvkShader> compile(
|
Rc<DxvkShader> compile(
|
||||||
const DxbcModuleInfo& moduleInfo,
|
const DxbcModuleInfo& moduleInfo,
|
||||||
const std::string& fileName) const;
|
const std::string& fileName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Compiles a pass-through geometry shader
|
* \brief Compiles a pass-through geometry shader
|
||||||
@ -85,6 +95,8 @@ namespace dxvk {
|
|||||||
Rc<DxbcIsgn> m_osgnChunk;
|
Rc<DxbcIsgn> m_osgnChunk;
|
||||||
Rc<DxbcIsgn> m_psgnChunk;
|
Rc<DxbcIsgn> m_psgnChunk;
|
||||||
Rc<DxbcShex> m_shexChunk;
|
Rc<DxbcShex> m_shexChunk;
|
||||||
|
|
||||||
|
std::optional<DxbcBindingMask> m_bindings;
|
||||||
|
|
||||||
void runAnalyzer(
|
void runAnalyzer(
|
||||||
DxbcAnalyzer& analyzer,
|
DxbcAnalyzer& analyzer,
|
||||||
|
@ -33,6 +33,43 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Shader binding mask
|
||||||
|
*
|
||||||
|
* Stores a bit masks of resource bindings
|
||||||
|
* that are accessed by any given shader.
|
||||||
|
*/
|
||||||
|
struct DxbcBindingMask {
|
||||||
|
uint32_t cbvMask = 0u;
|
||||||
|
uint32_t samplerMask = 0u;
|
||||||
|
uint64_t uavMask = 0u;
|
||||||
|
std::array<uint64_t, 2> srvMask = { };
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
cbvMask = 0u;
|
||||||
|
samplerMask = 0u;
|
||||||
|
uavMask = 0u;
|
||||||
|
srvMask = { };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const {
|
||||||
|
uint64_t mask = (uint64_t(cbvMask) | uint64_t(samplerMask) << 32u)
|
||||||
|
| (uavMask | srvMask[0] | srvMask[1]);
|
||||||
|
return !mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
DxbcBindingMask operator & (const DxbcBindingMask& other) const {
|
||||||
|
DxbcBindingMask result = *this;
|
||||||
|
result.cbvMask &= other.cbvMask;
|
||||||
|
result.samplerMask &= other.samplerMask;
|
||||||
|
result.uavMask &= other.uavMask;
|
||||||
|
result.srvMask[0] &= other.srvMask[0];
|
||||||
|
result.srvMask[1] &= other.srvMask[1];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Computes first binding index for a given stage
|
* \brief Computes first binding index for a given stage
|
||||||
*
|
*
|
||||||
@ -124,4 +161,4 @@ namespace dxvk {
|
|||||||
uint32_t primitiveVertexCount(
|
uint32_t primitiveVertexCount(
|
||||||
DxbcPrimitive primitive);
|
DxbcPrimitive primitive);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user