mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +01:00
[dxgi] DxgiPresenter now picks format depending on swap chain format
This commit is contained in:
parent
365f992a97
commit
f1ee761290
@ -7,8 +7,9 @@ namespace dxvk {
|
||||
DxgiPresenter::DxgiPresenter(
|
||||
const Rc<DxvkDevice>& device,
|
||||
HWND window,
|
||||
UINT bufferWidth,
|
||||
UINT bufferHeight)
|
||||
uint32_t bufferWidth,
|
||||
uint32_t bufferHeight,
|
||||
DXGI_FORMAT bufferFormat)
|
||||
: m_device (device),
|
||||
m_context (device->createContext()) {
|
||||
|
||||
@ -20,11 +21,10 @@ namespace dxvk {
|
||||
|
||||
// Create swap chain for the surface
|
||||
DxvkSwapchainProperties swapchainProperties;
|
||||
swapchainProperties.preferredSurfaceFormat.format = VK_FORMAT_B8G8R8A8_SRGB;
|
||||
swapchainProperties.preferredSurfaceFormat.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||
swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
swapchainProperties.preferredBufferSize.width = bufferWidth;
|
||||
swapchainProperties.preferredBufferSize.height = bufferHeight;
|
||||
swapchainProperties.preferredSurfaceFormat = this->pickFormat(bufferFormat);
|
||||
swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
swapchainProperties.preferredBufferSize.width = bufferWidth;
|
||||
swapchainProperties.preferredBufferSize.height = bufferHeight;
|
||||
|
||||
m_swapchain = m_device->createSwapchain(
|
||||
m_surface, swapchainProperties);
|
||||
@ -173,6 +173,45 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxgiPresenter::recreateSwapchain(
|
||||
uint32_t bufferWidth,
|
||||
uint32_t bufferHeight,
|
||||
DXGI_FORMAT bufferFormat) {
|
||||
DxvkSwapchainProperties swapchainProperties;
|
||||
swapchainProperties.preferredSurfaceFormat = this->pickFormat(bufferFormat);
|
||||
swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||
swapchainProperties.preferredBufferSize.width = bufferWidth;
|
||||
swapchainProperties.preferredBufferSize.height = bufferHeight;
|
||||
|
||||
m_swapchain->changeProperties(swapchainProperties);
|
||||
}
|
||||
|
||||
|
||||
VkSurfaceFormatKHR DxgiPresenter::pickFormat(DXGI_FORMAT fmt) const {
|
||||
std::vector<VkSurfaceFormatKHR> formats;
|
||||
|
||||
switch (fmt) {
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM:
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM: {
|
||||
formats.push_back({ VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR });
|
||||
formats.push_back({ VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR });
|
||||
} break;
|
||||
|
||||
case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
|
||||
case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: {
|
||||
formats.push_back({ VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR });
|
||||
formats.push_back({ VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR });
|
||||
} break;
|
||||
|
||||
default:
|
||||
Logger::warn(str::format("DxgiPresenter: Unknown format: ", fmt));
|
||||
}
|
||||
|
||||
return m_surface->pickSurfaceFormat(
|
||||
formats.size(), formats.data());
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkShader> DxgiPresenter::createVertexShader() {
|
||||
SpirvModule module;
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <dxvk_surface.h>
|
||||
#include <dxvk_swapchain.h>
|
||||
|
||||
#include "dxgi_include.h"
|
||||
|
||||
#include "../spirv/spirv_module.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -22,8 +24,9 @@ namespace dxvk {
|
||||
DxgiPresenter(
|
||||
const Rc<DxvkDevice>& device,
|
||||
HWND window,
|
||||
UINT bufferWidth,
|
||||
UINT bufferHeight);
|
||||
uint32_t bufferWidth,
|
||||
uint32_t bufferHeight,
|
||||
DXGI_FORMAT bufferFormat);
|
||||
|
||||
~DxgiPresenter();
|
||||
|
||||
@ -41,6 +44,15 @@ namespace dxvk {
|
||||
void presentImage(
|
||||
const Rc<DxvkImageView>& view);
|
||||
|
||||
/**
|
||||
* \brief Renders image to the screen
|
||||
* \param [in] view Source image view
|
||||
*/
|
||||
void recreateSwapchain(
|
||||
uint32_t bufferWidth,
|
||||
uint32_t bufferHeight,
|
||||
DXGI_FORMAT bufferFormat);
|
||||
|
||||
private:
|
||||
|
||||
enum BindingIds : uint32_t {
|
||||
@ -59,6 +71,8 @@ namespace dxvk {
|
||||
|
||||
Rc<DxvkSampler> m_sampler;
|
||||
|
||||
VkSurfaceFormatKHR pickFormat(DXGI_FORMAT fmt) const;
|
||||
|
||||
Rc<DxvkShader> createVertexShader();
|
||||
Rc<DxvkShader> createFragmentShader();
|
||||
|
||||
|
@ -46,6 +46,13 @@ namespace dxvk {
|
||||
SDL_GetError()));
|
||||
}
|
||||
|
||||
// Adjust initial back buffer size. If zero, these
|
||||
// shall be set to the current window size.
|
||||
VkExtent2D windowSize = this->getWindowSize();
|
||||
|
||||
if (m_desc.BufferDesc.Width == 0) m_desc.BufferDesc.Width = windowSize.width;
|
||||
if (m_desc.BufferDesc.Height == 0) m_desc.BufferDesc.Height = windowSize.height;
|
||||
|
||||
// Set initial window mode and fullscreen state
|
||||
if (FAILED(this->SetFullscreenState(!pDesc->Windowed, nullptr)))
|
||||
throw DxvkError("DxgiSwapChain::DxgiSwapChain: Failed to set initial fullscreen state");
|
||||
@ -187,15 +194,24 @@ namespace dxvk {
|
||||
UINT SwapChainFlags) {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
m_desc.BufferDesc.Width = Width;
|
||||
m_desc.BufferDesc.Height = Height;
|
||||
m_desc.BufferDesc.Format = NewFormat;
|
||||
m_desc.Flags = SwapChainFlags;
|
||||
VkExtent2D windowSize = this->getWindowSize();
|
||||
|
||||
m_desc.BufferDesc.Width = Width != 0 ? Width : windowSize.width;
|
||||
m_desc.BufferDesc.Height = Height != 0 ? Height : windowSize.height;
|
||||
|
||||
m_desc.Flags = SwapChainFlags;
|
||||
|
||||
if (BufferCount != 0)
|
||||
m_desc.BufferCount = BufferCount;
|
||||
m_desc.BufferCount = BufferCount;
|
||||
|
||||
if (NewFormat != DXGI_FORMAT_UNKNOWN)
|
||||
m_desc.BufferDesc.Format = NewFormat;
|
||||
|
||||
try {
|
||||
m_presenter->recreateSwapchain(
|
||||
m_desc.BufferDesc.Width,
|
||||
m_desc.BufferDesc.Height,
|
||||
m_desc.BufferDesc.Format);
|
||||
this->createBackBuffer();
|
||||
return S_OK;
|
||||
} catch (const DxvkError& err) {
|
||||
@ -289,7 +305,8 @@ namespace dxvk {
|
||||
m_device->GetDXVKDevice(),
|
||||
m_desc.OutputWindow,
|
||||
m_desc.BufferDesc.Width,
|
||||
m_desc.BufferDesc.Height);
|
||||
m_desc.BufferDesc.Height,
|
||||
m_desc.BufferDesc.Format);
|
||||
}
|
||||
|
||||
|
||||
@ -369,4 +386,17 @@ namespace dxvk {
|
||||
m_presenter->initBackBuffer(m_backBuffer);
|
||||
}
|
||||
|
||||
|
||||
VkExtent2D DxgiSwapChain::getWindowSize() const {
|
||||
int winWidth = 0;
|
||||
int winHeight = 0;
|
||||
|
||||
SDL_GetWindowSize(m_window, &winWidth, &winHeight);
|
||||
|
||||
VkExtent2D result;
|
||||
result.width = winWidth;
|
||||
result.height = winHeight;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -113,6 +113,8 @@ namespace dxvk {
|
||||
|
||||
void createContext();
|
||||
|
||||
VkExtent2D getWindowSize() const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -32,18 +32,24 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
VkSurfaceFormatKHR DxvkSurface::pickSurfaceFormat(VkSurfaceFormatKHR preferred) const {
|
||||
// If the implementation allows us to freely choose
|
||||
// the format, we'll just use the preferred format.
|
||||
if (m_surfaceFormats.size() == 1 && m_surfaceFormats.at(0).format == VK_FORMAT_UNDEFINED)
|
||||
return preferred;
|
||||
|
||||
// If the preferred format is explicitly listed in
|
||||
// the array of supported surface formats, use it
|
||||
for (auto fmt : m_surfaceFormats) {
|
||||
if (fmt.format == preferred.format
|
||||
&& fmt.colorSpace == preferred.colorSpace)
|
||||
return fmt;
|
||||
VkSurfaceFormatKHR DxvkSurface::pickSurfaceFormat(
|
||||
uint32_t preferredCount,
|
||||
const VkSurfaceFormatKHR* preferred) const {
|
||||
if (preferredCount > 0) {
|
||||
// If the implementation allows us to freely choose
|
||||
// the format, we'll just use the preferred format.
|
||||
if (m_surfaceFormats.size() == 1 && m_surfaceFormats.at(0).format == VK_FORMAT_UNDEFINED)
|
||||
return preferred[0];
|
||||
|
||||
// If the preferred format is explicitly listed in
|
||||
// the array of supported surface formats, use it
|
||||
for (uint32_t i = 0; i < preferredCount; i++) {
|
||||
for (auto fmt : m_surfaceFormats) {
|
||||
if (fmt.format == preferred[i].format
|
||||
&& fmt.colorSpace == preferred[i].colorSpace)
|
||||
return fmt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, fall back to the first format
|
||||
@ -51,10 +57,14 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
VkPresentModeKHR DxvkSurface::pickPresentMode(VkPresentModeKHR preferred) const {
|
||||
for (auto mode : m_presentModes) {
|
||||
if (mode == preferred)
|
||||
return mode;
|
||||
VkPresentModeKHR DxvkSurface::pickPresentMode(
|
||||
uint32_t preferredCount,
|
||||
const VkPresentModeKHR* preferred) const {
|
||||
for (uint32_t i = 0; i < preferredCount; i++) {
|
||||
for (auto mode : m_presentModes) {
|
||||
if (mode == preferred[i])
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
// This mode is guaranteed to be available
|
||||
|
@ -41,20 +41,24 @@ namespace dxvk {
|
||||
/**
|
||||
* \brief Picks a suitable surface format
|
||||
*
|
||||
* \param [in] preferred Preferred surface format
|
||||
* \param [in] preferredCount Number of formats to probe
|
||||
* \param [in] preferred Preferred surface formats
|
||||
* \returns The actual surface format
|
||||
*/
|
||||
VkSurfaceFormatKHR pickSurfaceFormat(
|
||||
VkSurfaceFormatKHR preferred) const;
|
||||
uint32_t preferredCount,
|
||||
const VkSurfaceFormatKHR* preferred) const;
|
||||
|
||||
/**
|
||||
* \brief Picks a supported present mode
|
||||
*
|
||||
* \param [in] preferred The preferred present mode
|
||||
* \param [in] preferredCount Number of modes to probe
|
||||
* \param [in] preferred Preferred present modes
|
||||
* \returns The actual present mode
|
||||
*/
|
||||
VkPresentModeKHR pickPresentMode(
|
||||
VkPresentModeKHR preferred) const;
|
||||
uint32_t preferredCount,
|
||||
const VkPresentModeKHR* preferred) const;
|
||||
|
||||
/**
|
||||
* \brief Picks a suitable image count for a swap chain
|
||||
|
@ -94,8 +94,8 @@ namespace dxvk {
|
||||
|
||||
// Recreate the actual swapchain object
|
||||
auto caps = m_surface->getSurfaceCapabilities();
|
||||
auto fmt = m_surface->pickSurfaceFormat(m_properties.preferredSurfaceFormat);
|
||||
auto mode = m_surface->pickPresentMode (m_properties.preferredPresentMode);
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user