mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-21 22:54:16 +01:00
[dxvk] Remove DxvkSwapChain
This commit is contained in:
parent
9139fbf95d
commit
9b923bb386
@ -9,7 +9,6 @@
|
|||||||
#include "../d3d11/d3d11_interfaces.h"
|
#include "../d3d11/d3d11_interfaces.h"
|
||||||
|
|
||||||
#include "../dxvk/dxvk_surface.h"
|
#include "../dxvk/dxvk_surface.h"
|
||||||
#include "../dxvk/dxvk_swapchain.h"
|
|
||||||
|
|
||||||
#include "../spirv/spirv_module.h"
|
#include "../spirv/spirv_module.h"
|
||||||
|
|
||||||
|
@ -204,13 +204,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkSwapchain> DxvkDevice::createSwapchain(
|
|
||||||
const Rc<DxvkSurface>& surface,
|
|
||||||
const DxvkSwapchainProperties& properties) {
|
|
||||||
return new DxvkSwapchain(this, surface, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkStatCounters DxvkDevice::getStatCounters() {
|
DxvkStatCounters DxvkDevice::getStatCounters() {
|
||||||
DxvkMemoryStats mem = m_memory->getMemoryStats();
|
DxvkMemoryStats mem = m_memory->getMemoryStats();
|
||||||
DxvkPipelineCount pipe = m_pipelineManager->getPipelineCount();
|
DxvkPipelineCount pipe = m_pipelineManager->getPipelineCount();
|
||||||
@ -242,18 +235,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VkResult DxvkDevice::presentSwapImage(
|
|
||||||
const VkPresentInfoKHR& presentInfo) {
|
|
||||||
{ // Queue submissions are not thread safe
|
|
||||||
std::lock_guard<std::mutex> queueLock(m_submissionLock);
|
|
||||||
std::lock_guard<sync::Spinlock> statLock(m_statLock);
|
|
||||||
|
|
||||||
m_statCounters.addCtr(DxvkStatCounter::QueuePresentCount, 1);
|
|
||||||
return m_vkd->vkQueuePresentKHR(m_presentQueue.queueHandle, &presentInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkResult DxvkDevice::presentImage(
|
VkResult DxvkDevice::presentImage(
|
||||||
const Rc<vk::Presenter>& presenter,
|
const Rc<vk::Presenter>& presenter,
|
||||||
VkSemaphore semaphore) {
|
VkSemaphore semaphore) {
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include "dxvk_sampler.h"
|
#include "dxvk_sampler.h"
|
||||||
#include "dxvk_shader.h"
|
#include "dxvk_shader.h"
|
||||||
#include "dxvk_stats.h"
|
#include "dxvk_stats.h"
|
||||||
#include "dxvk_swapchain.h"
|
|
||||||
#include "dxvk_sync.h"
|
#include "dxvk_sync.h"
|
||||||
#include "dxvk_unbound.h"
|
#include "dxvk_unbound.h"
|
||||||
|
|
||||||
@ -287,17 +286,6 @@ namespace dxvk {
|
|||||||
const DxvkInterfaceSlots& iface,
|
const DxvkInterfaceSlots& iface,
|
||||||
const SpirvCodeBuffer& code);
|
const SpirvCodeBuffer& code);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Creates a swap chain
|
|
||||||
*
|
|
||||||
* \param [in] surface The target surface
|
|
||||||
* \param [in] properties Swapchain properties
|
|
||||||
* \returns The swapchain object
|
|
||||||
*/
|
|
||||||
Rc<DxvkSwapchain> createSwapchain(
|
|
||||||
const Rc<DxvkSurface>& surface,
|
|
||||||
const DxvkSwapchainProperties& properties);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieves stat counters
|
* \brief Retrieves stat counters
|
||||||
*
|
*
|
||||||
@ -329,17 +317,6 @@ namespace dxvk {
|
|||||||
void registerShader(
|
void registerShader(
|
||||||
const Rc<DxvkShader>& shader);
|
const Rc<DxvkShader>& shader);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Presents a swap chain image
|
|
||||||
*
|
|
||||||
* This is implicitly called by the swap chain class
|
|
||||||
* when presenting an image. Do not use this directly.
|
|
||||||
* \param [in] presentInfo Swap image present info
|
|
||||||
* \returns Present status
|
|
||||||
*/
|
|
||||||
VkResult presentSwapImage(
|
|
||||||
const VkPresentInfoKHR& presentInfo);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Presents a swap chain image
|
* \brief Presents a swap chain image
|
||||||
*
|
*
|
||||||
|
@ -1,200 +0,0 @@
|
|||||||
#include "dxvk_main.h"
|
|
||||||
|
|
||||||
#include "dxvk_device.h"
|
|
||||||
#include "dxvk_framebuffer.h"
|
|
||||||
#include "dxvk_surface.h"
|
|
||||||
#include "dxvk_swapchain.h"
|
|
||||||
|
|
||||||
namespace dxvk {
|
|
||||||
|
|
||||||
DxvkSwapchain::DxvkSwapchain(
|
|
||||||
const Rc<DxvkDevice>& device,
|
|
||||||
const Rc<DxvkSurface>& surface,
|
|
||||||
const DxvkSwapchainProperties& properties)
|
|
||||||
: m_device (device),
|
|
||||||
m_vkd (device->vkd()),
|
|
||||||
m_surface (surface),
|
|
||||||
m_properties(properties) {
|
|
||||||
this->recreateSwapchain();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkSwapchain::~DxvkSwapchain() {
|
|
||||||
m_device->waitForIdle();
|
|
||||||
m_vkd->vkDestroySwapchainKHR(
|
|
||||||
m_vkd->device(), m_handle, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxvkSwapSemaphores DxvkSwapchain::getSemaphorePair() {
|
|
||||||
// It doesn't really matter that we increment the
|
|
||||||
// counter *before* returning the semaphore pair
|
|
||||||
m_frameIndex = (m_frameIndex + 1) % m_semaphoreSet.size();
|
|
||||||
return m_semaphoreSet.at(m_frameIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Rc<DxvkImageView> DxvkSwapchain::getImageView(
|
|
||||||
const Rc<DxvkSemaphore>& wakeSync) {
|
|
||||||
// AcquireNextImage might interfere with the Vulkan
|
|
||||||
// device queue internally, so we should lock it
|
|
||||||
m_device->lockSubmission();
|
|
||||||
|
|
||||||
VkResult status = this->acquireNextImage(wakeSync);
|
|
||||||
|
|
||||||
if (status == VK_ERROR_OUT_OF_DATE_KHR) {
|
|
||||||
this->recreateSwapchain();
|
|
||||||
status = this->acquireNextImage(wakeSync);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_device->unlockSubmission();
|
|
||||||
|
|
||||||
if (status != VK_SUCCESS
|
|
||||||
&& status != VK_SUBOPTIMAL_KHR)
|
|
||||||
throw DxvkError("DxvkSwapchain: Failed to acquire image");
|
|
||||||
|
|
||||||
return m_framebuffers.at(m_imageIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DxvkSwapchain::present(const Rc<DxvkSemaphore>& waitSync) {
|
|
||||||
const VkSemaphore waitSemaphore = waitSync->handle();
|
|
||||||
|
|
||||||
VkPresentInfoKHR info;
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
||||||
info.pNext = nullptr;
|
|
||||||
info.waitSemaphoreCount = 1;
|
|
||||||
info.pWaitSemaphores = &waitSemaphore;
|
|
||||||
info.swapchainCount = 1;
|
|
||||||
info.pSwapchains = &m_handle;
|
|
||||||
info.pImageIndices = &m_imageIndex;
|
|
||||||
info.pResults = nullptr;
|
|
||||||
|
|
||||||
VkResult status = m_device->presentSwapImage(info);
|
|
||||||
|
|
||||||
if (status == VK_SUBOPTIMAL_KHR
|
|
||||||
|| status == VK_ERROR_OUT_OF_DATE_KHR)
|
|
||||||
this->recreateSwapchain();
|
|
||||||
else if (status != VK_SUCCESS)
|
|
||||||
throw DxvkError("DxvkSwapchain: Failed to present image");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DxvkSwapchain::changeProperties(
|
|
||||||
const DxvkSwapchainProperties& props) {
|
|
||||||
m_properties = props;
|
|
||||||
this->recreateSwapchain();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VkResult DxvkSwapchain::acquireNextImage(
|
|
||||||
const Rc<DxvkSemaphore>& wakeSync) {
|
|
||||||
return m_vkd->vkAcquireNextImageKHR(
|
|
||||||
m_vkd->device(), m_handle,
|
|
||||||
std::numeric_limits<uint64_t>::max(),
|
|
||||||
wakeSync->handle(),
|
|
||||||
VK_NULL_HANDLE,
|
|
||||||
&m_imageIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DxvkSwapchain::recreateSwapchain() {
|
|
||||||
// Wait until we can be certain that none of our
|
|
||||||
// resources are still in use by the device.
|
|
||||||
m_device->waitForIdle();
|
|
||||||
|
|
||||||
// Destroy previous swapchain object
|
|
||||||
m_vkd->vkDestroySwapchainKHR(
|
|
||||||
m_vkd->device(), m_handle, nullptr);
|
|
||||||
|
|
||||||
// Recreate the actual swapchain object
|
|
||||||
auto caps = m_surface->getSurfaceCapabilities();
|
|
||||||
auto fmt = m_surface->pickSurfaceFormat(1, &m_properties.preferredSurfaceFormat);
|
|
||||||
auto mode = m_surface->pickPresentMode (1, &m_properties.preferredPresentMode);
|
|
||||||
|
|
||||||
VkSwapchainCreateInfoKHR swapInfo;
|
|
||||||
swapInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
|
||||||
swapInfo.pNext = nullptr;
|
|
||||||
swapInfo.flags = 0;
|
|
||||||
swapInfo.surface = m_surface->handle();
|
|
||||||
swapInfo.minImageCount = m_surface->pickImageCount(caps, mode, m_properties.preferredBufferCount);
|
|
||||||
swapInfo.imageFormat = fmt.format;
|
|
||||||
swapInfo.imageColorSpace = fmt.colorSpace;
|
|
||||||
swapInfo.imageExtent = m_surface->pickImageExtent(caps, m_properties.preferredBufferSize);
|
|
||||||
swapInfo.imageArrayLayers = 1;
|
|
||||||
swapInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
||||||
swapInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
||||||
swapInfo.queueFamilyIndexCount = 0;
|
|
||||||
swapInfo.pQueueFamilyIndices = nullptr;
|
|
||||||
swapInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
|
||||||
swapInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
|
||||||
swapInfo.presentMode = mode;
|
|
||||||
swapInfo.clipped = VK_TRUE;
|
|
||||||
swapInfo.oldSwapchain = VK_NULL_HANDLE;
|
|
||||||
|
|
||||||
Logger::debug(str::format(
|
|
||||||
"DxvkSwapchain: Actual swap chain properties: ",
|
|
||||||
"\n Format: ", swapInfo.imageFormat,
|
|
||||||
"\n Present mode: ", swapInfo.presentMode,
|
|
||||||
"\n Buffer size: ", swapInfo.imageExtent.width, "x", swapInfo.imageExtent.height,
|
|
||||||
"\n Image count: ", swapInfo.minImageCount));
|
|
||||||
|
|
||||||
if (m_vkd->vkCreateSwapchainKHR(m_vkd->device(), &swapInfo, nullptr, &m_handle) != VK_SUCCESS)
|
|
||||||
throw DxvkError("DxvkSwapchain: Failed to recreate swap chain");
|
|
||||||
|
|
||||||
// Retrieve swap images
|
|
||||||
auto swapImages = this->retrieveSwapImages();
|
|
||||||
|
|
||||||
m_framebuffers.resize(swapImages.size());
|
|
||||||
m_semaphoreSet.resize(swapImages.size());
|
|
||||||
|
|
||||||
DxvkImageCreateInfo imageInfo;
|
|
||||||
imageInfo.type = VK_IMAGE_TYPE_2D;
|
|
||||||
imageInfo.format = fmt.format;
|
|
||||||
imageInfo.flags = 0;
|
|
||||||
imageInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
|
||||||
imageInfo.extent.width = swapInfo.imageExtent.width;
|
|
||||||
imageInfo.extent.height = swapInfo.imageExtent.height;
|
|
||||||
imageInfo.extent.depth = 1;
|
|
||||||
imageInfo.numLayers = swapInfo.imageArrayLayers;
|
|
||||||
imageInfo.mipLevels = 1;
|
|
||||||
imageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
||||||
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
||||||
imageInfo.stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
||||||
imageInfo.access = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
|
||||||
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
|
||||||
| VK_ACCESS_MEMORY_READ_BIT;
|
|
||||||
imageInfo.layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
||||||
|
|
||||||
DxvkImageViewCreateInfo viewInfo;
|
|
||||||
viewInfo.type = VK_IMAGE_VIEW_TYPE_2D;
|
|
||||||
viewInfo.format = fmt.format;
|
|
||||||
viewInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
||||||
viewInfo.aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
viewInfo.minLevel = 0;
|
|
||||||
viewInfo.numLevels = 1;
|
|
||||||
viewInfo.minLayer = 0;
|
|
||||||
viewInfo.numLayers = swapInfo.imageArrayLayers;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < swapImages.size(); i++) {
|
|
||||||
m_framebuffers.at(i) = m_device->createImageView(
|
|
||||||
new DxvkImage(m_vkd, imageInfo, swapImages.at(i)), viewInfo);
|
|
||||||
|
|
||||||
m_semaphoreSet.at(i).acquireSync = m_device->createSemaphore();
|
|
||||||
m_semaphoreSet.at(i).presentSync = m_device->createSemaphore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::vector<VkImage> DxvkSwapchain::retrieveSwapImages() {
|
|
||||||
uint32_t imageCount = 0;
|
|
||||||
if (m_vkd->vkGetSwapchainImagesKHR(m_vkd->device(), m_handle, &imageCount, nullptr) != VK_SUCCESS)
|
|
||||||
throw DxvkError("DxvkSwapchain: Failed to retrieve swap chain images");
|
|
||||||
|
|
||||||
std::vector<VkImage> images(imageCount);
|
|
||||||
if (m_vkd->vkGetSwapchainImagesKHR(m_vkd->device(), m_handle, &imageCount, images.data()) != VK_SUCCESS)
|
|
||||||
throw DxvkError("DxvkSwapchain: Failed to retrieve swap chain images");
|
|
||||||
return images;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "dxvk_framebuffer.h"
|
|
||||||
#include "dxvk_sync.h"
|
|
||||||
|
|
||||||
namespace dxvk {
|
|
||||||
|
|
||||||
class DxvkDevice;
|
|
||||||
class DxvkFramebuffer;
|
|
||||||
class DxvkSurface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Swap chain semaphore pair
|
|
||||||
*
|
|
||||||
* Holds the two semaphores requires for
|
|
||||||
* synchronizing swap chain operations.
|
|
||||||
*/
|
|
||||||
struct DxvkSwapSemaphores {
|
|
||||||
Rc<DxvkSemaphore> acquireSync; ///< Post-acquire semaphore
|
|
||||||
Rc<DxvkSemaphore> presentSync; ///< Pre-present semaphore
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Swap chain properties
|
|
||||||
*/
|
|
||||||
struct DxvkSwapchainProperties {
|
|
||||||
VkSurfaceFormatKHR preferredSurfaceFormat;
|
|
||||||
VkPresentModeKHR preferredPresentMode;
|
|
||||||
VkExtent2D preferredBufferSize;
|
|
||||||
uint32_t preferredBufferCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief DXVK swapchain
|
|
||||||
*
|
|
||||||
* Manages a Vulkan swap chain object. Implements
|
|
||||||
* acquire and present methods and recreates the
|
|
||||||
* underlying swap chain object as necessary.
|
|
||||||
*/
|
|
||||||
class DxvkSwapchain : public RcObject {
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DxvkSwapchain(
|
|
||||||
const Rc<DxvkDevice>& device,
|
|
||||||
const Rc<DxvkSurface>& surface,
|
|
||||||
const DxvkSwapchainProperties& properties);
|
|
||||||
~DxvkSwapchain();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Acquires a pair of semaphores
|
|
||||||
*
|
|
||||||
* Retrieves a set of semaphores for the acquire
|
|
||||||
* and present operations. This must be called
|
|
||||||
* \e before \c getImageView.
|
|
||||||
* \returns Semaphore pair
|
|
||||||
*/
|
|
||||||
DxvkSwapSemaphores getSemaphorePair();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Retrieves the image view for the current frame
|
|
||||||
*
|
|
||||||
* If necessary, this will automatically recreate the
|
|
||||||
* underlying swapchain object and image view objects.
|
|
||||||
* \param [in] wakeSync Semaphore to signal
|
|
||||||
* \returns The image view object
|
|
||||||
*/
|
|
||||||
Rc<DxvkImageView> getImageView(
|
|
||||||
const Rc<DxvkSemaphore>& wakeSync);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Presents the current framebuffer
|
|
||||||
*
|
|
||||||
* This may actually fail to present an image. If that is the
|
|
||||||
* case, the surface contents will be undefined for this frame
|
|
||||||
* and the swapchain object will be recreated.
|
|
||||||
* \param [in] waitSync Semaphore to wait on
|
|
||||||
*/
|
|
||||||
void present(
|
|
||||||
const Rc<DxvkSemaphore>& waitSync);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Changes swapchain properties
|
|
||||||
*
|
|
||||||
* This must not be called between \ref getImageView
|
|
||||||
* and \ref present as this method may recreate the swap
|
|
||||||
* chain and framebuffer objects immediately.
|
|
||||||
* \param [in] props New swapchain properties
|
|
||||||
*/
|
|
||||||
void changeProperties(
|
|
||||||
const DxvkSwapchainProperties& props);
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
Rc<DxvkDevice> m_device;
|
|
||||||
Rc<vk::DeviceFn> m_vkd;
|
|
||||||
Rc<DxvkSurface> m_surface;
|
|
||||||
|
|
||||||
DxvkSwapchainProperties m_properties;
|
|
||||||
VkSwapchainKHR m_handle = VK_NULL_HANDLE;
|
|
||||||
uint32_t m_imageIndex = 0;
|
|
||||||
uint32_t m_frameIndex = 0;
|
|
||||||
|
|
||||||
std::vector<Rc<DxvkImageView>> m_framebuffers;
|
|
||||||
std::vector<DxvkSwapSemaphores> m_semaphoreSet;
|
|
||||||
|
|
||||||
VkResult acquireNextImage(
|
|
||||||
const Rc<DxvkSemaphore>& wakeSync);
|
|
||||||
|
|
||||||
void recreateSwapchain();
|
|
||||||
|
|
||||||
std::vector<VkImage> retrieveSwapImages();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -87,7 +87,6 @@ dxvk_src = files([
|
|||||||
'dxvk_state_cache.cpp',
|
'dxvk_state_cache.cpp',
|
||||||
'dxvk_stats.cpp',
|
'dxvk_stats.cpp',
|
||||||
'dxvk_surface.cpp',
|
'dxvk_surface.cpp',
|
||||||
'dxvk_swapchain.cpp',
|
|
||||||
'dxvk_sync.cpp',
|
'dxvk_sync.cpp',
|
||||||
'dxvk_unbound.cpp',
|
'dxvk_unbound.cpp',
|
||||||
'dxvk_util.cpp',
|
'dxvk_util.cpp',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user