1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 01:24:11 +01:00

[dxvk] Eliminate some redundant state checks

This commit is contained in:
Philip Rebohle 2019-09-26 14:20:50 +02:00
parent 7cdc402a58
commit a920a7275b
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99

View File

@ -3552,32 +3552,28 @@ namespace dxvk {
void DxvkContext::updateComputePipeline() { void DxvkContext::updateComputePipeline() {
if (m_flags.test(DxvkContextFlag::CpDirtyPipeline)) { m_flags.clr(DxvkContextFlag::CpDirtyPipeline);
m_flags.clr(DxvkContextFlag::CpDirtyPipeline);
m_state.cp.state.bsBindingMask.clear(); m_state.cp.state.bsBindingMask.clear();
m_state.cp.pipeline = m_common->pipelineManager().createComputePipeline(m_state.cp.shaders); m_state.cp.pipeline = m_common->pipelineManager().createComputePipeline(m_state.cp.shaders);
if (m_state.cp.pipeline != nullptr if (m_state.cp.pipeline != nullptr
&& m_state.cp.pipeline->layout()->pushConstRange().size) && m_state.cp.pipeline->layout()->pushConstRange().size)
m_flags.set(DxvkContextFlag::DirtyPushConstants); m_flags.set(DxvkContextFlag::DirtyPushConstants);
}
} }
void DxvkContext::updateComputePipelineState() { void DxvkContext::updateComputePipelineState() {
if (m_flags.test(DxvkContextFlag::CpDirtyPipelineState)) { m_flags.clr(DxvkContextFlag::CpDirtyPipelineState);
m_flags.clr(DxvkContextFlag::CpDirtyPipelineState);
m_cpActivePipeline = m_state.cp.pipeline != nullptr m_cpActivePipeline = m_state.cp.pipeline != nullptr
? m_state.cp.pipeline->getPipelineHandle(m_state.cp.state) ? m_state.cp.pipeline->getPipelineHandle(m_state.cp.state)
: VK_NULL_HANDLE; : VK_NULL_HANDLE;
if (m_cpActivePipeline != VK_NULL_HANDLE) { if (m_cpActivePipeline != VK_NULL_HANDLE) {
m_cmd->cmdBindPipeline( m_cmd->cmdBindPipeline(
VK_PIPELINE_BIND_POINT_COMPUTE, VK_PIPELINE_BIND_POINT_COMPUTE,
m_cpActivePipeline); m_cpActivePipeline);
}
} }
} }
@ -3602,72 +3598,67 @@ namespace dxvk {
void DxvkContext::updateGraphicsPipeline() { void DxvkContext::updateGraphicsPipeline() {
if (m_flags.test(DxvkContextFlag::GpDirtyPipeline)) { m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
m_flags.clr(DxvkContextFlag::GpDirtyPipeline);
m_state.gp.state.bsBindingMask.clear(); m_state.gp.state.bsBindingMask.clear();
m_state.gp.pipeline = m_common->pipelineManager().createGraphicsPipeline(m_state.gp.shaders); m_state.gp.pipeline = m_common->pipelineManager().createGraphicsPipeline(m_state.gp.shaders);
m_state.gp.flags = DxvkGraphicsPipelineFlags(); m_state.gp.flags = DxvkGraphicsPipelineFlags();
if (m_state.gp.pipeline != nullptr) { if (m_state.gp.pipeline != nullptr) {
m_state.gp.flags = m_state.gp.pipeline->flags(); m_state.gp.flags = m_state.gp.pipeline->flags();
if (m_state.gp.pipeline->layout()->pushConstRange().size) if (m_state.gp.pipeline->layout()->pushConstRange().size)
m_flags.set(DxvkContextFlag::DirtyPushConstants); m_flags.set(DxvkContextFlag::DirtyPushConstants);
}
} }
} }
void DxvkContext::updateGraphicsPipelineState() { void DxvkContext::updateGraphicsPipelineState() {
if (m_flags.test(DxvkContextFlag::GpDirtyPipelineState)) { m_flags.clr(DxvkContextFlag::GpDirtyPipelineState);
m_flags.clr(DxvkContextFlag::GpDirtyPipelineState);
this->pauseTransformFeedback(); this->pauseTransformFeedback();
// Set up vertex buffer strides for active bindings // Set up vertex buffer strides for active bindings
for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) { for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) {
const uint32_t binding = m_state.gp.state.ilBindings[i].binding; const uint32_t binding = m_state.gp.state.ilBindings[i].binding;
m_state.gp.state.ilBindings[i].stride = m_state.vi.vertexStrides[binding]; m_state.gp.state.ilBindings[i].stride = m_state.vi.vertexStrides[binding];
} }
for (uint32_t i = m_state.gp.state.ilBindingCount; i < MaxNumVertexBindings; i++) for (uint32_t i = m_state.gp.state.ilBindingCount; i < MaxNumVertexBindings; i++)
m_state.gp.state.ilBindings[i].stride = 0; m_state.gp.state.ilBindings[i].stride = 0;
// Check which dynamic states need to be active. States that // Check which dynamic states need to be active. States that
// are not dynamic will be invalidated in the command buffer. // are not dynamic will be invalidated in the command buffer.
m_flags.clr(DxvkContextFlag::GpDynamicBlendConstants, m_flags.clr(DxvkContextFlag::GpDynamicBlendConstants,
DxvkContextFlag::GpDynamicDepthBias, DxvkContextFlag::GpDynamicDepthBias,
DxvkContextFlag::GpDynamicDepthBounds, DxvkContextFlag::GpDynamicDepthBounds,
DxvkContextFlag::GpDynamicStencilRef); DxvkContextFlag::GpDynamicStencilRef);
m_flags.set(m_state.gp.state.useDynamicBlendConstants() m_flags.set(m_state.gp.state.useDynamicBlendConstants()
? DxvkContextFlag::GpDynamicBlendConstants ? DxvkContextFlag::GpDynamicBlendConstants
: DxvkContextFlag::GpDirtyBlendConstants); : DxvkContextFlag::GpDirtyBlendConstants);
m_flags.set(m_state.gp.state.useDynamicDepthBias() m_flags.set(m_state.gp.state.useDynamicDepthBias()
? DxvkContextFlag::GpDynamicDepthBias ? DxvkContextFlag::GpDynamicDepthBias
: DxvkContextFlag::GpDirtyDepthBias); : DxvkContextFlag::GpDirtyDepthBias);
m_flags.set(m_state.gp.state.useDynamicDepthBounds() m_flags.set(m_state.gp.state.useDynamicDepthBounds()
? DxvkContextFlag::GpDynamicDepthBounds ? DxvkContextFlag::GpDynamicDepthBounds
: DxvkContextFlag::GpDirtyDepthBounds); : DxvkContextFlag::GpDirtyDepthBounds);
m_flags.set(m_state.gp.state.useDynamicStencilRef() m_flags.set(m_state.gp.state.useDynamicStencilRef()
? DxvkContextFlag::GpDynamicStencilRef ? DxvkContextFlag::GpDynamicStencilRef
: DxvkContextFlag::GpDirtyStencilRef); : DxvkContextFlag::GpDirtyStencilRef);
// Retrieve and bind actual Vulkan pipeline handle // Retrieve and bind actual Vulkan pipeline handle
m_gpActivePipeline = m_state.gp.pipeline != nullptr && m_state.om.framebuffer != nullptr m_gpActivePipeline = m_state.gp.pipeline != nullptr && m_state.om.framebuffer != nullptr
? m_state.gp.pipeline->getPipelineHandle(m_state.gp.state, ? m_state.gp.pipeline->getPipelineHandle(m_state.gp.state, m_state.om.framebuffer->getRenderPass())
m_state.om.framebuffer->getRenderPass()) : VK_NULL_HANDLE;
: VK_NULL_HANDLE;
if (m_gpActivePipeline != VK_NULL_HANDLE) { if (m_gpActivePipeline != VK_NULL_HANDLE) {
m_cmd->cmdBindPipeline( m_cmd->cmdBindPipeline(
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
m_gpActivePipeline); m_gpActivePipeline);
}
} }
} }
@ -3979,86 +3970,80 @@ namespace dxvk {
void DxvkContext::updateFramebuffer() { void DxvkContext::updateFramebuffer() {
if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) { m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer);
m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer);
this->spillRenderPass(); this->spillRenderPass();
auto fb = m_device->createFramebuffer(m_state.om.renderTargets); auto fb = m_device->createFramebuffer(m_state.om.renderTargets);
m_state.gp.state.msSampleCount = fb->getSampleCount(); m_state.gp.state.msSampleCount = fb->getSampleCount();
m_state.om.framebuffer = fb; m_state.om.framebuffer = fb;
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
Rc<DxvkImageView> attachment = fb->getColorTarget(i).view; Rc<DxvkImageView> attachment = fb->getColorTarget(i).view;
m_state.gp.state.omComponentMapping[i] = attachment != nullptr m_state.gp.state.omComponentMapping[i] = attachment != nullptr
? util::invertComponentMapping(attachment->info().swizzle) ? util::invertComponentMapping(attachment->info().swizzle)
: VkComponentMapping(); : VkComponentMapping();
}
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
} }
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
} }
void DxvkContext::updateIndexBufferBinding() { void DxvkContext::updateIndexBufferBinding() {
if (m_flags.test(DxvkContextFlag::GpDirtyIndexBuffer)) { m_flags.clr(DxvkContextFlag::GpDirtyIndexBuffer);
m_flags.clr(DxvkContextFlag::GpDirtyIndexBuffer);
if (m_state.vi.indexBuffer.defined()) { if (m_state.vi.indexBuffer.defined()) {
auto bufferInfo = m_state.vi.indexBuffer.getDescriptor(); auto bufferInfo = m_state.vi.indexBuffer.getDescriptor();
m_cmd->cmdBindIndexBuffer( m_cmd->cmdBindIndexBuffer(
bufferInfo.buffer.buffer, bufferInfo.buffer.buffer,
bufferInfo.buffer.offset, bufferInfo.buffer.offset,
m_state.vi.indexType); m_state.vi.indexType);
if (m_vbTracked.set(MaxNumVertexBindings)) if (m_vbTracked.set(MaxNumVertexBindings))
m_cmd->trackResource<DxvkAccess::Read>(m_state.vi.indexBuffer.buffer()); m_cmd->trackResource<DxvkAccess::Read>(m_state.vi.indexBuffer.buffer());
} else { } else {
m_cmd->cmdBindIndexBuffer( m_cmd->cmdBindIndexBuffer(
m_common->dummyResources().bufferHandle(), m_common->dummyResources().bufferHandle(),
0, VK_INDEX_TYPE_UINT32); 0, VK_INDEX_TYPE_UINT32);
}
} }
} }
void DxvkContext::updateVertexBufferBindings() { void DxvkContext::updateVertexBufferBindings() {
if (m_flags.test(DxvkContextFlag::GpDirtyVertexBuffers)) { m_flags.clr(DxvkContextFlag::GpDirtyVertexBuffers);
m_flags.clr(DxvkContextFlag::GpDirtyVertexBuffers);
if (unlikely(!m_state.gp.state.ilBindingCount)) if (unlikely(!m_state.gp.state.ilBindingCount))
return; return;
std::array<VkBuffer, MaxNumVertexBindings> buffers; std::array<VkBuffer, MaxNumVertexBindings> buffers;
std::array<VkDeviceSize, MaxNumVertexBindings> offsets; std::array<VkDeviceSize, MaxNumVertexBindings> offsets;
// Set buffer handles and offsets for active bindings // Set buffer handles and offsets for active bindings
for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) { for (uint32_t i = 0; i < m_state.gp.state.ilBindingCount; i++) {
uint32_t binding = m_state.gp.state.ilBindings[i].binding; uint32_t binding = m_state.gp.state.ilBindings[i].binding;
if (likely(m_state.vi.vertexBuffers[binding].defined())) { if (likely(m_state.vi.vertexBuffers[binding].defined())) {
auto vbo = m_state.vi.vertexBuffers[binding].getDescriptor(); auto vbo = m_state.vi.vertexBuffers[binding].getDescriptor();
buffers[i] = vbo.buffer.buffer; buffers[i] = vbo.buffer.buffer;
offsets[i] = vbo.buffer.offset; offsets[i] = vbo.buffer.offset;
if (m_vbTracked.set(binding)) if (m_vbTracked.set(binding))
m_cmd->trackResource<DxvkAccess::Read>(m_state.vi.vertexBuffers[binding].buffer()); m_cmd->trackResource<DxvkAccess::Read>(m_state.vi.vertexBuffers[binding].buffer());
} else { } else {
buffers[i] = m_common->dummyResources().bufferHandle(); buffers[i] = m_common->dummyResources().bufferHandle();
offsets[i] = 0; offsets[i] = 0;
}
} }
// Vertex bindigs get remapped when compiling the
// pipeline, so this actually does the right thing
m_cmd->cmdBindVertexBuffers(
0, m_state.gp.state.ilBindingCount,
buffers.data(), offsets.data());
} }
// Vertex bindigs get remapped when compiling the
// pipeline, so this actually does the right thing
m_cmd->cmdBindVertexBuffers(
0, m_state.gp.state.ilBindingCount,
buffers.data(), offsets.data());
} }
@ -4094,33 +4079,29 @@ namespace dxvk {
void DxvkContext::updateTransformFeedbackState() { void DxvkContext::updateTransformFeedbackState() {
if (m_state.gp.flags.test(DxvkGraphicsPipelineFlag::HasTransformFeedback)) { if (m_flags.test(DxvkContextFlag::GpDirtyXfbBuffers)) {
if (m_flags.test(DxvkContextFlag::GpDirtyXfbBuffers)) { m_flags.clr(DxvkContextFlag::GpDirtyXfbBuffers);
m_flags.clr(DxvkContextFlag::GpDirtyXfbBuffers);
this->pauseTransformFeedback(); this->pauseTransformFeedback();
this->updateTransformFeedbackBuffers(); this->updateTransformFeedbackBuffers();
}
this->startTransformFeedback();
} }
this->startTransformFeedback();
} }
void DxvkContext::updateConditionalRendering() { void DxvkContext::updateConditionalRendering() {
if (m_flags.test(DxvkContextFlag::GpDirtyPredicate)) { m_flags.clr(DxvkContextFlag::GpDirtyPredicate);
m_flags.clr(DxvkContextFlag::GpDirtyPredicate);
pauseConditionalRendering(); pauseConditionalRendering();
if (m_state.cond.predicate.defined()) if (m_state.cond.predicate.defined())
startConditionalRendering(); startConditionalRendering();
}
} }
void DxvkContext::updateDynamicState() { void DxvkContext::updateDynamicState() {
if (m_gpActivePipeline == VK_NULL_HANDLE) if (!m_gpActivePipeline)
return; return;
if (m_flags.test(DxvkContextFlag::GpDirtyViewport)) { if (m_flags.test(DxvkContextFlag::GpDirtyViewport)) {
@ -4169,27 +4150,25 @@ namespace dxvk {
template<VkPipelineBindPoint BindPoint> template<VkPipelineBindPoint BindPoint>
void DxvkContext::updatePushConstants() { void DxvkContext::updatePushConstants() {
if (m_flags.test(DxvkContextFlag::DirtyPushConstants)) { m_flags.clr(DxvkContextFlag::DirtyPushConstants);
m_flags.clr(DxvkContextFlag::DirtyPushConstants);
auto layout = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS auto layout = BindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS
? (m_state.gp.pipeline != nullptr ? m_state.gp.pipeline->layout() : nullptr) ? (m_state.gp.pipeline != nullptr ? m_state.gp.pipeline->layout() : nullptr)
: (m_state.cp.pipeline != nullptr ? m_state.cp.pipeline->layout() : nullptr); : (m_state.cp.pipeline != nullptr ? m_state.cp.pipeline->layout() : nullptr);
if (!layout) if (!layout)
return; return;
VkPushConstantRange pushConstRange = layout->pushConstRange(); VkPushConstantRange pushConstRange = layout->pushConstRange();
if (!pushConstRange.size) if (!pushConstRange.size)
return; return;
m_cmd->cmdPushConstants( m_cmd->cmdPushConstants(
layout->pipelineLayout(), layout->pipelineLayout(),
pushConstRange.stageFlags, pushConstRange.stageFlags,
pushConstRange.offset, pushConstRange.offset,
pushConstRange.size, pushConstRange.size,
&m_state.pc.data[pushConstRange.offset]); &m_state.pc.data[pushConstRange.offset]);
}
} }
@ -4206,7 +4185,7 @@ namespace dxvk {
if (m_flags.any( if (m_flags.any(
DxvkContextFlag::CpDirtyResources, DxvkContextFlag::CpDirtyResources,
DxvkContextFlag::CpDirtyDescriptorOffsets)) DxvkContextFlag::CpDirtyDescriptorOffsets))
this->updateComputeShaderResources(); this->updateComputeShaderResources();
if (m_flags.test(DxvkContextFlag::CpDirtyPipelineState)) if (m_flags.test(DxvkContextFlag::CpDirtyPipelineState))
this->updateComputePipelineState(); this->updateComputePipelineState();