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