1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 10:54:16 +01:00

[dxvk] Introduce new way to create DxvkShader objects

This commit is contained in:
Philip Rebohle 2022-04-09 13:35:06 +02:00 committed by Philip Rebohle
parent 736f743ae4
commit b0db58f098
2 changed files with 109 additions and 31 deletions

View File

@ -64,7 +64,7 @@ namespace dxvk {
m_stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; m_stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
m_stage.pNext = nullptr; m_stage.pNext = nullptr;
m_stage.flags = 0; m_stage.flags = 0;
m_stage.stage = shader->stage(); m_stage.stage = shader->info().stage;
m_stage.module = VK_NULL_HANDLE; m_stage.module = VK_NULL_HANDLE;
m_stage.pName = "main"; m_stage.pName = "main";
m_stage.pSpecializationInfo = nullptr; m_stage.pSpecializationInfo = nullptr;
@ -105,14 +105,44 @@ namespace dxvk {
SpirvCodeBuffer code, SpirvCodeBuffer code,
const DxvkShaderOptions& options, const DxvkShaderOptions& options,
DxvkShaderConstData&& constData) DxvkShaderConstData&& constData)
: m_stage(stage), m_code(code), m_interface(iface), : DxvkShader(DxvkShaderCreateInfo {
m_options(options), m_constData(std::move(constData)) { stage, slotCount, slotInfos,
// Write back resource slot infos iface.inputSlots, iface.outputSlots,
for (uint32_t i = 0; i < slotCount; i++) iface.pushConstOffset, iface.pushConstSize,
m_slots.push_back(slotInfos[i]); uint32_t(constData.sizeInBytes()),
reinterpret_cast<const char*>(constData.data()),
// Gather the offsets where the binding IDs options.rasterizedStream,
// are stored so we can quickly remap them. { options.xfbStrides[0], options.xfbStrides[1],
options.xfbStrides[2], options.xfbStrides[3] }
}, std::move(code)) {
}
DxvkShader::DxvkShader(
const DxvkShaderCreateInfo& info,
SpirvCodeBuffer&& spirv)
: m_info(info), m_code(spirv) {
m_info.resourceSlots = nullptr;
m_info.uniformData = nullptr;
// Copy resource binding slot infos
if (info.resourceSlotCount) {
m_slots.resize(info.resourceSlotCount);
for (uint32_t i = 0; i < info.resourceSlotCount; i++)
m_slots[i] = info.resourceSlots[i];
m_info.resourceSlots = m_slots.data();
}
// Copy uniform buffer data
if (info.uniformSize) {
m_uniformData.resize(info.uniformSize);
std::memcpy(m_uniformData.data(), info.uniformData, info.uniformSize);
m_info.uniformData = m_uniformData.data();
}
// Run an analysis pass over the SPIR-V code to gather some
// info that we may need during pipeline compilation.
SpirvCodeBuffer code = std::move(spirv);
uint32_t o1VarId = 0; uint32_t o1VarId = 0;
for (auto ins : code) { for (auto ins : code) {
@ -147,8 +177,8 @@ namespace dxvk {
} }
} }
} }
DxvkShader::~DxvkShader() { DxvkShader::~DxvkShader() {
} }
@ -157,12 +187,12 @@ namespace dxvk {
void DxvkShader::defineResourceSlots( void DxvkShader::defineResourceSlots(
DxvkDescriptorSlotMapping& mapping) const { DxvkDescriptorSlotMapping& mapping) const {
for (const auto& slot : m_slots) for (const auto& slot : m_slots)
mapping.defineSlot(m_stage, slot); mapping.defineSlot(m_info.stage, slot);
if (m_interface.pushConstSize) { if (m_info.pushConstSize) {
mapping.definePushConstRange(m_stage, mapping.definePushConstRange(m_info.stage,
m_interface.pushConstOffset, m_info.pushConstOffset,
m_interface.pushConstSize); m_info.pushConstSize);
} }
} }

View File

@ -117,6 +117,31 @@ namespace dxvk {
}; };
/**
* \brief Shader info
*/
struct DxvkShaderCreateInfo {
/// Shader stage
VkShaderStageFlagBits stage;
/// Descriptor info
uint32_t resourceSlotCount = 0;
const DxvkResourceSlot* resourceSlots = nullptr;
/// Input and output register mask
uint32_t inputMask = 0;
uint32_t outputMask = 0;
/// Push constant range
uint32_t pushConstOffset = 0;
uint32_t pushConstSize = 0;
/// Uniform buffer data
uint32_t uniformSize = 0;
const char* uniformData = nullptr;
/// Rasterized stream, or -1
int32_t xfbRasterizedStream = 0;
/// Transform feedback vertex strides
uint32_t xfbStrides[MaxNumXfbBuffers] = { };
};
/** /**
* \brief Shader module create info * \brief Shader module create info
*/ */
@ -146,15 +171,27 @@ namespace dxvk {
SpirvCodeBuffer code, SpirvCodeBuffer code,
const DxvkShaderOptions& options, const DxvkShaderOptions& options,
DxvkShaderConstData&& constData); DxvkShaderConstData&& constData);
DxvkShader(
const DxvkShaderCreateInfo& info,
SpirvCodeBuffer&& spirv);
~DxvkShader(); ~DxvkShader();
/**
* \brief Shader info
* \returns Shader info
*/
const DxvkShaderCreateInfo& info() const {
return m_info;
}
/** /**
* \brief Shader stage * \brief Shader stage
* \returns Shader stage * \returns Shader stage
*/ */
VkShaderStageFlagBits stage() const { VkShaderStageFlagBits stage() const {
return m_stage; return m_info.stage;
} }
/** /**
@ -197,7 +234,12 @@ namespace dxvk {
* \returns Shader interface slots * \returns Shader interface slots
*/ */
DxvkInterfaceSlots interfaceSlots() const { DxvkInterfaceSlots interfaceSlots() const {
return m_interface; DxvkInterfaceSlots iface = { };
iface.inputSlots = m_info.inputMask;
iface.outputSlots = m_info.outputMask;
iface.pushConstOffset = m_info.pushConstOffset;
iface.pushConstSize = m_info.pushConstSize;
return iface;
} }
/** /**
@ -205,7 +247,11 @@ namespace dxvk {
* \returns Shader options * \returns Shader options
*/ */
DxvkShaderOptions shaderOptions() const { DxvkShaderOptions shaderOptions() const {
return m_options; DxvkShaderOptions options = { };
options.rasterizedStream = m_info.xfbRasterizedStream;
for (uint32_t i = 0; i < MaxNumXfbBuffers; i++)
options.xfbStrides[i] = m_info.xfbStrides[i];
return options;
} }
/** /**
@ -216,8 +262,11 @@ namespace dxvk {
* shader object. * shader object.
* \returns Shader constant data * \returns Shader constant data
*/ */
const DxvkShaderConstData& shaderConstants() const { DxvkShaderConstData shaderConstants() const {
return m_constData; return m_info.uniformSize
? DxvkShaderConstData(m_info.uniformSize / sizeof(uint32_t),
reinterpret_cast<const uint32_t*>(m_info.uniformData))
: DxvkShaderConstData();
} }
/** /**
@ -279,20 +328,19 @@ namespace dxvk {
private: private:
VkShaderStageFlagBits m_stage; DxvkShaderCreateInfo m_info;
SpirvCompressedBuffer m_code; SpirvCompressedBuffer m_code;
std::vector<DxvkResourceSlot> m_slots;
std::vector<size_t> m_idOffsets;
DxvkInterfaceSlots m_interface;
DxvkShaderFlags m_flags; DxvkShaderFlags m_flags;
DxvkShaderOptions m_options;
DxvkShaderConstData m_constData;
DxvkShaderKey m_key; DxvkShaderKey m_key;
size_t m_hash = 0; size_t m_hash = 0;
size_t m_o1IdxOffset = 0; size_t m_o1IdxOffset = 0;
size_t m_o1LocOffset = 0; size_t m_o1LocOffset = 0;
std::vector<DxvkResourceSlot> m_slots;
std::vector<char> m_uniformData;
std::vector<size_t> m_idOffsets;
static void eliminateInput(SpirvCodeBuffer& code, uint32_t location); static void eliminateInput(SpirvCodeBuffer& code, uint32_t location);