[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.pNext = nullptr;
m_stage.flags = 0;
m_stage.stage = shader->stage();
m_stage.stage = shader->info().stage;
m_stage.module = VK_NULL_HANDLE;
m_stage.pName = "main";
m_stage.pSpecializationInfo = nullptr;
@ -105,14 +105,44 @@ namespace dxvk {
SpirvCodeBuffer code,
const DxvkShaderOptions& options,
DxvkShaderConstData&& constData)
: m_stage(stage), m_code(code), m_interface(iface),
m_options(options), m_constData(std::move(constData)) {
// Write back resource slot infos
for (uint32_t i = 0; i < slotCount; i++)
m_slots.push_back(slotInfos[i]);
// Gather the offsets where the binding IDs
// are stored so we can quickly remap them.
: DxvkShader(DxvkShaderCreateInfo {
stage, slotCount, slotInfos,
iface.inputSlots, iface.outputSlots,
iface.pushConstOffset, iface.pushConstSize,
uint32_t(constData.sizeInBytes()),
reinterpret_cast<const char*>(constData.data()),
options.rasterizedStream,
{ 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;
for (auto ins : code) {
@ -147,8 +177,8 @@ namespace dxvk {
}
}
}
DxvkShader::~DxvkShader() {
}
@ -157,12 +187,12 @@ namespace dxvk {
void DxvkShader::defineResourceSlots(
DxvkDescriptorSlotMapping& mapping) const {
for (const auto& slot : m_slots)
mapping.defineSlot(m_stage, slot);
mapping.defineSlot(m_info.stage, slot);
if (m_interface.pushConstSize) {
mapping.definePushConstRange(m_stage,
m_interface.pushConstOffset,
m_interface.pushConstSize);
if (m_info.pushConstSize) {
mapping.definePushConstRange(m_info.stage,
m_info.pushConstOffset,
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
*/
@ -146,15 +171,27 @@ namespace dxvk {
SpirvCodeBuffer code,
const DxvkShaderOptions& options,
DxvkShaderConstData&& constData);
DxvkShader(
const DxvkShaderCreateInfo& info,
SpirvCodeBuffer&& spirv);
~DxvkShader();
/**
* \brief Shader info
* \returns Shader info
*/
const DxvkShaderCreateInfo& info() const {
return m_info;
}
/**
* \brief Shader stage
* \returns Shader stage
*/
VkShaderStageFlagBits stage() const {
return m_stage;
return m_info.stage;
}
/**
@ -197,7 +234,12 @@ namespace dxvk {
* \returns Shader interface slots
*/
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
*/
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.
* \returns Shader constant data
*/
const DxvkShaderConstData& shaderConstants() const {
return m_constData;
DxvkShaderConstData shaderConstants() const {
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:
VkShaderStageFlagBits m_stage;
SpirvCompressedBuffer m_code;
DxvkShaderCreateInfo m_info;
SpirvCompressedBuffer m_code;
std::vector<DxvkResourceSlot> m_slots;
std::vector<size_t> m_idOffsets;
DxvkInterfaceSlots m_interface;
DxvkShaderFlags m_flags;
DxvkShaderOptions m_options;
DxvkShaderConstData m_constData;
DxvkShaderKey m_key;
size_t m_hash = 0;
size_t m_o1IdxOffset = 0;
size_t m_o1LocOffset = 0;
size_t m_o1IdxOffset = 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);