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:
parent
32c2d91961
commit
30fa9df868
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "dxvk_compute.h"
|
#include "dxvk_compute.h"
|
||||||
#include "dxvk_device.h"
|
#include "dxvk_device.h"
|
||||||
|
#include "dxvk_graphics.h"
|
||||||
#include "dxvk_pipemanager.h"
|
#include "dxvk_pipemanager.h"
|
||||||
#include "dxvk_spec_const.h"
|
#include "dxvk_spec_const.h"
|
||||||
#include "dxvk_state_cache.h"
|
#include "dxvk_state_cache.h"
|
||||||
@ -106,23 +107,12 @@ namespace dxvk {
|
|||||||
Logger::debug(str::format(" cs : ", m_shaders.cs->debugName()));
|
Logger::debug(str::format(" cs : ", m_shaders.cs->debugName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t specConstantMask = m_shaders.cs->getSpecConstantMask();
|
DxvkPipelineSpecConstantState scState(m_shaders.cs->getSpecConstantMask(), state.sc);
|
||||||
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();
|
|
||||||
|
|
||||||
DxvkShaderStageInfo stageInfo(m_device);
|
DxvkShaderStageInfo stageInfo(m_device);
|
||||||
stageInfo.addStage(VK_SHADER_STAGE_COMPUTE_BIT,
|
stageInfo.addStage(VK_SHADER_STAGE_COMPUTE_BIT,
|
||||||
m_shaders.cs->getCode(m_bindings, DxvkShaderModuleCreateInfo()),
|
m_shaders.cs->getCode(m_bindings, DxvkShaderModuleCreateInfo()),
|
||||||
&specInfo);
|
&scState.scInfo);
|
||||||
|
|
||||||
VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO };
|
VkComputePipelineCreateInfo info = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO };
|
||||||
info.stage = *stageInfo.getStageInfos();
|
info.stage = *stageInfo.getStageInfos();
|
||||||
|
@ -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(
|
DxvkGraphicsPipeline::DxvkGraphicsPipeline(
|
||||||
DxvkDevice* device,
|
DxvkDevice* device,
|
||||||
DxvkPipelineManager* pipeMgr,
|
DxvkPipelineManager* pipeMgr,
|
||||||
@ -915,45 +977,34 @@ namespace dxvk {
|
|||||||
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE;
|
dynamicStates[dynamicStateCount++] = VK_DYNAMIC_STATE_FRONT_FACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up some specialization constants
|
// Set up pipeline state
|
||||||
DxvkSpecConstants specData;
|
DxvkGraphicsPipelineVertexInputState viState(m_device, state, m_shaders.vs.ptr());
|
||||||
|
DxvkGraphicsPipelinePreRasterizationState prState(m_device, state, m_shaders.gs.ptr());
|
||||||
for (uint32_t i = 0; i < MaxNumSpecConstants; i++) {
|
DxvkGraphicsPipelineFragmentShaderState fsState(m_device, state);
|
||||||
if (m_specConstantMask & (1u << i))
|
DxvkGraphicsPipelineFragmentOutputState foState(m_device, state, m_shaders.fs.ptr());
|
||||||
specData.set(i, state.sc.specConstants[i], 0u);
|
DxvkPipelineSpecConstantState scState(m_specConstantMask, state.sc);
|
||||||
}
|
|
||||||
|
|
||||||
if (m_specConstantMask & (1u << MaxNumSpecConstants))
|
|
||||||
specData.set(MaxNumSpecConstants, 1u, 0u);
|
|
||||||
|
|
||||||
VkSpecializationInfo specInfo = specData.getSpecInfo();
|
|
||||||
|
|
||||||
// Build stage infos for all provided shaders
|
// Build stage infos for all provided shaders
|
||||||
DxvkShaderStageInfo stageInfo(m_device);
|
DxvkShaderStageInfo stageInfo(m_device);
|
||||||
|
|
||||||
if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) {
|
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)
|
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 {
|
} 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)
|
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)
|
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)
|
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)
|
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 };
|
VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
|
||||||
dyInfo.dynamicStateCount = dynamicStateCount;
|
dyInfo.dynamicStateCount = dynamicStateCount;
|
||||||
dyInfo.pDynamicStates = dynamicStates.data();
|
dyInfo.pDynamicStates = dynamicStates.data();
|
||||||
|
@ -186,7 +186,34 @@ namespace dxvk {
|
|||||||
size_t hash() const;
|
size_t hash() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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
|
* \brief Flags that describe pipeline properties
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user