mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 13:24:10 +01:00
[dxvk] Implement push constant API
This commit is contained in:
parent
8931013234
commit
02768182f1
@ -1735,6 +1735,16 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::pushConstants(
|
||||
uint32_t offset,
|
||||
uint32_t size,
|
||||
const void* data) {
|
||||
std::memcpy(&m_state.pc.data[offset], data, size);
|
||||
|
||||
m_flags.set(DxvkContextFlag::DirtyPushConstants);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::resolveImage(
|
||||
const Rc<DxvkImage>& dstImage,
|
||||
const Rc<DxvkImage>& srcImage,
|
||||
@ -3232,8 +3242,12 @@ namespace dxvk {
|
||||
m_state.cp.state.bsBindingMask.clear();
|
||||
m_state.cp.pipeline = m_pipeMgr->createComputePipeline(m_state.cp.cs.shader);
|
||||
|
||||
if (m_state.cp.pipeline != nullptr)
|
||||
if (m_state.cp.pipeline != nullptr) {
|
||||
m_cmd->trackResource(m_state.cp.pipeline);
|
||||
|
||||
if (m_state.cp.pipeline->layout()->pushConstRange().size)
|
||||
m_flags.set(DxvkContextFlag::DirtyPushConstants);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3288,6 +3302,9 @@ namespace dxvk {
|
||||
if (m_state.gp.pipeline != nullptr) {
|
||||
m_state.gp.flags = m_state.gp.pipeline->flags();
|
||||
m_cmd->trackResource(m_state.gp.pipeline);
|
||||
|
||||
if (m_state.gp.pipeline->layout()->pushConstRange().size)
|
||||
m_flags.set(DxvkContextFlag::DirtyPushConstants);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3815,6 +3832,31 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::updatePushConstants(VkPipelineBindPoint bindPoint) {
|
||||
if (m_flags.test(DxvkContextFlag::DirtyPushConstants)) {
|
||||
m_flags.clr(DxvkContextFlag::DirtyPushConstants);
|
||||
|
||||
auto layout = bindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
|
||||
? (m_state.gp.pipeline != nullptr ? m_state.gp.pipeline->layout() : nullptr)
|
||||
: (m_state.cp.pipeline != nullptr ? m_state.cp.pipeline->layout() : nullptr);
|
||||
|
||||
if (!layout)
|
||||
return;
|
||||
|
||||
VkPushConstantRange pushConstRange = layout->pushConstRange();
|
||||
if (!pushConstRange.size)
|
||||
return;
|
||||
|
||||
m_cmd->cmdPushConstants(
|
||||
layout->pipelineLayout(),
|
||||
pushConstRange.stageFlags,
|
||||
pushConstRange.offset,
|
||||
pushConstRange.size,
|
||||
&m_state.pc.data[pushConstRange.offset]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool DxvkContext::validateComputeState() {
|
||||
return m_cpActivePipeline != VK_NULL_HANDLE;
|
||||
}
|
||||
@ -3848,6 +3890,9 @@ namespace dxvk {
|
||||
DxvkContextFlag::CpDirtyDescriptorSet,
|
||||
DxvkContextFlag::CpDirtyDescriptorOffsets))
|
||||
this->updateComputeShaderDescriptors();
|
||||
|
||||
if (m_flags.test(DxvkContextFlag::DirtyPushConstants))
|
||||
this->updatePushConstants(VK_PIPELINE_BIND_POINT_COMPUTE);
|
||||
}
|
||||
|
||||
|
||||
@ -3893,6 +3938,9 @@ namespace dxvk {
|
||||
DxvkContextFlag::GpDirtyDepthBias,
|
||||
DxvkContextFlag::GpDirtyDepthBounds))
|
||||
this->updateDynamicState();
|
||||
|
||||
if (m_flags.test(DxvkContextFlag::DirtyPushConstants))
|
||||
this->updatePushConstants(VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -653,6 +653,19 @@ namespace dxvk {
|
||||
const Rc<DxvkBuffer>& buffer,
|
||||
const DxvkBufferSliceHandle& slice);
|
||||
|
||||
/**
|
||||
* \brief Updates push constants
|
||||
*
|
||||
* Updates the given push constant range.
|
||||
* \param [in] offset Byte offset of data to update
|
||||
* \param [in] size Number of bytes to update
|
||||
* \param [in] data Pointer to raw data
|
||||
*/
|
||||
void pushConstants(
|
||||
uint32_t offset,
|
||||
uint32_t size,
|
||||
const void* data);
|
||||
|
||||
/**
|
||||
* \brief Resolves a multisampled image resource
|
||||
*
|
||||
@ -1075,6 +1088,9 @@ namespace dxvk {
|
||||
|
||||
void updateDynamicState();
|
||||
|
||||
void updatePushConstants(
|
||||
VkPipelineBindPoint bindPoint);
|
||||
|
||||
bool validateComputeState();
|
||||
bool validateGraphicsState();
|
||||
|
||||
|
@ -53,6 +53,7 @@ namespace dxvk {
|
||||
CpDirtyDescriptorSet, ///< Compute descriptor set needs to be updated
|
||||
|
||||
DirtyDrawBuffer, ///< Indirect argument buffer is dirty
|
||||
DirtyPushConstants, ///< Push constant data has changed
|
||||
};
|
||||
|
||||
using DxvkContextFlags = Flags<DxvkContextFlag>;
|
||||
@ -102,6 +103,11 @@ namespace dxvk {
|
||||
};
|
||||
|
||||
|
||||
struct DxvkPushConstantState {
|
||||
alignas(64) char data[MaxPushConstantSize];
|
||||
};
|
||||
|
||||
|
||||
struct DxvkXfbState {
|
||||
std::array<DxvkBufferSlice, MaxNumXfbBuffers> buffers;
|
||||
std::array<DxvkBufferSlice, MaxNumXfbBuffers> counters;
|
||||
@ -159,6 +165,7 @@ namespace dxvk {
|
||||
DxvkVertexInputState vi;
|
||||
DxvkViewportState vp;
|
||||
DxvkOutputMergerState om;
|
||||
DxvkPushConstantState pc;
|
||||
DxvkXfbState xfb;
|
||||
DxvkDynamicState dyn;
|
||||
DxvkCondRenderState cond;
|
||||
|
Loading…
Reference in New Issue
Block a user