1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00
OpenDX/src/dxvk/dxvk_framebuffer.cpp
Philip Rebohle 4e06f498dd [d3d11] Fixed several mip level-related bugs
- When a D3D11 texture was created with a mip level count of zero,
  DXVK would compute the correct number of mip levels, but not write
  them back to the description field.
- Framebuffers would always use the size of the top level, not the
  mip levels that were actually attached to the framebuffer.
- Several image copy operations did not handle mip levels other
  than the top mip level correctly.
2018-01-06 02:09:07 +01:00

105 lines
3.2 KiB
C++

#include "dxvk_framebuffer.h"
namespace dxvk {
DxvkRenderTargets:: DxvkRenderTargets() { }
DxvkRenderTargets::~DxvkRenderTargets() { }
DxvkRenderPassFormat DxvkRenderTargets::renderPassFormat() const {
DxvkRenderPassFormat result;
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
if (m_colorTargets.at(i) != nullptr) {
result.setColorFormat(i, m_colorTargets.at(i)->info().format);
result.setSampleCount(m_colorTargets.at(i)->image()->info().sampleCount);
}
}
if (m_depthTarget != nullptr) {
result.setDepthFormat(m_depthTarget->info().format);
result.setSampleCount(m_depthTarget->image()->info().sampleCount);
}
return result;
}
std::vector<VkImageView> DxvkRenderTargets::getAttachments() const {
std::vector<VkImageView> result;
if (m_depthTarget != nullptr)
result.push_back(m_depthTarget->handle());
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
if (m_colorTargets.at(i) != nullptr)
result.push_back(m_colorTargets.at(i)->handle());
}
return result;
}
DxvkFramebufferSize DxvkRenderTargets::getImageSize() const {
if (m_depthTarget != nullptr)
return this->renderTargetSize(m_depthTarget);
for (uint32_t i = 0; i < MaxNumRenderTargets; i++) {
if (m_colorTargets.at(i) != nullptr)
return this->renderTargetSize(m_colorTargets.at(i));
}
return DxvkFramebufferSize { 0, 0, 0 };
}
bool DxvkRenderTargets::hasAttachments() const {
bool result = m_depthTarget != nullptr;
for (uint32_t i = 0; (i < MaxNumRenderTargets) && !result; i++)
result |= m_colorTargets.at(i) != nullptr;
return result;
}
DxvkFramebufferSize DxvkRenderTargets::renderTargetSize(
const Rc<DxvkImageView>& renderTarget) const {
auto extent = renderTarget->mipLevelExtent(0);
auto layers = renderTarget->info().numLayers;
return DxvkFramebufferSize { extent.width, extent.height, layers };
}
DxvkFramebuffer::DxvkFramebuffer(
const Rc<vk::DeviceFn>& vkd,
const Rc<DxvkRenderPass>& renderPass,
const DxvkRenderTargets& renderTargets)
: m_vkd (vkd),
m_renderPass (renderPass),
m_renderTargets (renderTargets),
m_framebufferSize (renderTargets.getImageSize()) {
auto views = renderTargets.getAttachments();
VkFramebufferCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
info.pNext = nullptr;
info.flags = 0;
info.renderPass = renderPass->handle();
info.attachmentCount = views.size();
info.pAttachments = views.data();
info.width = m_framebufferSize.width;
info.height = m_framebufferSize.height;
info.layers = m_framebufferSize.layers;
if (m_vkd->vkCreateFramebuffer(m_vkd->device(), &info, nullptr, &m_framebuffer) != VK_SUCCESS)
throw DxvkError("DxvkFramebuffer::DxvkFramebuffer: Failed to create framebuffer object");
}
DxvkFramebuffer::~DxvkFramebuffer() {
m_vkd->vkDestroyFramebuffer(
m_vkd->device(), m_framebuffer, nullptr);
}
}