diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 57e4b070f..f6064406b 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -1,5 +1,3 @@ -#include - #include "dxgi_factory.h" #include "dxgi_swapchain.h" @@ -40,6 +38,33 @@ namespace dxvk { if (FAILED(this->SetFullscreenState(!pDesc->Windowed, nullptr))) throw DxvkError("DxgiSwapChain::DxgiSwapChain: Failed to set initial fullscreen state"); + + // Create swap chain + Rc dxvkDevice = m_device->GetDXVKDevice(); + Rc dxvkAdapter = dxvkDevice->adapter(); + + m_context = dxvkDevice->createContext(); + m_commandList = dxvkDevice->createCommandList(); + + m_acquireSync = dxvkDevice->createSemaphore(); + m_presentSync = dxvkDevice->createSemaphore(); + + HINSTANCE instance = reinterpret_cast( + GetWindowLongPtr(m_desc.OutputWindow, GWLP_HINSTANCE)); + + m_surface = dxvkAdapter->createSurface( + instance, m_desc.OutputWindow); + + DxvkSwapchainProperties swapchainProperties; + swapchainProperties.preferredSurfaceFormat.format = VK_FORMAT_B8G8R8A8_SNORM; + swapchainProperties.preferredSurfaceFormat.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; + swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_FIFO_KHR; + swapchainProperties.preferredBufferSize.width = m_desc.BufferDesc.Width; + swapchainProperties.preferredBufferSize.height = m_desc.BufferDesc.Height; + + m_swapchain = dxvkDevice->createSwapchain( + m_surface, swapchainProperties); + } @@ -73,6 +98,11 @@ namespace dxvk { HRESULT DxgiSwapChain::GetBuffer(UINT Buffer, REFIID riid, void** ppSurface) { std::lock_guard lock(m_mutex); + if (Buffer > 0) { + Logger::err("DxgiSwapChain::GetBuffer: Buffer > 0 not supported"); + return DXGI_ERROR_INVALID_CALL; + } + Logger::err("DxgiSwapChain::GetBuffer: Not implemented"); return E_NOTIMPL; } @@ -152,8 +182,47 @@ namespace dxvk { HRESULT DxgiSwapChain::Present(UINT SyncInterval, UINT Flags) { std::lock_guard lock(m_mutex); - Logger::err("DxgiSwapChain::Present: Not implemented"); - return E_NOTIMPL; + // TODO implement sync interval + // TODO implement flags + + auto dxvkDevice = m_device->GetDXVKDevice(); + + auto framebuffer = m_swapchain->getFramebuffer(m_acquireSync); + auto framebufferSize = framebuffer->size(); + + m_context->beginRecording(m_commandList); + m_context->bindFramebuffer(framebuffer); + + // TODO render back buffer into the swap image, + // the clear operation is only a placeholder. + VkClearAttachment clearAttachment; + clearAttachment.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + clearAttachment.colorAttachment = 0; + clearAttachment.clearValue.color.float32[0] = 1.0f; + clearAttachment.clearValue.color.float32[1] = 1.0f; + clearAttachment.clearValue.color.float32[2] = 1.0f; + clearAttachment.clearValue.color.float32[3] = 1.0f; + + VkClearRect clearArea; + clearArea.rect = VkRect2D { { 0, 0 }, framebufferSize.width, framebufferSize.height }; + clearArea.baseArrayLayer = 0; + clearArea.layerCount = framebufferSize.layers; + + m_context->clearRenderTarget( + clearAttachment, + clearArea); + + m_context->endRecording(); + + dxvkDevice->submitCommandList(m_commandList, + m_acquireSync, m_presentSync); + + m_swapchain->present( m_presentSync); + + // FIXME Make sure that the semaphores and the command + // list can be safely used without stalling the device. + dxvkDevice->waitForIdle(); + return S_OK; } @@ -165,8 +234,19 @@ namespace dxvk { UINT SwapChainFlags) { std::lock_guard lock(m_mutex); - Logger::err("DxgiSwapChain::ResizeBuffers: Not implemented"); - return E_NOTIMPL; + m_desc.BufferDesc.Width = Width; + m_desc.BufferDesc.Height = Height; + m_desc.BufferDesc.Format = NewFormat; + m_desc.BufferCount = BufferCount; + m_desc.Flags = SwapChainFlags; + + try { + // TODO implement + return S_OK; + } catch (const DxvkError& err) { + Logger::err(err.message()); + return DXGI_ERROR_DRIVER_INTERNAL_ERROR; + } } @@ -175,7 +255,6 @@ namespace dxvk { return DXGI_ERROR_INVALID_CALL; std::lock_guard lock(m_mutex); - m_desc.BufferDesc = *pNewTargetParameters; // Applies to windowed mode SDL_SetWindowSize(m_window, diff --git a/src/dxgi/dxgi_swapchain.h b/src/dxgi/dxgi_swapchain.h index 0e2408652..35401f6eb 100644 --- a/src/dxgi/dxgi_swapchain.h +++ b/src/dxgi/dxgi_swapchain.h @@ -3,6 +3,9 @@ #include #include +#include +#include + #include "dxgi_interfaces.h" #include "dxgi_object.h" @@ -83,6 +86,14 @@ namespace dxvk { SDL_Window* m_window = nullptr; + Rc m_context; + Rc m_commandList; + Rc m_surface; + Rc m_swapchain; + + Rc m_acquireSync; + Rc m_presentSync; + }; } diff --git a/tests/d3d11/test_d3d11_triangle.cpp b/tests/d3d11/test_d3d11_triangle.cpp index 4ebed1c39..122bab5f4 100644 --- a/tests/d3d11/test_d3d11_triangle.cpp +++ b/tests/d3d11/test_d3d11_triangle.cpp @@ -55,7 +55,7 @@ public: } void run() { - + m_swapChain->Present(0, 0); } private: