2017-10-11 03:09:04 +02:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
#include "dxgi_adapter.h"
|
2017-12-04 11:33:04 +01:00
|
|
|
#include "dxgi_enums.h"
|
2017-10-11 03:09:04 +02:00
|
|
|
#include "dxgi_factory.h"
|
|
|
|
#include "dxgi_output.h"
|
|
|
|
|
2017-12-04 11:33:04 +01:00
|
|
|
#include "../dxvk/vulkan/dxvk_vulkan_names.h"
|
|
|
|
|
2017-10-11 03:09:04 +02:00
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
DxgiAdapter::DxgiAdapter(
|
|
|
|
DxgiFactory* factory,
|
|
|
|
const Rc<DxvkAdapter>& adapter)
|
|
|
|
: m_factory (factory),
|
|
|
|
m_adapter (adapter) {
|
2017-12-04 11:33:04 +01:00
|
|
|
SetupFormatTable();
|
2017-10-11 03:09:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DxgiAdapter::~DxgiAdapter() {
|
2017-11-26 14:01:41 +01:00
|
|
|
|
2017-10-11 03:09:04 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT DxgiAdapter::QueryInterface(
|
|
|
|
REFIID riid,
|
|
|
|
void **ppvObject) {
|
2017-10-15 21:50:45 +02:00
|
|
|
COM_QUERY_IFACE(riid, ppvObject, IUnknown);
|
|
|
|
COM_QUERY_IFACE(riid, ppvObject, IDXGIObject);
|
2017-10-11 03:09:04 +02:00
|
|
|
COM_QUERY_IFACE(riid, ppvObject, IDXGIAdapter);
|
2017-11-26 16:12:11 +01:00
|
|
|
COM_QUERY_IFACE(riid, ppvObject, IDXGIAdapter1);
|
2017-11-27 15:51:53 +01:00
|
|
|
COM_QUERY_IFACE(riid, ppvObject, IDXGIAdapterPrivate);
|
2017-10-11 03:09:04 +02:00
|
|
|
|
|
|
|
Logger::warn("DxgiAdapter::QueryInterface: Unknown interface query");
|
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT DxgiAdapter::GetParent(
|
|
|
|
REFIID riid,
|
|
|
|
void **ppParent) {
|
|
|
|
return m_factory->QueryInterface(riid, ppParent);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT DxgiAdapter::CheckInterfaceSupport(
|
|
|
|
REFGUID InterfaceName,
|
|
|
|
LARGE_INTEGER *pUMDVersion) {
|
|
|
|
Logger::err("DxgiAdapter::CheckInterfaceSupport: No D3D10 support");
|
|
|
|
return DXGI_ERROR_UNSUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT DxgiAdapter::EnumOutputs(
|
|
|
|
UINT Output,
|
|
|
|
IDXGIOutput **ppOutput) {
|
|
|
|
if (ppOutput == nullptr)
|
|
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
|
|
|
|
int numDisplays = SDL_GetNumVideoDisplays();
|
|
|
|
|
|
|
|
if (numDisplays < 0) {
|
|
|
|
Logger::err("DxgiAdapter::EnumOutputs: Failed to query display count");
|
|
|
|
return DXGI_ERROR_DRIVER_INTERNAL_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Output >= static_cast<uint32_t>(numDisplays))
|
|
|
|
return DXGI_ERROR_NOT_FOUND;
|
|
|
|
|
|
|
|
*ppOutput = ref(new DxgiOutput(this, Output));
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT DxgiAdapter::GetDesc(DXGI_ADAPTER_DESC* pDesc) {
|
2017-11-26 16:12:11 +01:00
|
|
|
DXGI_ADAPTER_DESC1 desc1;
|
|
|
|
HRESULT hr = this->GetDesc1(&desc1);
|
|
|
|
|
|
|
|
if (SUCCEEDED(hr)) {
|
2017-11-26 16:18:32 +01:00
|
|
|
std::memcpy(
|
|
|
|
pDesc->Description,
|
|
|
|
desc1.Description,
|
|
|
|
sizeof(pDesc->Description));
|
|
|
|
|
2017-11-26 16:12:11 +01:00
|
|
|
pDesc->VendorId = desc1.VendorId;
|
|
|
|
pDesc->DeviceId = desc1.DeviceId;
|
|
|
|
pDesc->SubSysId = desc1.SubSysId;
|
|
|
|
pDesc->Revision = desc1.Revision;
|
|
|
|
pDesc->DedicatedVideoMemory = desc1.DedicatedVideoMemory;
|
|
|
|
pDesc->DedicatedSystemMemory = desc1.DedicatedSystemMemory;
|
|
|
|
pDesc->SharedSystemMemory = desc1.SharedSystemMemory;
|
|
|
|
pDesc->AdapterLuid = desc1.AdapterLuid;
|
|
|
|
}
|
|
|
|
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT DxgiAdapter::GetDesc1(DXGI_ADAPTER_DESC1* pDesc) {
|
2017-10-11 03:09:04 +02:00
|
|
|
if (pDesc == nullptr)
|
|
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
|
|
|
|
const auto deviceProp = m_adapter->deviceProperties();
|
|
|
|
const auto memoryProp = m_adapter->memoryProperties();
|
|
|
|
|
|
|
|
std::memset(pDesc->Description, 0, sizeof(pDesc->Description));
|
|
|
|
std::mbstowcs(pDesc->Description, deviceProp.deviceName, _countof(pDesc->Description) - 1);
|
|
|
|
|
|
|
|
VkDeviceSize deviceMemory = 0;
|
|
|
|
VkDeviceSize sharedMemory = 0;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < memoryProp.memoryHeapCount; i++) {
|
|
|
|
VkMemoryHeap heap = memoryProp.memoryHeaps[i];
|
|
|
|
|
|
|
|
if (heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
|
|
|
|
deviceMemory += heap.size;
|
|
|
|
else
|
|
|
|
sharedMemory += heap.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
pDesc->VendorId = deviceProp.vendorID;
|
|
|
|
pDesc->DeviceId = deviceProp.deviceID;
|
|
|
|
pDesc->SubSysId = 0;
|
|
|
|
pDesc->Revision = 0;
|
|
|
|
pDesc->DedicatedVideoMemory = deviceMemory;
|
|
|
|
pDesc->DedicatedSystemMemory = 0;
|
|
|
|
pDesc->SharedSystemMemory = sharedMemory;
|
|
|
|
pDesc->AdapterLuid = LUID { 0, 0 }; // TODO implement
|
2017-11-26 16:12:11 +01:00
|
|
|
pDesc->Flags = 0;
|
2017-10-11 03:09:04 +02:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2017-10-11 15:31:36 +02:00
|
|
|
|
|
|
|
Rc<DxvkAdapter> DxgiAdapter::GetDXVKAdapter() {
|
|
|
|
return m_adapter;
|
|
|
|
}
|
|
|
|
|
2017-12-04 11:33:04 +01:00
|
|
|
|
|
|
|
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<VkFormat>& 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_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;
|
|
|
|
}
|
|
|
|
|
2017-10-11 03:09:04 +02:00
|
|
|
}
|