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:
parent
8606576d83
commit
1075990dbe
@ -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();
|
||||||
|
@ -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();
|
||||||
|
@ -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 };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user