1
0
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:
Philip Rebohle 2019-05-07 20:51:27 +02:00
parent 8931013234
commit 02768182f1
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 72 additions and 1 deletions

View File

@ -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);
}

View File

@ -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();

View File

@ -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;