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

[dxvk] Apply render target bindings at draw time

This should help reduce the number of redundant render pass spills,
especially in games which use deferred contexts for rendering. This
optimization mostly helps in GPU-bound scenarios.
This commit is contained in:
Philip Rebohle 2018-04-26 14:47:55 +02:00
parent 8606576d83
commit 1075990dbe
3 changed files with 31 additions and 12 deletions

View File

@ -98,19 +98,18 @@ namespace dxvk {
m_state.om.framebuffer = fb; m_state.om.framebuffer = fb;
} }
m_state.om.renderTargets = fb != nullptr
? fb->renderTargets()
: DxvkRenderTargets();
m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer);
} }
void DxvkContext::bindRenderTargets(const DxvkRenderTargets& targets) { void DxvkContext::bindRenderTargets(const DxvkRenderTargets& targets) {
bool sameAsCurr = m_state.om.framebuffer != nullptr if (m_state.om.framebuffer == nullptr || !m_state.om.framebuffer->renderTargets().matches(targets)) {
&& m_state.om.framebuffer->renderTargets().matches(targets); m_state.om.renderTargets = targets;
m_flags.set(DxvkContextFlag::GpDirtyFramebuffer);
if (!sameAsCurr) {
Rc<DxvkFramebuffer> fb = targets.hasAttachments()
? m_device->createFramebuffer(targets)
: nullptr;
this->bindFramebuffer(fb);
} }
} }
@ -392,6 +391,8 @@ namespace dxvk {
const VkClearRect& clearRect, const VkClearRect& clearRect,
VkImageAspectFlags clearAspects, VkImageAspectFlags clearAspects,
const VkClearValue& clearValue) { const VkClearValue& clearValue) {
this->updateFramebuffer();
// Check whether the render target view is an attachment // Check whether the render target view is an attachment
// of the current framebuffer. If not, we need to create // of the current framebuffer. If not, we need to create
// a temporary framebuffer. // a temporary framebuffer.
@ -1798,6 +1799,23 @@ namespace dxvk {
} }
void DxvkContext::updateFramebuffer() {
if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) {
m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer);
this->spillRenderPass();
auto fb = m_device->createFramebuffer(m_state.om.renderTargets);
m_state.gp.state.msSampleCount = fb->sampleCount();
m_state.gp.state.omRenderPass = fb->renderPass();
m_state.om.framebuffer = fb;
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
}
}
void DxvkContext::updateIndexBufferBinding() { void DxvkContext::updateIndexBufferBinding() {
if (m_flags.test(DxvkContextFlag::GpDirtyIndexBuffer)) { if (m_flags.test(DxvkContextFlag::GpDirtyIndexBuffer)) {
m_flags.clr(DxvkContextFlag::GpDirtyIndexBuffer); m_flags.clr(DxvkContextFlag::GpDirtyIndexBuffer);
@ -1881,6 +1899,7 @@ namespace dxvk {
void DxvkContext::commitGraphicsState() { void DxvkContext::commitGraphicsState() {
this->updateFramebuffer();
this->startRenderPass(); this->startRenderPass();
this->updateGraphicsPipeline(); this->updateGraphicsPipeline();
this->updateIndexBufferBinding(); this->updateIndexBufferBinding();

View File

@ -662,9 +662,7 @@ namespace dxvk {
const DxvkBindingState& bindingState, const DxvkBindingState& bindingState,
const Rc<DxvkPipelineLayout>& layout); const Rc<DxvkPipelineLayout>& layout);
void updateViewports(); void updateFramebuffer();
void updateBlendConstants();
void updateStencilReference();
void updateIndexBufferBinding(); void updateIndexBufferBinding();
void updateVertexBufferBindings(); void updateVertexBufferBindings();

View File

@ -22,6 +22,7 @@ namespace dxvk {
*/ */
enum class DxvkContextFlag : uint64_t { enum class DxvkContextFlag : uint64_t {
GpRenderPassBound, ///< Render pass is currently bound GpRenderPassBound, ///< Render pass is currently bound
GpDirtyFramebuffer, ///< Framebuffer binding is out of date
GpDirtyPipeline, ///< Graphics pipeline binding is out of date GpDirtyPipeline, ///< Graphics pipeline binding is out of date
GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled GpDirtyPipelineState, ///< Graphics pipeline needs to be recompiled
GpDirtyResources, ///< Graphics pipeline resource bindings are out of date GpDirtyResources, ///< Graphics pipeline resource bindings are out of date
@ -53,6 +54,7 @@ namespace dxvk {
struct DxvkOutputMergerState { struct DxvkOutputMergerState {
DxvkRenderTargets renderTargets;
Rc<DxvkFramebuffer> framebuffer = nullptr; Rc<DxvkFramebuffer> framebuffer = nullptr;
DxvkBlendConstants blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f }; DxvkBlendConstants blendConstants = { 0.0f, 0.0f, 0.0f, 0.0f };