mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-13 16:08:50 +01:00
[dxvk] Remove frame buffer from context state
This commit is contained in:
parent
5b725205ef
commit
f1aad6cb7b
@ -109,7 +109,7 @@ namespace dxvk {
|
|||||||
m_state.om.renderTargets,
|
m_state.om.renderTargets,
|
||||||
m_state.om.renderPassOps);
|
m_state.om.renderPassOps);
|
||||||
|
|
||||||
if (m_state.om.framebuffer == nullptr || !m_state.om.framebuffer->hasTargets(targets)) {
|
if (!m_state.om.framebufferInfo.hasTargets(targets)) {
|
||||||
// Create a new framebuffer object next
|
// Create a new framebuffer object next
|
||||||
// time we start rendering something
|
// time we start rendering something
|
||||||
m_flags.set(DxvkContextFlag::GpDirtyFramebuffer);
|
m_flags.set(DxvkContextFlag::GpDirtyFramebuffer);
|
||||||
@ -583,9 +583,8 @@ namespace dxvk {
|
|||||||
// If not, we need to create a temporary framebuffer.
|
// If not, we need to create a temporary framebuffer.
|
||||||
int32_t attachmentIndex = -1;
|
int32_t attachmentIndex = -1;
|
||||||
|
|
||||||
if (m_state.om.framebuffer != nullptr
|
if (m_state.om.framebufferInfo.isFullSize(imageView))
|
||||||
&& m_state.om.framebuffer->isFullSize(imageView))
|
attachmentIndex = m_state.om.framebufferInfo.findAttachment(imageView);
|
||||||
attachmentIndex = m_state.om.framebuffer->findAttachment(imageView);
|
|
||||||
|
|
||||||
if (attachmentIndex < 0) {
|
if (attachmentIndex < 0) {
|
||||||
// Suspend works here because we'll end up with one of these scenarios:
|
// Suspend works here because we'll end up with one of these scenarios:
|
||||||
@ -596,13 +595,13 @@ namespace dxvk {
|
|||||||
// If there is overlap, we need to explicitly transition affected attachments.
|
// If there is overlap, we need to explicitly transition affected attachments.
|
||||||
this->spillRenderPass(true);
|
this->spillRenderPass(true);
|
||||||
this->prepareImage(m_execBarriers, imageView->image(), imageView->subresources(), false);
|
this->prepareImage(m_execBarriers, imageView->image(), imageView->subresources(), false);
|
||||||
} else if (!m_state.om.framebuffer->isWritable(attachmentIndex, clearAspects)) {
|
} else if (!m_state.om.framebufferInfo.isWritable(attachmentIndex, clearAspects)) {
|
||||||
// We cannot inline clears if the clear aspects are not writable
|
// We cannot inline clears if the clear aspects are not writable
|
||||||
this->spillRenderPass(true);
|
this->spillRenderPass(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
|
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
|
||||||
uint32_t colorIndex = std::max(0, m_state.om.framebuffer->getColorAttachmentIndex(attachmentIndex));
|
uint32_t colorIndex = std::max(0, m_state.om.framebufferInfo.getColorAttachmentIndex(attachmentIndex));
|
||||||
|
|
||||||
VkClearAttachment clearInfo;
|
VkClearAttachment clearInfo;
|
||||||
clearInfo.aspectMask = clearAspects;
|
clearInfo.aspectMask = clearAspects;
|
||||||
@ -1951,12 +1950,12 @@ namespace dxvk {
|
|||||||
else if (discardAspects & VK_IMAGE_ASPECT_DEPTH_BIT)
|
else if (discardAspects & VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||||
depthOp.loadOpS = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
depthOp.loadOpS = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||||
|
|
||||||
if (attachmentIndex >= 0 && !m_state.om.framebuffer->isWritable(attachmentIndex, clearAspects | discardAspects)) {
|
if (attachmentIndex >= 0 && !m_state.om.framebufferInfo.isWritable(attachmentIndex, clearAspects | discardAspects)) {
|
||||||
// Do not fold the clear/discard into the render pass if any of the affected aspects
|
// Do not fold the clear/discard into the render pass if any of the affected aspects
|
||||||
// isn't writable. We can only hit this particular path when starting a render pass,
|
// isn't writable. We can only hit this particular path when starting a render pass,
|
||||||
// so we can safely manipulate load layouts here.
|
// so we can safely manipulate load layouts here.
|
||||||
int32_t colorIndex = m_state.om.framebuffer->getColorAttachmentIndex(attachmentIndex);
|
int32_t colorIndex = m_state.om.framebufferInfo.getColorAttachmentIndex(attachmentIndex);
|
||||||
VkImageLayout renderLayout = m_state.om.framebuffer->getAttachment(attachmentIndex).layout;
|
VkImageLayout renderLayout = m_state.om.framebufferInfo.getAttachment(attachmentIndex).layout;
|
||||||
|
|
||||||
if (colorIndex < 0) {
|
if (colorIndex < 0) {
|
||||||
depthOp.loadLayout = m_state.om.renderPassOps.depthOps.loadLayout;
|
depthOp.loadLayout = m_state.om.renderPassOps.depthOps.loadLayout;
|
||||||
@ -2016,14 +2015,12 @@ namespace dxvk {
|
|||||||
ops.barrier.dstStages = imageView->imageInfo().stages;
|
ops.barrier.dstStages = imageView->imageInfo().stages;
|
||||||
ops.barrier.dstAccess = imageView->imageInfo().access;
|
ops.barrier.dstAccess = imageView->imageInfo().access;
|
||||||
|
|
||||||
this->renderPassBindFramebuffer(
|
this->renderPassBindFramebuffer(makeFramebufferInfo(attachments), ops, 1, &clearValue);
|
||||||
m_device->createFramebuffer(attachments),
|
|
||||||
ops, 1, &clearValue);
|
|
||||||
this->renderPassUnbindFramebuffer();
|
this->renderPassUnbindFramebuffer();
|
||||||
} else {
|
} else {
|
||||||
// Perform the operation when starting the next render pass
|
// Perform the operation when starting the next render pass
|
||||||
if ((clearAspects | discardAspects) & VK_IMAGE_ASPECT_COLOR_BIT) {
|
if ((clearAspects | discardAspects) & VK_IMAGE_ASPECT_COLOR_BIT) {
|
||||||
uint32_t colorIndex = m_state.om.framebuffer->getColorAttachmentIndex(attachmentIndex);
|
uint32_t colorIndex = m_state.om.framebufferInfo.getColorAttachmentIndex(attachmentIndex);
|
||||||
|
|
||||||
m_state.om.renderPassOps.colorOps[colorIndex].loadOp = colorOp.loadOp;
|
m_state.om.renderPassOps.colorOps[colorIndex].loadOp = colorOp.loadOp;
|
||||||
if (m_state.om.renderPassOps.colorOps[colorIndex].loadOp != VK_ATTACHMENT_LOAD_OP_LOAD && !is3D)
|
if (m_state.om.renderPassOps.colorOps[colorIndex].loadOp != VK_ATTACHMENT_LOAD_OP_LOAD && !is3D)
|
||||||
@ -2103,8 +2100,8 @@ namespace dxvk {
|
|||||||
for (const auto& clear : m_deferredClears) {
|
for (const auto& clear : m_deferredClears) {
|
||||||
int32_t attachmentIndex = -1;
|
int32_t attachmentIndex = -1;
|
||||||
|
|
||||||
if (useRenderPass && m_state.om.framebuffer->isFullSize(clear.imageView))
|
if (useRenderPass && m_state.om.framebufferInfo.isFullSize(clear.imageView))
|
||||||
attachmentIndex = m_state.om.framebuffer->findAttachment(clear.imageView);
|
attachmentIndex = m_state.om.framebufferInfo.findAttachment(clear.imageView);
|
||||||
|
|
||||||
this->performClear(clear.imageView, attachmentIndex,
|
this->performClear(clear.imageView, attachmentIndex,
|
||||||
clear.discardAspects, clear.clearAspects, clear.clearValue);
|
clear.discardAspects, clear.clearAspects, clear.clearValue);
|
||||||
@ -3093,11 +3090,10 @@ namespace dxvk {
|
|||||||
// so that we can avoid spilling the render pass if it is.
|
// so that we can avoid spilling the render pass if it is.
|
||||||
int32_t attachmentIndex = -1;
|
int32_t attachmentIndex = -1;
|
||||||
|
|
||||||
if (m_state.om.framebuffer != nullptr
|
if (m_state.om.framebufferInfo.isFullSize(imageView))
|
||||||
&& m_state.om.framebuffer->isFullSize(imageView))
|
attachmentIndex = m_state.om.framebufferInfo.findAttachment(imageView);
|
||||||
attachmentIndex = m_state.om.framebuffer->findAttachment(imageView);
|
|
||||||
|
|
||||||
if (attachmentIndex >= 0 && !m_state.om.framebuffer->isWritable(attachmentIndex, aspect))
|
if (attachmentIndex >= 0 && !m_state.om.framebufferInfo.isWritable(attachmentIndex, aspect))
|
||||||
attachmentIndex = -1;
|
attachmentIndex = -1;
|
||||||
|
|
||||||
if (attachmentIndex < 0) {
|
if (attachmentIndex < 0) {
|
||||||
@ -3149,9 +3145,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
// We cannot leverage render pass clears
|
// We cannot leverage render pass clears
|
||||||
// because we clear only part of the view
|
// because we clear only part of the view
|
||||||
this->renderPassBindFramebuffer(
|
this->renderPassBindFramebuffer(makeFramebufferInfo(attachments), ops, 0, nullptr);
|
||||||
m_device->createFramebuffer(attachments),
|
|
||||||
ops, 0, nullptr);
|
|
||||||
} else {
|
} else {
|
||||||
// Make sure the render pass is active so
|
// Make sure the render pass is active so
|
||||||
// that we can actually perform the clear
|
// that we can actually perform the clear
|
||||||
@ -3165,7 +3159,7 @@ namespace dxvk {
|
|||||||
clearInfo.clearValue = value;
|
clearInfo.clearValue = value;
|
||||||
|
|
||||||
if ((aspect & VK_IMAGE_ASPECT_COLOR_BIT) && (attachmentIndex >= 0))
|
if ((aspect & VK_IMAGE_ASPECT_COLOR_BIT) && (attachmentIndex >= 0))
|
||||||
clearInfo.colorAttachment = m_state.om.framebuffer->getColorAttachmentIndex(attachmentIndex);
|
clearInfo.colorAttachment = m_state.om.framebufferInfo.getColorAttachmentIndex(attachmentIndex);
|
||||||
|
|
||||||
VkClearRect clearRect;
|
VkClearRect clearRect;
|
||||||
clearRect.rect.offset.x = offset.x;
|
clearRect.rect.offset.x = offset.x;
|
||||||
@ -3949,9 +3943,9 @@ namespace dxvk {
|
|||||||
m_execBarriers.recordCommands(m_cmd);
|
m_execBarriers.recordCommands(m_cmd);
|
||||||
|
|
||||||
this->renderPassBindFramebuffer(
|
this->renderPassBindFramebuffer(
|
||||||
m_state.om.framebuffer,
|
m_state.om.framebufferInfo,
|
||||||
m_state.om.renderPassOps,
|
m_state.om.renderPassOps,
|
||||||
m_state.om.framebuffer->numAttachments(),
|
m_state.om.framebufferInfo.numAttachments(),
|
||||||
m_state.om.clearValues.data());
|
m_state.om.clearValues.data());
|
||||||
|
|
||||||
// Track the final layout of each render target
|
// Track the final layout of each render target
|
||||||
@ -4004,12 +3998,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxvkContext::renderPassBindFramebuffer(
|
void DxvkContext::renderPassBindFramebuffer(
|
||||||
const Rc<DxvkFramebuffer>& framebuffer,
|
const DxvkFramebufferInfo& framebufferInfo,
|
||||||
const DxvkRenderPassOps& ops,
|
const DxvkRenderPassOps& ops,
|
||||||
uint32_t clearValueCount,
|
uint32_t clearValueCount,
|
||||||
const VkClearValue* clearValues) {
|
const VkClearValue* clearValues) {
|
||||||
const DxvkFramebufferSize fbSize = framebuffer->size();
|
const DxvkFramebufferSize fbSize = framebufferInfo.size();
|
||||||
|
|
||||||
|
Rc<DxvkFramebuffer> framebuffer = m_device->createFramebuffer(framebufferInfo.attachments());
|
||||||
|
|
||||||
VkRect2D renderArea;
|
VkRect2D renderArea;
|
||||||
renderArea.offset = VkOffset2D { 0, 0 };
|
renderArea.offset = VkOffset2D { 0, 0 };
|
||||||
renderArea.extent = VkExtent2D { fbSize.width, fbSize.height };
|
renderArea.extent = VkExtent2D { fbSize.width, fbSize.height };
|
||||||
@ -4017,7 +4013,7 @@ namespace dxvk {
|
|||||||
VkRenderPassBeginInfo info;
|
VkRenderPassBeginInfo info;
|
||||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
info.pNext = nullptr;
|
info.pNext = nullptr;
|
||||||
info.renderPass = framebuffer->getRenderPassHandle(ops);
|
info.renderPass = framebufferInfo.renderPass()->getHandle(ops);
|
||||||
info.framebuffer = framebuffer->handle();
|
info.framebuffer = framebuffer->handle();
|
||||||
info.renderArea = renderArea;
|
info.renderArea = renderArea;
|
||||||
info.clearValueCount = clearValueCount;
|
info.clearValueCount = clearValueCount;
|
||||||
@ -4028,9 +4024,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
m_cmd->trackResource<DxvkAccess::None>(framebuffer);
|
m_cmd->trackResource<DxvkAccess::None>(framebuffer);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < framebuffer->numAttachments(); i++) {
|
for (uint32_t i = 0; i < framebufferInfo.numAttachments(); i++) {
|
||||||
m_cmd->trackResource<DxvkAccess::None> (framebuffer->getAttachment(i).view);
|
m_cmd->trackResource<DxvkAccess::None> (framebufferInfo.getAttachment(i).view);
|
||||||
m_cmd->trackResource<DxvkAccess::Write>(framebuffer->getAttachment(i).view->image());
|
m_cmd->trackResource<DxvkAccess::Write>(framebufferInfo.getAttachment(i).view->image());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cmd->addStatCtr(DxvkStatCounter::CmdRenderPassCount, 1);
|
m_cmd->addStatCtr(DxvkStatCounter::CmdRenderPassCount, 1);
|
||||||
@ -4252,7 +4248,8 @@ namespace dxvk {
|
|||||||
: DxvkContextFlag::GpDirtyStencilRef);
|
: DxvkContextFlag::GpDirtyStencilRef);
|
||||||
|
|
||||||
// Retrieve and bind actual Vulkan pipeline handle
|
// Retrieve and bind actual Vulkan pipeline handle
|
||||||
m_gpActivePipeline = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state, m_state.om.framebuffer->getRenderPass());
|
m_gpActivePipeline = m_state.gp.pipeline->getPipelineHandle(
|
||||||
|
m_state.gp.state, m_state.om.framebufferInfo.renderPass());
|
||||||
|
|
||||||
if (unlikely(!m_gpActivePipeline))
|
if (unlikely(!m_gpActivePipeline))
|
||||||
return false;
|
return false;
|
||||||
@ -4484,20 +4481,29 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkFramebufferInfo DxvkContext::makeFramebufferInfo(
|
||||||
|
const DxvkRenderTargets& renderTargets) {
|
||||||
|
auto renderPassFormat = DxvkFramebufferInfo::getRenderPassFormat(renderTargets);
|
||||||
|
auto renderPassObject = m_common->renderPassPool().getRenderPass(renderPassFormat);
|
||||||
|
|
||||||
|
return DxvkFramebufferInfo(renderTargets, m_device->getDefaultFramebufferSize(), renderPassObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::updateFramebuffer() {
|
void DxvkContext::updateFramebuffer() {
|
||||||
if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) {
|
if (m_flags.test(DxvkContextFlag::GpDirtyFramebuffer)) {
|
||||||
m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer);
|
m_flags.clr(DxvkContextFlag::GpDirtyFramebuffer);
|
||||||
|
|
||||||
this->spillRenderPass(true);
|
this->spillRenderPass(true);
|
||||||
|
|
||||||
auto fb = m_device->createFramebuffer(m_state.om.renderTargets);
|
DxvkFramebufferInfo fbInfo = makeFramebufferInfo(m_state.om.renderTargets);
|
||||||
this->updateRenderTargetLayouts(fb, m_state.om.framebuffer);
|
this->updateRenderTargetLayouts(fbInfo, m_state.om.framebufferInfo);
|
||||||
|
|
||||||
m_state.gp.state.ms.setSampleCount(fb->getSampleCount());
|
m_state.gp.state.ms.setSampleCount(fbInfo.getSampleCount());
|
||||||
m_state.om.framebuffer = fb;
|
m_state.om.framebufferInfo = fbInfo;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||||
const Rc<DxvkImageView>& attachment = fb->getColorTarget(i).view;
|
const Rc<DxvkImageView>& attachment = fbInfo.getColorTarget(i).view;
|
||||||
|
|
||||||
VkComponentMapping mapping = attachment != nullptr
|
VkComponentMapping mapping = attachment != nullptr
|
||||||
? util::invertComponentMapping(attachment->info().swizzle)
|
? util::invertComponentMapping(attachment->info().swizzle)
|
||||||
@ -4530,11 +4536,8 @@ namespace dxvk {
|
|||||||
void DxvkContext::transitionRenderTargetLayouts(
|
void DxvkContext::transitionRenderTargetLayouts(
|
||||||
DxvkBarrierSet& barriers,
|
DxvkBarrierSet& barriers,
|
||||||
bool sharedOnly) {
|
bool sharedOnly) {
|
||||||
if (m_state.om.framebuffer == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||||
const DxvkAttachment& color = m_state.om.framebuffer->getColorTarget(i);
|
const DxvkAttachment& color = m_state.om.framebufferInfo.getColorTarget(i);
|
||||||
|
|
||||||
if (color.view != nullptr && (!sharedOnly || color.view->imageInfo().shared)) {
|
if (color.view != nullptr && (!sharedOnly || color.view->imageInfo().shared)) {
|
||||||
this->transitionColorAttachment(barriers, color, m_rtLayouts.color[i]);
|
this->transitionColorAttachment(barriers, color, m_rtLayouts.color[i]);
|
||||||
@ -4542,7 +4545,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DxvkAttachment& depth = m_state.om.framebuffer->getDepthTarget();
|
const DxvkAttachment& depth = m_state.om.framebufferInfo.getDepthTarget();
|
||||||
|
|
||||||
if (depth.view != nullptr && (!sharedOnly || depth.view->imageInfo().shared)) {
|
if (depth.view != nullptr && (!sharedOnly || depth.view->imageInfo().shared)) {
|
||||||
this->transitionDepthAttachment(barriers, depth, m_rtLayouts.depth);
|
this->transitionDepthAttachment(barriers, depth, m_rtLayouts.depth);
|
||||||
@ -4592,60 +4595,58 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void DxvkContext::updateRenderTargetLayouts(
|
void DxvkContext::updateRenderTargetLayouts(
|
||||||
const Rc<DxvkFramebuffer>& newFb,
|
const DxvkFramebufferInfo& newFb,
|
||||||
const Rc<DxvkFramebuffer>& oldFb) {
|
const DxvkFramebufferInfo& oldFb) {
|
||||||
DxvkRenderTargetLayouts layouts = { };
|
DxvkRenderTargetLayouts layouts = { };
|
||||||
|
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||||
if (newFb->getColorTarget(i).view != nullptr)
|
if (newFb.getColorTarget(i).view != nullptr)
|
||||||
layouts.color[i] = newFb->getColorTarget(i).view->imageInfo().layout;
|
layouts.color[i] = newFb.getColorTarget(i).view->imageInfo().layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newFb->getDepthTarget().view != nullptr)
|
if (newFb.getDepthTarget().view != nullptr)
|
||||||
layouts.depth = newFb->getDepthTarget().view->imageInfo().layout;
|
layouts.depth = newFb.getDepthTarget().view->imageInfo().layout;
|
||||||
|
|
||||||
if (oldFb != nullptr) {
|
// Check whether any of the previous attachments have been moved
|
||||||
// Check whether any of the previous attachments have been moved
|
// around or been rebound with a different view. This may help
|
||||||
// around or been rebound with a different view. This may help
|
// reduce the number of image layout transitions between passes.
|
||||||
// reduce the number of image layout transitions between passes.
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
const DxvkAttachment& oldAttachment = oldFb.getColorTarget(i);
|
||||||
const DxvkAttachment& oldAttachment = oldFb->getColorTarget(i);
|
|
||||||
|
|
||||||
if (oldAttachment.view != nullptr) {
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < MaxNumRenderTargets && !found; j++) {
|
|
||||||
const DxvkAttachment& newAttachment = newFb->getColorTarget(j);
|
|
||||||
|
|
||||||
found = newAttachment.view == oldAttachment.view || (newAttachment.view != nullptr
|
|
||||||
&& newAttachment.view->image() == oldAttachment.view->image()
|
|
||||||
&& newAttachment.view->subresources() == oldAttachment.view->subresources());
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
layouts.color[j] = m_rtLayouts.color[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found && m_flags.test(DxvkContextFlag::GpRenderPassSuspended))
|
|
||||||
this->transitionColorAttachment(m_execBarriers, oldAttachment, m_rtLayouts.color[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const DxvkAttachment& oldAttachment = oldFb->getDepthTarget();
|
|
||||||
|
|
||||||
if (oldAttachment.view != nullptr) {
|
if (oldAttachment.view != nullptr) {
|
||||||
const DxvkAttachment& newAttachment = newFb->getDepthTarget();
|
bool found = false;
|
||||||
|
|
||||||
bool found = newAttachment.view == oldAttachment.view || (newAttachment.view != nullptr
|
for (uint32_t j = 0; j < MaxNumRenderTargets && !found; j++) {
|
||||||
&& newAttachment.view->image() == oldAttachment.view->image()
|
const DxvkAttachment& newAttachment = newFb.getColorTarget(j);
|
||||||
&& newAttachment.view->subresources() == oldAttachment.view->subresources());
|
|
||||||
|
|
||||||
if (found)
|
found = newAttachment.view == oldAttachment.view || (newAttachment.view != nullptr
|
||||||
layouts.depth = m_rtLayouts.depth;
|
&& newAttachment.view->image() == oldAttachment.view->image()
|
||||||
else if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended))
|
&& newAttachment.view->subresources() == oldAttachment.view->subresources());
|
||||||
this->transitionDepthAttachment(m_execBarriers, oldAttachment, m_rtLayouts.depth);
|
|
||||||
|
if (found)
|
||||||
|
layouts.color[j] = m_rtLayouts.color[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found && m_flags.test(DxvkContextFlag::GpRenderPassSuspended))
|
||||||
|
this->transitionColorAttachment(m_execBarriers, oldAttachment, m_rtLayouts.color[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DxvkAttachment& oldAttachment = oldFb.getDepthTarget();
|
||||||
|
|
||||||
|
if (oldAttachment.view != nullptr) {
|
||||||
|
const DxvkAttachment& newAttachment = newFb.getDepthTarget();
|
||||||
|
|
||||||
|
bool found = newAttachment.view == oldAttachment.view || (newAttachment.view != nullptr
|
||||||
|
&& newAttachment.view->image() == oldAttachment.view->image()
|
||||||
|
&& newAttachment.view->subresources() == oldAttachment.view->subresources());
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
layouts.depth = m_rtLayouts.depth;
|
||||||
|
else if (m_flags.test(DxvkContextFlag::GpRenderPassSuspended))
|
||||||
|
this->transitionDepthAttachment(m_execBarriers, oldAttachment, m_rtLayouts.depth);
|
||||||
|
}
|
||||||
|
|
||||||
m_rtLayouts = layouts;
|
m_rtLayouts = layouts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4675,7 +4676,7 @@ namespace dxvk {
|
|||||||
// Transition any attachment with overlapping subresources
|
// Transition any attachment with overlapping subresources
|
||||||
if (image->info().usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
|
if (image->info().usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
|
||||||
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
|
||||||
const DxvkAttachment& attachment = m_state.om.framebuffer->getColorTarget(i);
|
const DxvkAttachment& attachment = m_state.om.framebufferInfo.getColorTarget(i);
|
||||||
|
|
||||||
if (attachment.view != nullptr && attachment.view->image() == image
|
if (attachment.view != nullptr && attachment.view->image() == image
|
||||||
&& (is3D || vk::checkSubresourceRangeOverlap(attachment.view->subresources(), subresources))) {
|
&& (is3D || vk::checkSubresourceRangeOverlap(attachment.view->subresources(), subresources))) {
|
||||||
@ -4684,7 +4685,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const DxvkAttachment& attachment = m_state.om.framebuffer->getDepthTarget();
|
const DxvkAttachment& attachment = m_state.om.framebufferInfo.getDepthTarget();
|
||||||
|
|
||||||
if (attachment.view != nullptr && attachment.view->image() == image
|
if (attachment.view != nullptr && attachment.view->image() == image
|
||||||
&& (is3D || vk::checkSubresourceRangeOverlap(attachment.view->subresources(), subresources))) {
|
&& (is3D || vk::checkSubresourceRangeOverlap(attachment.view->subresources(), subresources))) {
|
||||||
|
@ -1067,6 +1067,7 @@ namespace dxvk {
|
|||||||
* tools to mark different workloads within a frame.
|
* tools to mark different workloads within a frame.
|
||||||
*/
|
*/
|
||||||
void insertDebugLabel(VkDebugUtilsLabelEXT *label);
|
void insertDebugLabel(VkDebugUtilsLabelEXT *label);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Rc<DxvkDevice> m_device;
|
Rc<DxvkDevice> m_device;
|
||||||
@ -1227,7 +1228,7 @@ namespace dxvk {
|
|||||||
void spillRenderPass(bool suspend);
|
void spillRenderPass(bool suspend);
|
||||||
|
|
||||||
void renderPassBindFramebuffer(
|
void renderPassBindFramebuffer(
|
||||||
const Rc<DxvkFramebuffer>& framebuffer,
|
const DxvkFramebufferInfo& framebufferInfo,
|
||||||
const DxvkRenderPassOps& ops,
|
const DxvkRenderPassOps& ops,
|
||||||
uint32_t clearValueCount,
|
uint32_t clearValueCount,
|
||||||
const VkClearValue* clearValues);
|
const VkClearValue* clearValues);
|
||||||
@ -1261,6 +1262,9 @@ namespace dxvk {
|
|||||||
VkDescriptorSet set,
|
VkDescriptorSet set,
|
||||||
const DxvkPipelineLayout* layout);
|
const DxvkPipelineLayout* layout);
|
||||||
|
|
||||||
|
DxvkFramebufferInfo makeFramebufferInfo(
|
||||||
|
const DxvkRenderTargets& renderTargets);
|
||||||
|
|
||||||
void updateFramebuffer();
|
void updateFramebuffer();
|
||||||
|
|
||||||
void applyRenderTargetLoadLayouts();
|
void applyRenderTargetLoadLayouts();
|
||||||
@ -1282,8 +1286,8 @@ namespace dxvk {
|
|||||||
VkImageLayout oldLayout);
|
VkImageLayout oldLayout);
|
||||||
|
|
||||||
void updateRenderTargetLayouts(
|
void updateRenderTargetLayouts(
|
||||||
const Rc<DxvkFramebuffer>& newFb,
|
const DxvkFramebufferInfo& newFb,
|
||||||
const Rc<DxvkFramebuffer>& oldFb);
|
const DxvkFramebufferInfo& oldFb);
|
||||||
|
|
||||||
void prepareImage(
|
void prepareImage(
|
||||||
DxvkBarrierSet& barriers,
|
DxvkBarrierSet& barriers,
|
||||||
|
@ -105,7 +105,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkRenderTargets renderTargets;
|
DxvkRenderTargets renderTargets;
|
||||||
DxvkRenderPassOps renderPassOps;
|
DxvkRenderPassOps renderPassOps;
|
||||||
Rc<DxvkFramebuffer> framebuffer = nullptr;
|
DxvkFramebufferInfo framebufferInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,6 +41,14 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkFramebufferSize DxvkDevice::getDefaultFramebufferSize() const {
|
||||||
|
return DxvkFramebufferSize {
|
||||||
|
m_properties.core.properties.limits.maxFramebufferWidth,
|
||||||
|
m_properties.core.properties.limits.maxFramebufferHeight,
|
||||||
|
m_properties.core.properties.limits.maxFramebufferLayers };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
VkPipelineStageFlags DxvkDevice::getShaderPipelineStages() const {
|
VkPipelineStageFlags DxvkDevice::getShaderPipelineStages() const {
|
||||||
VkPipelineStageFlags result = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
|
VkPipelineStageFlags result = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
|
||||||
| VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
| VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
||||||
@ -106,16 +114,12 @@ namespace dxvk {
|
|||||||
|
|
||||||
Rc<DxvkFramebuffer> DxvkDevice::createFramebuffer(
|
Rc<DxvkFramebuffer> DxvkDevice::createFramebuffer(
|
||||||
const DxvkRenderTargets& renderTargets) {
|
const DxvkRenderTargets& renderTargets) {
|
||||||
const DxvkFramebufferSize defaultSize = {
|
|
||||||
m_properties.core.properties.limits.maxFramebufferWidth,
|
|
||||||
m_properties.core.properties.limits.maxFramebufferHeight,
|
|
||||||
m_properties.core.properties.limits.maxFramebufferLayers };
|
|
||||||
|
|
||||||
auto renderPassFormat = DxvkFramebuffer::getRenderPassFormat(renderTargets);
|
auto renderPassFormat = DxvkFramebuffer::getRenderPassFormat(renderTargets);
|
||||||
auto renderPassObject = m_objects.renderPassPool().getRenderPass(renderPassFormat);
|
auto renderPassObject = m_objects.renderPassPool().getRenderPass(renderPassFormat);
|
||||||
|
|
||||||
return new DxvkFramebuffer(m_vkd,
|
return new DxvkFramebuffer(m_vkd,
|
||||||
renderPassObject, renderTargets, defaultSize);
|
renderPassObject, renderTargets,
|
||||||
|
getDefaultFramebufferSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,6 +197,12 @@ namespace dxvk {
|
|||||||
*/
|
*/
|
||||||
bool isUnifiedMemoryArchitecture() const;
|
bool isUnifiedMemoryArchitecture() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Queries default framebuffer size
|
||||||
|
* \returns Default framebuffer size
|
||||||
|
*/
|
||||||
|
DxvkFramebufferSize getDefaultFramebufferSize() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Queries supported shader stages
|
* \brief Queries supported shader stages
|
||||||
* \returns Supported shader pipeline stages
|
* \returns Supported shader pipeline stages
|
||||||
|
@ -71,6 +71,14 @@ namespace dxvk {
|
|||||||
|
|
||||||
~DxvkFramebufferInfo();
|
~DxvkFramebufferInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieves all attachments
|
||||||
|
* \returns Render targets
|
||||||
|
*/
|
||||||
|
const DxvkRenderTargets& attachments() const {
|
||||||
|
return m_renderTargets;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Framebuffer size
|
* \brief Framebuffer size
|
||||||
* \returns Framebuffer size
|
* \returns Framebuffer size
|
||||||
|
Loading…
Reference in New Issue
Block a user