1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-04 19:29:15 +01:00

[dxvk] Introduce DxvkGraphicsPipelineSpecConstantState

This commit is contained in:
Philip Rebohle 2022-07-30 23:38:22 +02:00
parent 32c2d91961
commit 30fa9df868
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 106 additions and 38 deletions

View File

@ -4,6 +4,7 @@
#include "dxvk_compute.h"
#include "dxvk_device.h"
#include "dxvk_graphics.h"
#include "dxvk_pipemanager.h"
#include "dxvk_spec_const.h"
#include "dxvk_state_cache.h"
@ -106,23 +107,12 @@ namespace dxvk {
Logger::debug(str::format(" cs : ", m_shaders.cs->debugName()));
}
uint32_t specConstantMask = m_shaders.cs->getSpecConstantMask();
DxvkSpecConstants specData;
for (uint32_t i = 0; i < MaxNumSpecConstants; i++) {
if (specConstantMask & (1u << i))
specData.set(i, state.sc.specConstants[i], 0u);
}
if (specConstantMask & (1u << MaxNumSpecConstants))
specData.set(MaxNumSpecConstants, 1u, 0u);
VkSpecializationInfo specInfo = specData.getSpecInfo();
DxvkPipelineSpecConstantState scState(m_shaders.cs->getSpecConstantMask(), state.sc);
DxvkShaderStageInfo stageInfo(m_device);
stageInfo.addStage(VK_SHADER_STAGE_COMPUTE_BIT,
m_shaders.cs->getCode(m_bindings, DxvkShaderModuleCreateInfo()),
&specInfo);
&scState.scInfo);
VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO };
info.stage = *stageInfo.getStageInfos();

View File

@ -601,6 +601,68 @@ namespace dxvk {
}
DxvkPipelineSpecConstantState::DxvkPipelineSpecConstantState() {
}
DxvkPipelineSpecConstantState::DxvkPipelineSpecConstantState(
uint32_t mask,
const DxvkScInfo& state) {
for (uint32_t i = 0; i < MaxNumSpecConstants; i++) {
if (mask & (1u << i))
addConstant(i, state.specConstants[i]);
}
if (mask & (1u << MaxNumSpecConstants))
addConstant(MaxNumSpecConstants, VK_TRUE);
if (scInfo.mapEntryCount) {
scInfo.pMapEntries = scConstantMap.data();
scInfo.dataSize = scInfo.mapEntryCount * sizeof(uint32_t);
scInfo.pData = scConstantData.data();
}
}
bool DxvkPipelineSpecConstantState::eq(const DxvkPipelineSpecConstantState& other) const {
bool eq = scInfo.mapEntryCount == other.scInfo.mapEntryCount;
for (uint32_t i = 0; i < scInfo.mapEntryCount && eq; i++) {
eq = scConstantMap[i].constantID == other.scConstantMap[i].constantID
&& scConstantData[i] == other.scConstantData[i];
}
return eq;
}
size_t DxvkPipelineSpecConstantState::hash() const {
DxvkHashState hash;
hash.add(scInfo.mapEntryCount);
for (uint32_t i = 0; i < scInfo.mapEntryCount; i++) {
hash.add(scConstantMap[i].constantID);
hash.add(scConstantData[i]);
}
return hash;
}
void DxvkPipelineSpecConstantState::addConstant(uint32_t id, uint32_t value) {
if (value) {
uint32_t index = scInfo.mapEntryCount++;
scConstantMap[index].constantID = id;
scConstantMap[index].offset = sizeof(uint32_t) * index;
scConstantMap[index].size = sizeof(uint32_t);
scConstantData[index] = value;
}
}
DxvkGraphicsPipeline::DxvkGraphicsPipeline(
DxvkDevice* device,
DxvkPipelineManager* pipeMgr,
@ -915,45 +977,34 @@ namespace dxvk {
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE;
}
// Set up some specialization constants
DxvkSpecConstants specData;
for (uint32_t i = 0; i < MaxNumSpecConstants; i++) {
if (m_specConstantMask & (1u << i))
specData.set(i, state.sc.specConstants[i], 0u);
}
if (m_specConstantMask & (1u << MaxNumSpecConstants))
specData.set(MaxNumSpecConstants, 1u, 0u);
VkSpecializationInfo specInfo = specData.getSpecInfo();
// Set up pipeline state
DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr());
DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr());
DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state);
DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr());
DxvkPipelineSpecConstantState scState(m_specConstantMask, state.sc);
// Build stage infos for all provided shaders
DxvkShaderStageInfo stageInfo(m_device);
if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) {
stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(), &specInfo);
stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, m_vsLibrary->getModuleIdentifier(), &scState.scInfo);
if (m_shaders.fs != nullptr)
stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(), &specInfo);
stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, m_fsLibrary->getModuleIdentifier(), &scState.scInfo);
} else {
stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, state), &specInfo);
stageInfo.addStage(VK_SHADER_STAGE_VERTEX_BIT, getShaderCode(m_shaders.vs, state), &scState.scInfo);
if (m_shaders.tcs != nullptr)
stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, state), &specInfo);
stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, getShaderCode(m_shaders.tcs, state), &scState.scInfo);
if (m_shaders.tes != nullptr)
stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, state), &specInfo);
stageInfo.addStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, getShaderCode(m_shaders.tes, state), &scState.scInfo);
if (m_shaders.gs != nullptr)
stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, state), &specInfo);
stageInfo.addStage(VK_SHADER_STAGE_GEOMETRY_BIT, getShaderCode(m_shaders.gs, state), &scState.scInfo);
if (m_shaders.fs != nullptr)
stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, state), &specInfo);
stageInfo.addStage(VK_SHADER_STAGE_FRAGMENT_BIT, getShaderCode(m_shaders.fs, state), &scState.scInfo);
}
DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr());
DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr());
DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state);
DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr());
VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
dyInfo.dynamicStateCount = dynamicStateCount;
dyInfo.pDynamicStates = dynamicStates.data();

View File

@ -187,6 +187,33 @@ namespace dxvk {
};
/**
* \brief Specialization constant state for pipelines
*
* Can only be used when all pipeline state is known.
*/
struct DxvkPipelineSpecConstantState {
DxvkPipelineSpecConstantState();
DxvkPipelineSpecConstantState(
uint32_t mask,
const DxvkScInfo& state);
VkSpecializationInfo scInfo = { };
std::array<VkSpecializationMapEntry, MaxNumSpecConstants + 1> scConstantMap = { };
std::array<uint32_t, MaxNumSpecConstants + 1> scConstantData = { };
bool eq(const DxvkPipelineSpecConstantState& other) const;
size_t hash() const;
private:
void addConstant(uint32_t id, uint32_t value);
};
/**
* \brief Flags that describe pipeline properties
*/