1
0
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:
Philip Rebohle 2021-11-03 17:55:06 +01:00
parent 5b725205ef
commit f1aad6cb7b
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 119 additions and 96 deletions

View File

@ -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))) {

View File

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

View File

@ -105,7 +105,7 @@ namespace dxvk {
DxvkRenderTargets renderTargets; DxvkRenderTargets renderTargets;
DxvkRenderPassOps renderPassOps; DxvkRenderPassOps renderPassOps;
Rc<DxvkFramebuffer> framebuffer = nullptr; DxvkFramebufferInfo framebufferInfo;
}; };

View File

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

View File

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

View File

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