diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index af54c1a4a..8742d0a63 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -2,9 +2,12 @@ #include #include "dxgi_adapter.h" +#include "dxgi_enums.h" #include "dxgi_factory.h" #include "dxgi_output.h" +#include "../dxvk/vulkan/dxvk_vulkan_names.h" + namespace dxvk { DxgiAdapter::DxgiAdapter( @@ -12,7 +15,7 @@ namespace dxvk { const Rc& adapter) : m_factory (factory), m_adapter (adapter) { - + SetupFormatTable(); } @@ -134,4 +137,127 @@ namespace dxvk { return m_adapter; } + + DxgiFormatPair DxgiAdapter::LookupFormat(DXGI_FORMAT format) { + auto pair = m_formats.find(format); + + return pair != m_formats.end() + ? pair->second + : DxgiFormatPair(); + } + + + void DxgiAdapter::AddFormat( + DXGI_FORMAT srcFormat, + VkFormat dstFormat, + const std::initializer_list& fallbacks, + VkFormatFeatureFlags features) { + DxgiFormatPair formatPair; + formatPair.wanted = dstFormat; + formatPair.actual = VK_FORMAT_UNDEFINED; + + if (this->HasFormatSupport(dstFormat, features)) { + formatPair.actual = dstFormat; + } else { + for (VkFormat fmt : fallbacks) { + if (this->HasFormatSupport(fmt, features)) { + formatPair.actual = fmt; + break; + } + } + } + + if (formatPair.actual == VK_FORMAT_UNDEFINED) + Logger::err(str::format("DxgiAdapter: ", srcFormat, " not supported")); + else if (formatPair.actual != formatPair.wanted) + Logger::warn(str::format("DxgiAdapter: ", srcFormat, " -> ", formatPair.actual)); + + m_formats.insert(std::make_pair(srcFormat, formatPair)); + } + + + void DxgiAdapter::SetupFormatTable() { + AddFormat( + DXGI_FORMAT_R8G8B8A8_TYPELESS, + VK_FORMAT_R8G8B8A8_UINT, {}, 0); + + AddFormat( + DXGI_FORMAT_R8G8B8A8_UINT, + VK_FORMAT_R8G8B8A8_UINT, {}, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + AddFormat( + DXGI_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R8G8B8A8_UNORM, {}, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT); + + AddFormat( + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, + VK_FORMAT_R8G8B8A8_SRGB, {}, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT); + + AddFormat( + DXGI_FORMAT_R8G8B8A8_SINT, + VK_FORMAT_R8G8B8A8_SINT, {}, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); + + AddFormat( + DXGI_FORMAT_R8G8B8A8_SNORM, + VK_FORMAT_R8G8B8A8_SNORM, {}, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT | + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT | + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT); + + AddFormat( + DXGI_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, { + VK_FORMAT_D32_SFLOAT_S8_UINT, + }, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + + AddFormat( + DXGI_FORMAT_D16_UNORM, + VK_FORMAT_D16_UNORM, {}, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + + // TODO finish me + } + + + bool DxgiAdapter::HasFormatSupport( + VkFormat format, + VkFormatFeatureFlags features) const { + VkFormatProperties info = m_adapter->formatProperties(format); + return ((info.optimalTilingFeatures | info.bufferFeatures) & features) == features; + } + } diff --git a/src/dxgi/dxgi_adapter.h b/src/dxgi/dxgi_adapter.h index 65818d279..ea69cf968 100644 --- a/src/dxgi/dxgi_adapter.h +++ b/src/dxgi/dxgi_adapter.h @@ -1,6 +1,8 @@ #pragma once +#include #include +#include #include #include @@ -46,11 +48,28 @@ namespace dxvk { Rc GetDXVKAdapter() final; + DxgiFormatPair LookupFormat( + DXGI_FORMAT format) final; + private: Com m_factory; Rc m_adapter; + std::unordered_map m_formats; + + void AddFormat( + DXGI_FORMAT srcFormat, + VkFormat dstFormat, + const std::initializer_list& fallbacks, + VkFormatFeatureFlags features); + + void SetupFormatTable(); + + bool HasFormatSupport( + VkFormat format, + VkFormatFeatureFlags features) const; + }; } diff --git a/src/dxgi/dxgi_enums.cpp b/src/dxgi/dxgi_enums.cpp new file mode 100644 index 000000000..5d9e75d11 --- /dev/null +++ b/src/dxgi/dxgi_enums.cpp @@ -0,0 +1,123 @@ +#include "dxgi_enums.h" + +std::ostream& operator << (std::ostream& os, DXGI_FORMAT e) { + switch (e) { + ENUM_NAME(DXGI_FORMAT_UNKNOWN); + ENUM_NAME(DXGI_FORMAT_R32G32B32A32_TYPELESS); + ENUM_NAME(DXGI_FORMAT_R32G32B32A32_FLOAT); + ENUM_NAME(DXGI_FORMAT_R32G32B32A32_UINT); + ENUM_NAME(DXGI_FORMAT_R32G32B32A32_SINT); + ENUM_NAME(DXGI_FORMAT_R32G32B32_TYPELESS); + ENUM_NAME(DXGI_FORMAT_R32G32B32_FLOAT); + ENUM_NAME(DXGI_FORMAT_R32G32B32_UINT); + ENUM_NAME(DXGI_FORMAT_R32G32B32_SINT); + ENUM_NAME(DXGI_FORMAT_R16G16B16A16_TYPELESS); + ENUM_NAME(DXGI_FORMAT_R16G16B16A16_FLOAT); + ENUM_NAME(DXGI_FORMAT_R16G16B16A16_UNORM); + ENUM_NAME(DXGI_FORMAT_R16G16B16A16_UINT); + ENUM_NAME(DXGI_FORMAT_R16G16B16A16_SNORM); + ENUM_NAME(DXGI_FORMAT_R16G16B16A16_SINT); + ENUM_NAME(DXGI_FORMAT_R32G32_TYPELESS); + ENUM_NAME(DXGI_FORMAT_R32G32_FLOAT); + ENUM_NAME(DXGI_FORMAT_R32G32_UINT); + ENUM_NAME(DXGI_FORMAT_R32G32_SINT); + ENUM_NAME(DXGI_FORMAT_R32G8X24_TYPELESS); + ENUM_NAME(DXGI_FORMAT_D32_FLOAT_S8X24_UINT); + ENUM_NAME(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS); + ENUM_NAME(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT); + ENUM_NAME(DXGI_FORMAT_R10G10B10A2_TYPELESS); + ENUM_NAME(DXGI_FORMAT_R10G10B10A2_UNORM); + ENUM_NAME(DXGI_FORMAT_R10G10B10A2_UINT); + ENUM_NAME(DXGI_FORMAT_R11G11B10_FLOAT); + ENUM_NAME(DXGI_FORMAT_R8G8B8A8_TYPELESS); + ENUM_NAME(DXGI_FORMAT_R8G8B8A8_UNORM); + ENUM_NAME(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); + ENUM_NAME(DXGI_FORMAT_R8G8B8A8_UINT); + ENUM_NAME(DXGI_FORMAT_R8G8B8A8_SNORM); + ENUM_NAME(DXGI_FORMAT_R8G8B8A8_SINT); + ENUM_NAME(DXGI_FORMAT_R16G16_TYPELESS); + ENUM_NAME(DXGI_FORMAT_R16G16_FLOAT); + ENUM_NAME(DXGI_FORMAT_R16G16_UNORM); + ENUM_NAME(DXGI_FORMAT_R16G16_UINT); + ENUM_NAME(DXGI_FORMAT_R16G16_SNORM); + ENUM_NAME(DXGI_FORMAT_R16G16_SINT); + ENUM_NAME(DXGI_FORMAT_R32_TYPELESS); + ENUM_NAME(DXGI_FORMAT_D32_FLOAT); + ENUM_NAME(DXGI_FORMAT_R32_FLOAT); + ENUM_NAME(DXGI_FORMAT_R32_UINT); + ENUM_NAME(DXGI_FORMAT_R32_SINT); + ENUM_NAME(DXGI_FORMAT_R24G8_TYPELESS); + ENUM_NAME(DXGI_FORMAT_D24_UNORM_S8_UINT); + ENUM_NAME(DXGI_FORMAT_R24_UNORM_X8_TYPELESS); + ENUM_NAME(DXGI_FORMAT_X24_TYPELESS_G8_UINT); + ENUM_NAME(DXGI_FORMAT_R8G8_TYPELESS); + ENUM_NAME(DXGI_FORMAT_R8G8_UNORM); + ENUM_NAME(DXGI_FORMAT_R8G8_UINT); + ENUM_NAME(DXGI_FORMAT_R8G8_SNORM); + ENUM_NAME(DXGI_FORMAT_R8G8_SINT); + ENUM_NAME(DXGI_FORMAT_R16_TYPELESS); + ENUM_NAME(DXGI_FORMAT_R16_FLOAT); + ENUM_NAME(DXGI_FORMAT_D16_UNORM); + ENUM_NAME(DXGI_FORMAT_R16_UNORM); + ENUM_NAME(DXGI_FORMAT_R16_UINT); + ENUM_NAME(DXGI_FORMAT_R16_SNORM); + ENUM_NAME(DXGI_FORMAT_R16_SINT); + ENUM_NAME(DXGI_FORMAT_R8_TYPELESS); + ENUM_NAME(DXGI_FORMAT_R8_UNORM); + ENUM_NAME(DXGI_FORMAT_R8_UINT); + ENUM_NAME(DXGI_FORMAT_R8_SNORM); + ENUM_NAME(DXGI_FORMAT_R8_SINT); + ENUM_NAME(DXGI_FORMAT_A8_UNORM); + ENUM_NAME(DXGI_FORMAT_R1_UNORM); + ENUM_NAME(DXGI_FORMAT_R9G9B9E5_SHAREDEXP); + ENUM_NAME(DXGI_FORMAT_R8G8_B8G8_UNORM); + ENUM_NAME(DXGI_FORMAT_G8R8_G8B8_UNORM); + ENUM_NAME(DXGI_FORMAT_BC1_TYPELESS); + ENUM_NAME(DXGI_FORMAT_BC1_UNORM); + ENUM_NAME(DXGI_FORMAT_BC1_UNORM_SRGB); + ENUM_NAME(DXGI_FORMAT_BC2_TYPELESS); + ENUM_NAME(DXGI_FORMAT_BC2_UNORM); + ENUM_NAME(DXGI_FORMAT_BC2_UNORM_SRGB); + ENUM_NAME(DXGI_FORMAT_BC3_TYPELESS); + ENUM_NAME(DXGI_FORMAT_BC3_UNORM); + ENUM_NAME(DXGI_FORMAT_BC3_UNORM_SRGB); + ENUM_NAME(DXGI_FORMAT_BC4_TYPELESS); + ENUM_NAME(DXGI_FORMAT_BC4_UNORM); + ENUM_NAME(DXGI_FORMAT_BC4_SNORM); + ENUM_NAME(DXGI_FORMAT_BC5_TYPELESS); + ENUM_NAME(DXGI_FORMAT_BC5_UNORM); + ENUM_NAME(DXGI_FORMAT_BC5_SNORM); + ENUM_NAME(DXGI_FORMAT_B5G6R5_UNORM); + ENUM_NAME(DXGI_FORMAT_B5G5R5A1_UNORM); + ENUM_NAME(DXGI_FORMAT_B8G8R8A8_UNORM); + ENUM_NAME(DXGI_FORMAT_B8G8R8X8_UNORM); + ENUM_NAME(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM); + ENUM_NAME(DXGI_FORMAT_B8G8R8A8_TYPELESS); + ENUM_NAME(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB); + ENUM_NAME(DXGI_FORMAT_B8G8R8X8_TYPELESS); + ENUM_NAME(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB); + ENUM_NAME(DXGI_FORMAT_BC6H_TYPELESS); + ENUM_NAME(DXGI_FORMAT_BC6H_UF16); + ENUM_NAME(DXGI_FORMAT_BC6H_SF16); + ENUM_NAME(DXGI_FORMAT_BC7_TYPELESS); + ENUM_NAME(DXGI_FORMAT_BC7_UNORM); + ENUM_NAME(DXGI_FORMAT_BC7_UNORM_SRGB); + ENUM_NAME(DXGI_FORMAT_AYUV); + ENUM_NAME(DXGI_FORMAT_Y410); + ENUM_NAME(DXGI_FORMAT_Y416); + ENUM_NAME(DXGI_FORMAT_NV12); + ENUM_NAME(DXGI_FORMAT_P010); + ENUM_NAME(DXGI_FORMAT_P016); + ENUM_NAME(DXGI_FORMAT_420_OPAQUE); + ENUM_NAME(DXGI_FORMAT_YUY2); + ENUM_NAME(DXGI_FORMAT_Y210); + ENUM_NAME(DXGI_FORMAT_Y216); + ENUM_NAME(DXGI_FORMAT_NV11); + ENUM_NAME(DXGI_FORMAT_AI44); + ENUM_NAME(DXGI_FORMAT_IA44); + ENUM_NAME(DXGI_FORMAT_P8); + ENUM_NAME(DXGI_FORMAT_A8P8); + ENUM_NAME(DXGI_FORMAT_B4G4R4A4_UNORM); + ENUM_DEFAULT(e); + } +} \ No newline at end of file diff --git a/src/dxgi/dxgi_enums.h b/src/dxgi/dxgi_enums.h new file mode 100644 index 000000000..2a48427eb --- /dev/null +++ b/src/dxgi/dxgi_enums.h @@ -0,0 +1,5 @@ +#pragma once + +#include "dxgi_include.h" + +std::ostream& operator << (std::ostream& os, DXGI_FORMAT e); diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index 136d7a5bd..b8efece1c 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -1,5 +1,7 @@ #pragma once +#include "../dxvk/dxvk_include.h" + #include "dxgi_include.h" namespace dxvk { @@ -8,6 +10,20 @@ namespace dxvk { class DxvkBuffer; class DxvkDevice; class DxvkImage; + + /** + * \brief Format pair + * + * For a DXGI format, this stores two Vulkan formats: + * The format that directly corresponds to the DXGI + * format, and a similar format that the device can + * use. If the device supports the desired format, + * both formats will be equal. + */ + struct DxgiFormatPair { + VkFormat wanted = VK_FORMAT_UNDEFINED; + VkFormat actual = VK_FORMAT_UNDEFINED; + }; } /** @@ -22,6 +38,9 @@ IDXGIAdapterPrivate : public IDXGIAdapter1 { static const GUID guid; virtual dxvk::Rc GetDXVKAdapter() = 0; + + virtual dxvk::DxgiFormatPair LookupFormat( + DXGI_FORMAT format) = 0; }; diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index bcf200b99..207f68215 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -14,18 +14,20 @@ namespace dxvk { // Retrieve a device pointer that allows us to // communicate with the underlying D3D device if (FAILED(pDevice->QueryInterface(__uuidof(IDXGIPresentDevicePrivate), - reinterpret_cast(&m_device)))) + reinterpret_cast(&m_presentDevice)))) throw DxvkError("DxgiSwapChain::DxgiSwapChain: Invalid device"); // Retrieve the adapter, which is going // to be used to enumerate displays. - Com device; + Com adapter; - if (FAILED(pDevice->QueryInterface(__uuidof(IDXGIDevice), - reinterpret_cast(&device)))) + if (FAILED(pDevice->QueryInterface(__uuidof(IDXGIDevicePrivate), + reinterpret_cast(&m_device)))) throw DxvkError("DxgiSwapChain::DxgiSwapChain: Invalid device"); - if (FAILED(device->GetAdapter(&m_adapter))) + if (FAILED(m_device->GetAdapter(&adapter)) + || FAILED(adapter->QueryInterface(__uuidof(IDXGIAdapterPrivate), + reinterpret_cast(&m_adapter)))) throw DxvkError("DxgiSwapChain::DxgiSwapChain: Failed to retrieve adapter"); // Initialize frame statistics @@ -161,16 +163,10 @@ namespace dxvk { HRESULT DxgiSwapChain::Present(UINT SyncInterval, UINT Flags) { std::lock_guard lock(m_mutex); - // Query DXGI device to retrieve DXVK device - Com dxgiDevice; - - m_device->GetDevice(__uuidof(IDXGIDevicePrivate), - reinterpret_cast(&dxgiDevice)); - try { // Submit pending rendering commands // before recording the present code. - m_device->FlushRenderingCommands(); + m_presentDevice->FlushRenderingCommands(); // TODO implement sync interval // TODO implement flags @@ -289,12 +285,8 @@ namespace dxvk { void DxgiSwapChain::createPresenter() { - Com dxgiDevice; - m_device->GetDevice(__uuidof(IDXGIDevicePrivate), - reinterpret_cast(&dxgiDevice)); - m_presenter = new DxgiPresenter( - dxgiDevice->GetDXVKDevice(), + m_device->GetDXVKDevice(), m_desc.OutputWindow, m_desc.BufferDesc.Width, m_desc.BufferDesc.Height); @@ -302,13 +294,12 @@ namespace dxvk { void DxgiSwapChain::createBackBuffer() { - // TODO select format based on DXGI format - // TODO support proper multi-sampling - Com dxgiDevice; - m_device->GetDevice(__uuidof(IDXGIDevicePrivate), - reinterpret_cast(&dxgiDevice)); + // Pick the back buffer format based on the requested swap chain format + DxgiFormatPair bufferFormat = m_adapter->LookupFormat(m_desc.BufferDesc.Format); + Logger::info(str::format("DxgiSwapChain: Creating back buffer with ", bufferFormat.actual)); - const Rc dxvkDevice = dxgiDevice->GetDXVKDevice(); + // TODO support proper multi-sampling + const Rc dxvkDevice = m_device->GetDXVKDevice(); // Create an image that can be rendered to // and that can be used as a sampled texture. @@ -316,7 +307,7 @@ namespace dxvk { DxvkImageCreateInfo imageInfo; imageInfo.type = VK_IMAGE_TYPE_2D; - imageInfo.format = VK_FORMAT_R8G8B8A8_SRGB; + imageInfo.format = bufferFormat.actual; imageInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT; imageInfo.extent.width = m_desc.BufferDesc.Width; imageInfo.extent.height = m_desc.BufferDesc.Height; @@ -348,7 +339,7 @@ namespace dxvk { | VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT; } - if (FAILED(DXGICreateImageResourcePrivate(dxgiDevice.ptr(), &imageInfo, + if (FAILED(DXGICreateImageResourcePrivate(m_device.ptr(), &imageInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, DXGI_USAGE_BACK_BUFFER | m_desc.BufferUsage, &resource))) throw DxvkError("DxgiSwapChain::createBackBuffer: Failed to create back buffer"); @@ -370,7 +361,7 @@ namespace dxvk { // Wrap the back buffer image into an interface // that the device can use to access the image. - if (FAILED(m_device->WrapSwapChainBackBuffer(resource.ptr(), &m_desc, &m_backBufferIface))) + if (FAILED(m_presentDevice->WrapSwapChainBackBuffer(resource.ptr(), &m_desc, &m_backBufferIface))) throw DxvkError("DxgiSwapChain::createBackBuffer: Failed to create back buffer interface"); // Initialize the image properly so that diff --git a/src/dxgi/dxgi_swapchain.h b/src/dxgi/dxgi_swapchain.h index 3b7e3bf1d..673c87764 100644 --- a/src/dxgi/dxgi_swapchain.h +++ b/src/dxgi/dxgi_swapchain.h @@ -84,8 +84,9 @@ namespace dxvk { std::mutex m_mutex; Com m_factory; - Com m_adapter; - Com m_device; + Com m_adapter; + Com m_device; + Com m_presentDevice; DXGI_SWAP_CHAIN_DESC m_desc; DXGI_FRAME_STATISTICS m_stats; diff --git a/src/dxgi/meson.build b/src/dxgi/meson.build index bc8883bb6..4d4b4d0fa 100644 --- a/src/dxgi/meson.build +++ b/src/dxgi/meson.build @@ -1,6 +1,7 @@ dxgi_src = [ 'dxgi_adapter.cpp', 'dxgi_device.cpp', + 'dxgi_enums.cpp', 'dxgi_factory.cpp', 'dxgi_main.cpp', 'dxgi_output.cpp',