1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-28 07:54:14 +01:00

[dxgi] DxgiVkPresenter: use Microsoft-style API

This commit is contained in:
Philip Rebohle 2018-04-13 13:57:29 +02:00
parent 5d7c83855e
commit ded6dec7eb
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 85 additions and 89 deletions

View File

@ -7,7 +7,7 @@
namespace dxvk { namespace dxvk {
DxgiPresenter::DxgiPresenter( DxgiVkPresenter::DxgiVkPresenter(
const Rc<DxvkDevice>& device, const Rc<DxvkDevice>& device,
HWND window) HWND window)
: m_device (device), : m_device (device),
@ -28,16 +28,16 @@ namespace dxvk {
// Samplers for presentation. We'll create one with point sampling that will // Samplers for presentation. We'll create one with point sampling that will
// be used when the back buffer resolution matches the output resolution, and // be used when the back buffer resolution matches the output resolution, and
// one with linar sampling that will be used when the image will be scaled. // one with linar sampling that will be used when the image will be scaled.
m_samplerFitting = this->createSampler(VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER); m_samplerFitting = CreateSampler(VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
m_samplerScaling = this->createSampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER); m_samplerScaling = CreateSampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
// Create objects required for the gamma ramp. This is implemented partially // Create objects required for the gamma ramp. This is implemented partially
// with an UBO, which stores global parameters, and a lookup texture, which // with an UBO, which stores global parameters, and a lookup texture, which
// stores the actual gamma ramp and can be sampled with a linear filter. // stores the actual gamma ramp and can be sampled with a linear filter.
m_gammaUbo = this->createGammaUbo(); m_gammaUbo = CreateGammaUbo();
m_gammaSampler = this->createSampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE); m_gammaSampler = CreateSampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
m_gammaTexture = this->createGammaTexture(); m_gammaTexture = CreateGammaTexture();
m_gammaTextureView = this->createGammaTextureView(); m_gammaTextureView = CreateGammaTextureView();
// Set up context state. The shader bindings and the // Set up context state. The shader bindings and the
// constant state objects will never be modified. // constant state objects will never be modified.
@ -108,33 +108,33 @@ namespace dxvk {
m_context->bindShader( m_context->bindShader(
VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_VERTEX_BIT,
this->createVertexShader()); CreateVertexShader());
m_context->bindShader( m_context->bindShader(
VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_FRAGMENT_BIT,
this->createFragmentShader()); CreateFragmentShader());
m_hud = hud::Hud::createHud(m_device); m_hud = hud::Hud::createHud(m_device);
} }
DxgiPresenter::~DxgiPresenter() { DxgiVkPresenter::~DxgiVkPresenter() {
m_device->waitForIdle(); m_device->waitForIdle();
} }
void DxgiPresenter::initBackBuffer(const Rc<DxvkImage>& image) { void DxgiVkPresenter::InitBackBuffer(const Rc<DxvkImage>& Image) {
m_context->beginRecording( m_context->beginRecording(
m_device->createCommandList()); m_device->createCommandList());
VkImageSubresourceRange sr; VkImageSubresourceRange sr;
sr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; sr.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
sr.baseMipLevel = 0; sr.baseMipLevel = 0;
sr.levelCount = image->info().mipLevels; sr.levelCount = Image->info().mipLevels;
sr.baseArrayLayer = 0; sr.baseArrayLayer = 0;
sr.layerCount = image->info().numLayers; sr.layerCount = Image->info().numLayers;
m_context->initImage(image, sr); m_context->initImage(Image, sr);
m_device->submitCommandList( m_device->submitCommandList(
m_context->endRecording(), m_context->endRecording(),
@ -142,7 +142,7 @@ namespace dxvk {
} }
void DxgiPresenter::presentImage() { void DxgiVkPresenter::PresentImage() {
if (m_hud != nullptr) { if (m_hud != nullptr) {
m_hud->render({ m_hud->render({
m_options.preferredBufferSize.width, m_options.preferredBufferSize.width,
@ -222,22 +222,22 @@ namespace dxvk {
} }
void DxgiPresenter::updateBackBuffer(const Rc<DxvkImage>& image) { void DxgiVkPresenter::UpdateBackBuffer(const Rc<DxvkImage>& Image) {
// Explicitly destroy the old stuff // Explicitly destroy the old stuff
m_backBuffer = image; m_backBuffer = Image;
m_backBufferResolve = nullptr; m_backBufferResolve = nullptr;
m_backBufferView = nullptr; m_backBufferView = nullptr;
// If a multisampled back buffer was requested, we also need to // If a multisampled back buffer was requested, we also need to
// create a resolve image with otherwise identical properties. // create a resolve image with otherwise identical properties.
// Multisample images cannot be sampled from. // Multisample images cannot be sampled from.
if (image->info().sampleCount != VK_SAMPLE_COUNT_1_BIT) { if (Image->info().sampleCount != VK_SAMPLE_COUNT_1_BIT) {
DxvkImageCreateInfo resolveInfo; DxvkImageCreateInfo resolveInfo;
resolveInfo.type = VK_IMAGE_TYPE_2D; resolveInfo.type = VK_IMAGE_TYPE_2D;
resolveInfo.format = image->info().format; resolveInfo.format = Image->info().format;
resolveInfo.flags = 0; resolveInfo.flags = 0;
resolveInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT; resolveInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT;
resolveInfo.extent = image->info().extent; resolveInfo.extent = Image->info().extent;
resolveInfo.numLayers = 1; resolveInfo.numLayers = 1;
resolveInfo.mipLevels = 1; resolveInfo.mipLevels = 1;
resolveInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT resolveInfo.usage = VK_IMAGE_USAGE_SAMPLED_BIT
@ -257,7 +257,7 @@ namespace dxvk {
// image to be bound as a shader resource. // image to be bound as a shader resource.
DxvkImageViewCreateInfo viewInfo; DxvkImageViewCreateInfo viewInfo;
viewInfo.type = VK_IMAGE_VIEW_TYPE_2D; viewInfo.type = VK_IMAGE_VIEW_TYPE_2D;
viewInfo.format = image->info().format; viewInfo.format = Image->info().format;
viewInfo.aspect = VK_IMAGE_ASPECT_COLOR_BIT; viewInfo.aspect = VK_IMAGE_ASPECT_COLOR_BIT;
viewInfo.minLevel = 0; viewInfo.minLevel = 0;
viewInfo.numLevels = 1; viewInfo.numLevels = 1;
@ -270,41 +270,39 @@ namespace dxvk {
: m_backBuffer, : m_backBuffer,
viewInfo); viewInfo);
this->initBackBuffer(m_backBuffer); InitBackBuffer(m_backBuffer);
} }
void DxgiPresenter::recreateSwapchain(const DxvkSwapchainProperties& options) { void DxgiVkPresenter::RecreateSwapchain(const DxvkSwapchainProperties* pOptions) {
const bool doRecreate = const bool doRecreate =
options.preferredSurfaceFormat.format != m_options.preferredSurfaceFormat.format pOptions->preferredSurfaceFormat.format != m_options.preferredSurfaceFormat.format
|| options.preferredSurfaceFormat.colorSpace != m_options.preferredSurfaceFormat.colorSpace || pOptions->preferredSurfaceFormat.colorSpace != m_options.preferredSurfaceFormat.colorSpace
|| options.preferredPresentMode != m_options.preferredPresentMode || pOptions->preferredPresentMode != m_options.preferredPresentMode
|| options.preferredBufferSize.width != m_options.preferredBufferSize.width || pOptions->preferredBufferSize.width != m_options.preferredBufferSize.width
|| options.preferredBufferSize.height != m_options.preferredBufferSize.height; || pOptions->preferredBufferSize.height != m_options.preferredBufferSize.height;
if (doRecreate) { if (doRecreate) {
Logger::info(str::format( Logger::info(str::format(
"DxgiPresenter: Recreating swap chain: ", "DxgiVkPresenter: Recreating swap chain: ",
"\n Format: ", options.preferredSurfaceFormat.format, "\n Format: ", pOptions->preferredSurfaceFormat.format,
"\n Present mode: ", options.preferredPresentMode, "\n Present mode: ", pOptions->preferredPresentMode,
"\n Buffer size: ", options.preferredBufferSize.width, "x", options.preferredBufferSize.height)); "\n Buffer size: ", pOptions->preferredBufferSize.width, "x", pOptions->preferredBufferSize.height));
m_options = options; if (m_swapchain == nullptr)
m_swapchain = m_device->createSwapchain(m_surface, *pOptions);
else
m_swapchain->changeProperties(*pOptions);
if (m_swapchain == nullptr) { m_options = *pOptions;
m_swapchain = m_device->createSwapchain(
m_surface, options);
} else {
m_swapchain->changeProperties(options);
}
} }
} }
VkSurfaceFormatKHR DxgiPresenter::pickSurfaceFormat(DXGI_FORMAT fmt) const { VkSurfaceFormatKHR DxgiVkPresenter::PickSurfaceFormat(DXGI_FORMAT Fmt) const {
std::vector<VkSurfaceFormatKHR> formats; std::vector<VkSurfaceFormatKHR> formats;
switch (fmt) { switch (Fmt) {
case DXGI_FORMAT_R8G8B8A8_UNORM: case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM: { case DXGI_FORMAT_B8G8R8A8_UNORM: {
formats.push_back({ VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR }); formats.push_back({ VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR });
@ -327,7 +325,7 @@ namespace dxvk {
} break; } break;
default: default:
Logger::warn(str::format("DxgiPresenter: Unknown format: ", fmt)); Logger::warn(str::format("DxgiVkPresenter: Unknown format: ", Fmt));
} }
return m_surface->pickSurfaceFormat( return m_surface->pickSurfaceFormat(
@ -335,12 +333,12 @@ namespace dxvk {
} }
VkPresentModeKHR DxgiPresenter::pickPresentMode(VkPresentModeKHR preferred) const { VkPresentModeKHR DxgiVkPresenter::PickPresentMode(VkPresentModeKHR Preferred) const {
return m_surface->pickPresentMode(1, &preferred); return m_surface->pickPresentMode(1, &Preferred);
} }
void DxgiPresenter::setGammaControl( void DxgiVkPresenter::SetGammaControl(
const DXGI_VK_GAMMA_INPUT_CONTROL* pGammaControl, const DXGI_VK_GAMMA_INPUT_CONTROL* pGammaControl,
const DXGI_VK_GAMMA_CURVE* pGammaCurve) { const DXGI_VK_GAMMA_CURVE* pGammaCurve) {
m_context->beginRecording( m_context->beginRecording(
@ -362,21 +360,21 @@ namespace dxvk {
} }
Rc<DxvkSampler> DxgiPresenter::createSampler( Rc<DxvkSampler> DxgiVkPresenter::CreateSampler(
VkFilter filter, VkFilter Filter,
VkSamplerAddressMode addressMode) { VkSamplerAddressMode AddressMode) {
DxvkSamplerCreateInfo samplerInfo; DxvkSamplerCreateInfo samplerInfo;
samplerInfo.magFilter = filter; samplerInfo.magFilter = Filter;
samplerInfo.minFilter = filter; samplerInfo.minFilter = Filter;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
samplerInfo.mipmapLodBias = 0.0f; samplerInfo.mipmapLodBias = 0.0f;
samplerInfo.mipmapLodMin = 0.0f; samplerInfo.mipmapLodMin = 0.0f;
samplerInfo.mipmapLodMax = 0.0f; samplerInfo.mipmapLodMax = 0.0f;
samplerInfo.useAnisotropy = VK_FALSE; samplerInfo.useAnisotropy = VK_FALSE;
samplerInfo.maxAnisotropy = 1.0f; samplerInfo.maxAnisotropy = 1.0f;
samplerInfo.addressModeU = addressMode; samplerInfo.addressModeU = AddressMode;
samplerInfo.addressModeV = addressMode; samplerInfo.addressModeV = AddressMode;
samplerInfo.addressModeW = addressMode; samplerInfo.addressModeW = AddressMode;
samplerInfo.compareToDepth = VK_FALSE; samplerInfo.compareToDepth = VK_FALSE;
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
@ -385,7 +383,7 @@ namespace dxvk {
} }
Rc<DxvkBuffer> DxgiPresenter::createGammaUbo() { Rc<DxvkBuffer> DxgiVkPresenter::CreateGammaUbo() {
DxvkBufferCreateInfo info; DxvkBufferCreateInfo info;
info.size = sizeof(DXGI_VK_GAMMA_INPUT_CONTROL); info.size = sizeof(DXGI_VK_GAMMA_INPUT_CONTROL);
info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT
@ -398,7 +396,7 @@ namespace dxvk {
} }
Rc<DxvkImage> DxgiPresenter::createGammaTexture() { Rc<DxvkImage> DxgiVkPresenter::CreateGammaTexture() {
DxvkImageCreateInfo info; DxvkImageCreateInfo info;
info.type = VK_IMAGE_TYPE_1D; info.type = VK_IMAGE_TYPE_1D;
info.format = VK_FORMAT_R16G16B16A16_UNORM; info.format = VK_FORMAT_R16G16B16A16_UNORM;
@ -419,7 +417,7 @@ namespace dxvk {
} }
Rc<DxvkImageView> DxgiPresenter::createGammaTextureView() { Rc<DxvkImageView> DxgiVkPresenter::CreateGammaTextureView() {
DxvkImageViewCreateInfo info; DxvkImageViewCreateInfo info;
info.type = VK_IMAGE_VIEW_TYPE_1D; info.type = VK_IMAGE_VIEW_TYPE_1D;
info.format = VK_FORMAT_R16G16B16A16_UNORM; info.format = VK_FORMAT_R16G16B16A16_UNORM;
@ -432,7 +430,7 @@ namespace dxvk {
} }
Rc<DxvkShader> DxgiPresenter::createVertexShader() { Rc<DxvkShader> DxgiVkPresenter::CreateVertexShader() {
const SpirvCodeBuffer codeBuffer(dxgi_presenter_vert); const SpirvCodeBuffer codeBuffer(dxgi_presenter_vert);
return m_device->createShader( return m_device->createShader(
@ -442,7 +440,7 @@ namespace dxvk {
} }
Rc<DxvkShader> DxgiPresenter::createFragmentShader() { Rc<DxvkShader> DxgiVkPresenter::CreateFragmentShader() {
const SpirvCodeBuffer codeBuffer(dxgi_presenter_frag); const SpirvCodeBuffer codeBuffer(dxgi_presenter_frag);
// Shader resource slots // Shader resource slots

View File

@ -84,27 +84,26 @@ namespace dxvk {
* \ref DxgiSwapChain to the Vulkan * \ref DxgiSwapChain to the Vulkan
* swap chain. * swap chain.
*/ */
class DxgiPresenter : public RcObject { class DxgiVkPresenter : public RcObject {
public: public:
DxgiPresenter( DxgiVkPresenter(
const Rc<DxvkDevice>& device, const Rc<DxvkDevice>& device,
HWND window); HWND window);
~DxgiPresenter(); ~DxgiVkPresenter();
/** /**
* \brief Initializes back buffer image * \brief Initializes back buffer image
* \param [in] image Back buffer image * \param [in] image Back buffer image
*/ */
void initBackBuffer( void InitBackBuffer(const Rc<DxvkImage>& Image);
const Rc<DxvkImage>& image);
/** /**
* \brief Renders back buffer to the screen * \brief Renders back buffer to the screen
*/ */
void presentImage(); void PresentImage();
/** /**
* \brief Sets new back buffer * \brief Sets new back buffer
@ -113,8 +112,7 @@ namespace dxvk {
* the back buffer image was replaced. * the back buffer image was replaced.
* \param [in] image Back buffer image * \param [in] image Back buffer image
*/ */
void updateBackBuffer( void UpdateBackBuffer(const Rc<DxvkImage>& Image);
const Rc<DxvkImage>& image);
/** /**
* \brief Recreats Vulkan swap chain * \brief Recreats Vulkan swap chain
@ -124,8 +122,8 @@ namespace dxvk {
* properties have changed, this is a no-op. * properties have changed, this is a no-op.
* \param [in] options New swap chain options * \param [in] options New swap chain options
*/ */
void recreateSwapchain( void RecreateSwapchain(
const DxvkSwapchainProperties& options); const DxvkSwapchainProperties* pOptions);
/** /**
* \brief Picks a surface format based on a DXGI format * \brief Picks a surface format based on a DXGI format
@ -135,7 +133,7 @@ namespace dxvk {
* \param [in] fmt The DXGI format * \param [in] fmt The DXGI format
* \returns The Vulkan format * \returns The Vulkan format
*/ */
VkSurfaceFormatKHR pickSurfaceFormat(DXGI_FORMAT fmt) const; VkSurfaceFormatKHR PickSurfaceFormat(DXGI_FORMAT Fmt) const;
/** /**
* \brief Picks a supported present mode * \brief Picks a supported present mode
@ -143,7 +141,7 @@ namespace dxvk {
* \param [in] preferred Preferred present mode * \param [in] preferred Preferred present mode
* \returns An actually supported present mode * \returns An actually supported present mode
*/ */
VkPresentModeKHR pickPresentMode(VkPresentModeKHR preferred) const; VkPresentModeKHR PickPresentMode(VkPresentModeKHR Preferred) const;
/** /**
* \brief Sets gamma curve * \brief Sets gamma curve
@ -152,7 +150,7 @@ namespace dxvk {
* \param [in] pGammaControl Input parameters * \param [in] pGammaControl Input parameters
* \param [in] pGammaCurve Gamma curve * \param [in] pGammaCurve Gamma curve
*/ */
void setGammaControl( void SetGammaControl(
const DXGI_VK_GAMMA_INPUT_CONTROL* pGammaControl, const DXGI_VK_GAMMA_INPUT_CONTROL* pGammaControl,
const DXGI_VK_GAMMA_CURVE* pGammaCurve); const DXGI_VK_GAMMA_CURVE* pGammaCurve);
@ -189,16 +187,16 @@ namespace dxvk {
DxvkBlendMode m_blendMode; DxvkBlendMode m_blendMode;
DxvkSwapchainProperties m_options; DxvkSwapchainProperties m_options;
Rc<DxvkSampler> createSampler( Rc<DxvkSampler> CreateSampler(
VkFilter filter, VkFilter Filter,
VkSamplerAddressMode addressMode); VkSamplerAddressMode AddressMode);
Rc<DxvkBuffer> createGammaUbo(); Rc<DxvkBuffer> CreateGammaUbo();
Rc<DxvkImage> createGammaTexture(); Rc<DxvkImage> CreateGammaTexture();
Rc<DxvkImageView> createGammaTextureView(); Rc<DxvkImageView> CreateGammaTextureView();
Rc<DxvkShader> createVertexShader(); Rc<DxvkShader> CreateVertexShader();
Rc<DxvkShader> createFragmentShader(); Rc<DxvkShader> CreateFragmentShader();
}; };

View File

@ -199,14 +199,14 @@ namespace dxvk {
// Vulkan swap chain itself remains valid. // Vulkan swap chain itself remains valid.
DxvkSwapchainProperties swapchainProps; DxvkSwapchainProperties swapchainProps;
swapchainProps.preferredSurfaceFormat swapchainProps.preferredSurfaceFormat
= m_presenter->pickSurfaceFormat(m_desc.BufferDesc.Format); = m_presenter->PickSurfaceFormat(m_desc.BufferDesc.Format);
swapchainProps.preferredPresentMode = SyncInterval == 0 swapchainProps.preferredPresentMode = SyncInterval == 0
? m_presenter->pickPresentMode(VK_PRESENT_MODE_IMMEDIATE_KHR) ? m_presenter->PickPresentMode(VK_PRESENT_MODE_IMMEDIATE_KHR)
: m_presenter->pickPresentMode(VK_PRESENT_MODE_FIFO_KHR); : m_presenter->PickPresentMode(VK_PRESENT_MODE_FIFO_KHR);
swapchainProps.preferredBufferSize = GetWindowSize(); swapchainProps.preferredBufferSize = GetWindowSize();
m_presenter->recreateSwapchain(swapchainProps); m_presenter->RecreateSwapchain(&swapchainProps);
m_presenter->presentImage(); m_presenter->PresentImage();
return S_OK; return S_OK;
} catch (const DxvkError& err) { } catch (const DxvkError& err) {
Logger::err(err.message()); Logger::err(err.message());
@ -301,7 +301,7 @@ namespace dxvk {
curve.ControlPoints[i].A = 0; curve.ControlPoints[i].A = 0;
} }
m_presenter->setGammaControl(&control, &curve); m_presenter->SetGammaControl(&control, &curve);
return S_OK; return S_OK;
} }
@ -321,14 +321,14 @@ namespace dxvk {
curve.ControlPoints[i] = { value, value, value, 0 }; curve.ControlPoints[i] = { value, value, value, 0 };
} }
m_presenter->setGammaControl(&control, &curve); m_presenter->SetGammaControl(&control, &curve);
return S_OK; return S_OK;
} }
HRESULT DxgiSwapChain::CreatePresenter() { HRESULT DxgiSwapChain::CreatePresenter() {
try { try {
m_presenter = new DxgiPresenter( m_presenter = new DxgiVkPresenter(
m_device->GetDXVKDevice(), m_device->GetDXVKDevice(),
m_desc.OutputWindow); m_desc.OutputWindow);
return S_OK; return S_OK;
@ -357,7 +357,7 @@ namespace dxvk {
} }
try { try {
m_presenter->updateBackBuffer(m_backBuffer->GetDXVKImage()); m_presenter->UpdateBackBuffer(m_backBuffer->GetDXVKImage());
return S_OK; return S_OK;
} catch (const DxvkError& e) { } catch (const DxvkError& e) {
Logger::err(e.message()); Logger::err(e.message());

View File

@ -104,7 +104,7 @@ namespace dxvk {
DXGI_SWAP_CHAIN_DESC m_desc; DXGI_SWAP_CHAIN_DESC m_desc;
DXGI_FRAME_STATISTICS m_stats; DXGI_FRAME_STATISTICS m_stats;
Rc<DxgiPresenter> m_presenter; Rc<DxgiVkPresenter> m_presenter;
Com<IDXGIVkBackBuffer> m_backBuffer; Com<IDXGIVkBackBuffer> m_backBuffer;
HMONITOR m_monitor; HMONITOR m_monitor;