mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +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(
|
DxgiPresenter::DxgiPresenter(
|
||||||
const Rc<DxvkDevice>& device,
|
const Rc<DxvkDevice>& device,
|
||||||
HWND window,
|
HWND window,
|
||||||
UINT bufferWidth,
|
uint32_t bufferWidth,
|
||||||
UINT bufferHeight)
|
uint32_t bufferHeight,
|
||||||
|
DXGI_FORMAT bufferFormat)
|
||||||
: m_device (device),
|
: m_device (device),
|
||||||
m_context (device->createContext()) {
|
m_context (device->createContext()) {
|
||||||
|
|
||||||
@ -20,11 +21,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Create swap chain for the surface
|
// Create swap chain for the surface
|
||||||
DxvkSwapchainProperties swapchainProperties;
|
DxvkSwapchainProperties swapchainProperties;
|
||||||
swapchainProperties.preferredSurfaceFormat.format = VK_FORMAT_B8G8R8A8_SRGB;
|
swapchainProperties.preferredSurfaceFormat = this->pickFormat(bufferFormat);
|
||||||
swapchainProperties.preferredSurfaceFormat.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
||||||
swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
|
swapchainProperties.preferredBufferSize.width = bufferWidth;
|
||||||
swapchainProperties.preferredBufferSize.width = bufferWidth;
|
swapchainProperties.preferredBufferSize.height = bufferHeight;
|
||||||
swapchainProperties.preferredBufferSize.height = bufferHeight;
|
|
||||||
|
|
||||||
m_swapchain = m_device->createSwapchain(
|
m_swapchain = m_device->createSwapchain(
|
||||||
m_surface, swapchainProperties);
|
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() {
|
Rc<DxvkShader> DxgiPresenter::createVertexShader() {
|
||||||
SpirvModule module;
|
SpirvModule module;
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <dxvk_surface.h>
|
#include <dxvk_surface.h>
|
||||||
#include <dxvk_swapchain.h>
|
#include <dxvk_swapchain.h>
|
||||||
|
|
||||||
|
#include "dxgi_include.h"
|
||||||
|
|
||||||
#include "../spirv/spirv_module.h"
|
#include "../spirv/spirv_module.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -22,8 +24,9 @@ namespace dxvk {
|
|||||||
DxgiPresenter(
|
DxgiPresenter(
|
||||||
const Rc<DxvkDevice>& device,
|
const Rc<DxvkDevice>& device,
|
||||||
HWND window,
|
HWND window,
|
||||||
UINT bufferWidth,
|
uint32_t bufferWidth,
|
||||||
UINT bufferHeight);
|
uint32_t bufferHeight,
|
||||||
|
DXGI_FORMAT bufferFormat);
|
||||||
|
|
||||||
~DxgiPresenter();
|
~DxgiPresenter();
|
||||||
|
|
||||||
@ -41,6 +44,15 @@ namespace dxvk {
|
|||||||
void presentImage(
|
void presentImage(
|
||||||
const Rc<DxvkImageView>& view);
|
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:
|
private:
|
||||||
|
|
||||||
enum BindingIds : uint32_t {
|
enum BindingIds : uint32_t {
|
||||||
@ -59,6 +71,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
Rc<DxvkSampler> m_sampler;
|
Rc<DxvkSampler> m_sampler;
|
||||||
|
|
||||||
|
VkSurfaceFormatKHR pickFormat(DXGI_FORMAT fmt) const;
|
||||||
|
|
||||||
Rc<DxvkShader> createVertexShader();
|
Rc<DxvkShader> createVertexShader();
|
||||||
Rc<DxvkShader> createFragmentShader();
|
Rc<DxvkShader> createFragmentShader();
|
||||||
|
|
||||||
|
@ -46,6 +46,13 @@ namespace dxvk {
|
|||||||
SDL_GetError()));
|
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
|
// Set initial window mode and fullscreen state
|
||||||
if (FAILED(this->SetFullscreenState(!pDesc->Windowed, nullptr)))
|
if (FAILED(this->SetFullscreenState(!pDesc->Windowed, nullptr)))
|
||||||
throw DxvkError("DxgiSwapChain::DxgiSwapChain: Failed to set initial fullscreen state");
|
throw DxvkError("DxgiSwapChain::DxgiSwapChain: Failed to set initial fullscreen state");
|
||||||
@ -187,15 +194,24 @@ namespace dxvk {
|
|||||||
UINT SwapChainFlags) {
|
UINT SwapChainFlags) {
|
||||||
std::lock_guard<std::mutex> lock(m_mutex);
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
m_desc.BufferDesc.Width = Width;
|
VkExtent2D windowSize = this->getWindowSize();
|
||||||
m_desc.BufferDesc.Height = Height;
|
|
||||||
m_desc.BufferDesc.Format = NewFormat;
|
m_desc.BufferDesc.Width = Width != 0 ? Width : windowSize.width;
|
||||||
m_desc.Flags = SwapChainFlags;
|
m_desc.BufferDesc.Height = Height != 0 ? Height : windowSize.height;
|
||||||
|
|
||||||
|
m_desc.Flags = SwapChainFlags;
|
||||||
|
|
||||||
if (BufferCount != 0)
|
if (BufferCount != 0)
|
||||||
m_desc.BufferCount = BufferCount;
|
m_desc.BufferCount = BufferCount;
|
||||||
|
|
||||||
|
if (NewFormat != DXGI_FORMAT_UNKNOWN)
|
||||||
|
m_desc.BufferDesc.Format = NewFormat;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
m_presenter->recreateSwapchain(
|
||||||
|
m_desc.BufferDesc.Width,
|
||||||
|
m_desc.BufferDesc.Height,
|
||||||
|
m_desc.BufferDesc.Format);
|
||||||
this->createBackBuffer();
|
this->createBackBuffer();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
} catch (const DxvkError& err) {
|
} catch (const DxvkError& err) {
|
||||||
@ -289,7 +305,8 @@ namespace dxvk {
|
|||||||
m_device->GetDXVKDevice(),
|
m_device->GetDXVKDevice(),
|
||||||
m_desc.OutputWindow,
|
m_desc.OutputWindow,
|
||||||
m_desc.BufferDesc.Width,
|
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);
|
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();
|
void createContext();
|
||||||
|
|
||||||
|
VkExtent2D getWindowSize() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,18 +32,24 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VkSurfaceFormatKHR DxvkSurface::pickSurfaceFormat(VkSurfaceFormatKHR preferred) const {
|
VkSurfaceFormatKHR DxvkSurface::pickSurfaceFormat(
|
||||||
// If the implementation allows us to freely choose
|
uint32_t preferredCount,
|
||||||
// the format, we'll just use the preferred format.
|
const VkSurfaceFormatKHR* preferred) const {
|
||||||
if (m_surfaceFormats.size() == 1 && m_surfaceFormats.at(0).format == VK_FORMAT_UNDEFINED)
|
if (preferredCount > 0) {
|
||||||
return preferred;
|
// If the implementation allows us to freely choose
|
||||||
|
// the format, we'll just use the preferred format.
|
||||||
// If the preferred format is explicitly listed in
|
if (m_surfaceFormats.size() == 1 && m_surfaceFormats.at(0).format == VK_FORMAT_UNDEFINED)
|
||||||
// the array of supported surface formats, use it
|
return preferred[0];
|
||||||
for (auto fmt : m_surfaceFormats) {
|
|
||||||
if (fmt.format == preferred.format
|
// If the preferred format is explicitly listed in
|
||||||
&& fmt.colorSpace == preferred.colorSpace)
|
// the array of supported surface formats, use it
|
||||||
return fmt;
|
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
|
// Otherwise, fall back to the first format
|
||||||
@ -51,10 +57,14 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VkPresentModeKHR DxvkSurface::pickPresentMode(VkPresentModeKHR preferred) const {
|
VkPresentModeKHR DxvkSurface::pickPresentMode(
|
||||||
for (auto mode : m_presentModes) {
|
uint32_t preferredCount,
|
||||||
if (mode == preferred)
|
const VkPresentModeKHR* preferred) const {
|
||||||
return mode;
|
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
|
// This mode is guaranteed to be available
|
||||||
|
@ -41,20 +41,24 @@ namespace dxvk {
|
|||||||
/**
|
/**
|
||||||
* \brief Picks a suitable surface format
|
* \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
|
* \returns The actual surface format
|
||||||
*/
|
*/
|
||||||
VkSurfaceFormatKHR pickSurfaceFormat(
|
VkSurfaceFormatKHR pickSurfaceFormat(
|
||||||
VkSurfaceFormatKHR preferred) const;
|
uint32_t preferredCount,
|
||||||
|
const VkSurfaceFormatKHR* preferred) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Picks a supported present mode
|
* \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
|
* \returns The actual present mode
|
||||||
*/
|
*/
|
||||||
VkPresentModeKHR pickPresentMode(
|
VkPresentModeKHR pickPresentMode(
|
||||||
VkPresentModeKHR preferred) const;
|
uint32_t preferredCount,
|
||||||
|
const VkPresentModeKHR* preferred) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Picks a suitable image count for a swap chain
|
* \brief Picks a suitable image count for a swap chain
|
||||||
|
@ -94,8 +94,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Recreate the actual swapchain object
|
// Recreate the actual swapchain object
|
||||||
auto caps = m_surface->getSurfaceCapabilities();
|
auto caps = m_surface->getSurfaceCapabilities();
|
||||||
auto fmt = m_surface->pickSurfaceFormat(m_properties.preferredSurfaceFormat);
|
auto fmt = m_surface->pickSurfaceFormat(1, &m_properties.preferredSurfaceFormat);
|
||||||
auto mode = m_surface->pickPresentMode (m_properties.preferredPresentMode);
|
auto mode = m_surface->pickPresentMode (1, &m_properties.preferredPresentMode);
|
||||||
|
|
||||||
VkSwapchainCreateInfoKHR swapInfo;
|
VkSwapchainCreateInfoKHR swapInfo;
|
||||||
swapInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
swapInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user