1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-22 16:54:27 +01:00

[dxgi] Implemented separate color/depth format tables

This is required because in D3D11, typeless formats can be used
to create both depth and stencil images, and color formats can
be used to view depth images. In Vulkan, images and views that
are used as depth-stencil attachments will have to be created
with a depth-stencil format, so we have to take the image's
bind flags into account when picking a format.
This commit is contained in:
Philip Rebohle 2017-12-19 14:47:35 +01:00
parent 64a74735f8
commit f2587ab1b6
9 changed files with 221 additions and 177 deletions

View File

@ -107,9 +107,17 @@ namespace dxvk {
const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_TEXTURE2D_DESC* pDesc,
const D3D11_SUBRESOURCE_DATA* pInitialData, const D3D11_SUBRESOURCE_DATA* pInitialData,
ID3D11Texture2D** ppTexture2D) { ID3D11Texture2D** ppTexture2D) {
DxgiFormatMode formatMode = DxgiFormatMode::Any;
if (pDesc->BindFlags & D3D11_BIND_RENDER_TARGET)
formatMode = DxgiFormatMode::Color;
if (pDesc->BindFlags & D3D11_BIND_DEPTH_STENCIL)
formatMode = DxgiFormatMode::Depth;
DxvkImageCreateInfo info; DxvkImageCreateInfo info;
info.type = VK_IMAGE_TYPE_2D; info.type = VK_IMAGE_TYPE_2D;
info.format = m_dxgiAdapter->LookupFormat(pDesc->Format).actual; info.format = m_dxgiAdapter->LookupFormat(pDesc->Format, formatMode).actual;
info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
info.sampleCount = VK_SAMPLE_COUNT_1_BIT; info.sampleCount = VK_SAMPLE_COUNT_1_BIT;
info.extent.width = pDesc->Width; info.extent.width = pDesc->Width;
@ -187,7 +195,7 @@ namespace dxvk {
return hr; return hr;
*ppTexture2D = ref(new D3D11Texture2D( *ppTexture2D = ref(new D3D11Texture2D(
this, image.ptr(), *pDesc)); this, image.ptr(), formatMode, *pDesc));
InitTexture(image.ptr(), pInitialData); InitTexture(image.ptr(), pInitialData);
} }
@ -235,11 +243,20 @@ namespace dxvk {
reinterpret_cast<void**>(&imageResource)))) reinterpret_cast<void**>(&imageResource))))
return E_INVALIDARG; return E_INVALIDARG;
// TODO fix this properly
DxgiFormatMode formatMode = DxgiFormatMode::Any;
Com<D3D11Texture2D> texture2D;
if (SUCCEEDED(pResource->QueryInterface(
__uuidof(ID3D11Texture2D),
reinterpret_cast<void**>(&texture2D))))
formatMode = texture2D->GetFormatMode();
// Fill in the view info. The view type depends solely // Fill in the view info. The view type depends solely
// on the view dimension field in the view description, // on the view dimension field in the view description,
// not on the resource type. // not on the resource type.
DxvkImageViewCreateInfo viewInfo; DxvkImageViewCreateInfo viewInfo;
viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format).actual; viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, formatMode).actual;
viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask;
switch (desc.ViewDimension) { switch (desc.ViewDimension) {
@ -383,7 +400,7 @@ namespace dxvk {
// Fill in Vulkan image view info // Fill in Vulkan image view info
DxvkImageViewCreateInfo viewInfo; DxvkImageViewCreateInfo viewInfo;
viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format).actual; viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Color).actual;
viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask;
switch (desc.ViewDimension) { switch (desc.ViewDimension) {
@ -478,7 +495,7 @@ namespace dxvk {
// Fill in Vulkan image view info // Fill in Vulkan image view info
DxvkImageViewCreateInfo viewInfo; DxvkImageViewCreateInfo viewInfo;
viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format).actual; viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Depth).actual;
viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask;
switch (desc.ViewDimension) { switch (desc.ViewDimension) {
@ -573,7 +590,7 @@ namespace dxvk {
attrib.location = entry->registerId; attrib.location = entry->registerId;
attrib.binding = pInputElementDescs[i].InputSlot; attrib.binding = pInputElementDescs[i].InputSlot;
attrib.format = m_dxgiAdapter->LookupFormat( attrib.format = m_dxgiAdapter->LookupFormat(
pInputElementDescs[i].Format).actual; pInputElementDescs[i].Format, DxgiFormatMode::Color).actual;
attrib.offset = pInputElementDescs[i].AlignedByteOffset; attrib.offset = pInputElementDescs[i].AlignedByteOffset;
// The application may choose to let the implementation // The application may choose to let the implementation
@ -964,7 +981,8 @@ namespace dxvk {
*pNumQualityLevels = 0; *pNumQualityLevels = 0;
// We need to check whether the format is // We need to check whether the format is
VkFormat format = m_dxgiAdapter->LookupFormat(Format).actual; VkFormat format = m_dxgiAdapter->LookupFormat(
Format, DxgiFormatMode::Any).actual;
if (format == VK_FORMAT_UNDEFINED) { if (format == VK_FORMAT_UNDEFINED) {
Logger::err(str::format("D3D11: Unsupported format: ", Format)); Logger::err(str::format("D3D11: Unsupported format: ", Format));
@ -1466,7 +1484,7 @@ namespace dxvk {
HRESULT D3D11Device::GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const { HRESULT D3D11Device::GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const {
const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format).actual; const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format, DxgiFormatMode::Any).actual;
const VkFormatProperties fmtInfo = m_dxvkAdapter->formatProperties(fmt); const VkFormatProperties fmtInfo = m_dxvkAdapter->formatProperties(fmt);
if (fmt == VK_FORMAT_UNDEFINED) if (fmt == VK_FORMAT_UNDEFINED)

View File

@ -35,7 +35,7 @@ namespace dxvk {
desc.MiscFlags = 0; desc.MiscFlags = 0;
*ppInterface = ref(new D3D11Texture2D( *ppInterface = ref(new D3D11Texture2D(
m_device, pResource, desc)); m_device, pResource, DxgiFormatMode::Color, desc));
return S_OK; return S_OK;
} }

View File

@ -6,10 +6,12 @@ namespace dxvk {
D3D11Texture2D::D3D11Texture2D( D3D11Texture2D::D3D11Texture2D(
D3D11Device* device, D3D11Device* device,
IDXGIImageResourcePrivate* resource, IDXGIImageResourcePrivate* resource,
DxgiFormatMode formatMode,
const D3D11_TEXTURE2D_DESC& desc) const D3D11_TEXTURE2D_DESC& desc)
: m_device (device), : m_device (device),
m_resource(resource), m_resource (resource),
m_desc (desc) { m_formatMode(formatMode),
m_desc (desc) {
} }
@ -60,9 +62,4 @@ namespace dxvk {
*pDesc = m_desc; *pDesc = m_desc;
} }
Rc<DxvkImage> D3D11Texture2D::GetDXVKImage() {
return m_resource->GetDXVKImage();
}
} }

View File

@ -17,6 +17,7 @@ namespace dxvk {
D3D11Texture2D( D3D11Texture2D(
D3D11Device* device, D3D11Device* device,
IDXGIImageResourcePrivate* resource, IDXGIImageResourcePrivate* resource,
DxgiFormatMode formatMode,
const D3D11_TEXTURE2D_DESC& desc); const D3D11_TEXTURE2D_DESC& desc);
~D3D11Texture2D(); ~D3D11Texture2D();
@ -37,12 +38,19 @@ namespace dxvk {
void STDMETHODCALLTYPE GetDesc( void STDMETHODCALLTYPE GetDesc(
D3D11_TEXTURE2D_DESC *pDesc) final; D3D11_TEXTURE2D_DESC *pDesc) final;
Rc<DxvkImage> GetDXVKImage(); DxgiFormatMode GetFormatMode() const {
return m_formatMode;
}
Rc<DxvkImage> GetDXVKImage() const {
return m_resource->GetDXVKImage();
}
private: private:
Com<D3D11Device> m_device; Com<D3D11Device> m_device;
Com<IDXGIImageResourcePrivate> m_resource; Com<IDXGIImageResourcePrivate> m_resource;
DxgiFormatMode m_formatMode;
D3D11_TEXTURE2D_DESC m_desc; D3D11_TEXTURE2D_DESC m_desc;
}; };

View File

@ -138,200 +138,194 @@ namespace dxvk {
} }
DxgiFormatPair STDMETHODCALLTYPE DxgiAdapter::LookupFormat(DXGI_FORMAT format) { DxgiFormatPair STDMETHODCALLTYPE DxgiAdapter::LookupFormat(DXGI_FORMAT format, DxgiFormatMode mode) {
auto pair = m_formats.find(format); // If the mode is 'Any', probe color formats first
if (mode != DxgiFormatMode::Depth) {
auto color = m_colorFormats.find(format);
return pair != m_formats.end() if (color != m_colorFormats.end())
? pair->second return color->second;
: DxgiFormatPair(); }
if (mode != DxgiFormatMode::Color) {
auto depth = m_depthFormats.find(format);
if (depth != m_depthFormats.end())
return depth->second;
}
return DxgiFormatPair();
} }
void DxgiAdapter::AddFormat( void DxgiAdapter::AddColorFormat(
DXGI_FORMAT srcFormat, DXGI_FORMAT srcFormat,
VkFormat dstFormat) { VkFormat dstFormat) {
DxgiFormatPair formatPair; DxgiFormatPair formatPair;
formatPair.wanted = dstFormat; formatPair.wanted = dstFormat;
formatPair.actual = dstFormat; formatPair.actual = dstFormat;
m_formats.insert(std::make_pair(srcFormat, formatPair)); m_colorFormats.insert(std::make_pair(srcFormat, formatPair));
} }
void DxgiAdapter::AddFormat( void DxgiAdapter::AddDepthFormat(
DXGI_FORMAT srcFormat, DXGI_FORMAT srcFormat,
VkFormat dstFormat, VkFormat dstFormat) {
const std::initializer_list<VkFormat>& fallbacks,
VkFormatFeatureFlags features) {
DxgiFormatPair formatPair; DxgiFormatPair formatPair;
formatPair.wanted = dstFormat; formatPair.wanted = dstFormat;
formatPair.actual = VK_FORMAT_UNDEFINED; formatPair.actual = dstFormat;
m_depthFormats.insert(std::make_pair(srcFormat, formatPair));
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() { void DxgiAdapter::SetupFormatTable() {
AddFormat(DXGI_FORMAT_UNKNOWN, VK_FORMAT_UNDEFINED); /***********************************************************************************/
/* C O L O R F O R M A T S */
AddColorFormat(DXGI_FORMAT_UNKNOWN, VK_FORMAT_UNDEFINED);
AddFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS, VK_FORMAT_R32G32B32A32_UINT); AddColorFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS, VK_FORMAT_R32G32B32A32_UINT);
AddFormat(DXGI_FORMAT_R32G32B32A32_FLOAT, VK_FORMAT_R32G32B32A32_SFLOAT); AddColorFormat(DXGI_FORMAT_R32G32B32A32_FLOAT, VK_FORMAT_R32G32B32A32_SFLOAT);
AddFormat(DXGI_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_UINT); AddColorFormat(DXGI_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_UINT);
AddFormat(DXGI_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SINT); AddColorFormat(DXGI_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SINT);
AddFormat(DXGI_FORMAT_R32G32B32_TYPELESS, VK_FORMAT_R32G32B32_UINT); AddColorFormat(DXGI_FORMAT_R32G32B32_TYPELESS, VK_FORMAT_R32G32B32_UINT);
AddFormat(DXGI_FORMAT_R32G32B32_FLOAT, VK_FORMAT_R32G32B32_SFLOAT); AddColorFormat(DXGI_FORMAT_R32G32B32_FLOAT, VK_FORMAT_R32G32B32_SFLOAT);
AddFormat(DXGI_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_UINT); AddColorFormat(DXGI_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_UINT);
AddFormat(DXGI_FORMAT_R32G32B32_SINT, VK_FORMAT_R32G32B32_SINT); AddColorFormat(DXGI_FORMAT_R32G32B32_SINT, VK_FORMAT_R32G32B32_SINT);
AddFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS, VK_FORMAT_R16G16B16A16_UINT); AddColorFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS, VK_FORMAT_R16G16B16A16_UINT);
AddFormat(DXGI_FORMAT_R16G16B16A16_FLOAT, VK_FORMAT_R16G16B16A16_SFLOAT); AddColorFormat(DXGI_FORMAT_R16G16B16A16_FLOAT, VK_FORMAT_R16G16B16A16_SFLOAT);
AddFormat(DXGI_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM); AddColorFormat(DXGI_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM);
AddFormat(DXGI_FORMAT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_UINT); AddColorFormat(DXGI_FORMAT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_UINT);
AddFormat(DXGI_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM); AddColorFormat(DXGI_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM);
AddFormat(DXGI_FORMAT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SINT); AddColorFormat(DXGI_FORMAT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SINT);
AddFormat(DXGI_FORMAT_R32G32_TYPELESS, VK_FORMAT_R32G32_UINT); AddColorFormat(DXGI_FORMAT_R32G32_TYPELESS, VK_FORMAT_R32G32_UINT);
AddFormat(DXGI_FORMAT_R32G32_FLOAT, VK_FORMAT_R32G32_SFLOAT); AddColorFormat(DXGI_FORMAT_R32G32_FLOAT, VK_FORMAT_R32G32_SFLOAT);
AddFormat(DXGI_FORMAT_R32G32_UINT, VK_FORMAT_R32G32_UINT); AddColorFormat(DXGI_FORMAT_R32G32_UINT, VK_FORMAT_R32G32_UINT);
AddFormat(DXGI_FORMAT_R32G32_SINT, VK_FORMAT_R32G32_SINT); AddColorFormat(DXGI_FORMAT_R32G32_SINT, VK_FORMAT_R32G32_SINT);
AddFormat(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); AddColorFormat(DXGI_FORMAT_R10G10B10A2_TYPELESS, VK_FORMAT_A2R10G10B10_UINT_PACK32);
// AddFormat(DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_UNDEFINED); AddColorFormat(DXGI_FORMAT_R10G10B10A2_UINT, VK_FORMAT_A2R10G10B10_UINT_PACK32);
// AddFormat(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_UNDEFINED); AddColorFormat(DXGI_FORMAT_R10G10B10A2_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32);
// AddFormat(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_UNDEFINED);
AddFormat(DXGI_FORMAT_R10G10B10A2_TYPELESS, VK_FORMAT_A2R10G10B10_UINT_PACK32); AddColorFormat(DXGI_FORMAT_R11G11B10_FLOAT, VK_FORMAT_B10G11R11_UFLOAT_PACK32);
AddFormat(DXGI_FORMAT_R10G10B10A2_UINT, VK_FORMAT_A2R10G10B10_UINT_PACK32);
AddFormat(DXGI_FORMAT_R10G10B10A2_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32);
AddFormat(DXGI_FORMAT_R11G11B10_FLOAT, VK_FORMAT_B10G11R11_UFLOAT_PACK32); AddColorFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS, VK_FORMAT_R8G8B8A8_UINT);
AddColorFormat(DXGI_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM);
AddColorFormat(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, VK_FORMAT_R8G8B8A8_SRGB);
AddColorFormat(DXGI_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UINT);
AddColorFormat(DXGI_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SNORM);
AddColorFormat(DXGI_FORMAT_R8G8B8A8_SINT, VK_FORMAT_R8G8B8A8_SINT);
AddFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS, VK_FORMAT_R8G8B8A8_UINT); AddColorFormat(DXGI_FORMAT_R16G16_TYPELESS, VK_FORMAT_R16G16_UINT);
AddFormat(DXGI_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM); AddColorFormat(DXGI_FORMAT_R16G16_FLOAT, VK_FORMAT_R16G16_SFLOAT);
AddFormat(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, VK_FORMAT_R8G8B8A8_SRGB); AddColorFormat(DXGI_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16_UNORM);
AddFormat(DXGI_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UINT); AddColorFormat(DXGI_FORMAT_R16G16_UINT, VK_FORMAT_R16G16_UINT);
AddFormat(DXGI_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SNORM); AddColorFormat(DXGI_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16_SNORM);
AddFormat(DXGI_FORMAT_R8G8B8A8_SINT, VK_FORMAT_R8G8B8A8_SINT); AddColorFormat(DXGI_FORMAT_R16G16_SINT, VK_FORMAT_R16G16_SINT);
AddFormat(DXGI_FORMAT_R16G16_TYPELESS, VK_FORMAT_R16G16_UINT); AddColorFormat(DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_R32_UINT);
AddFormat(DXGI_FORMAT_R16G16_FLOAT, VK_FORMAT_R16G16_SFLOAT); AddColorFormat(DXGI_FORMAT_R32_FLOAT, VK_FORMAT_R32_SFLOAT);
AddFormat(DXGI_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16_UNORM); AddColorFormat(DXGI_FORMAT_R32_UINT, VK_FORMAT_R32_UINT);
AddFormat(DXGI_FORMAT_R16G16_UINT, VK_FORMAT_R16G16_UINT); AddColorFormat(DXGI_FORMAT_R32_SINT, VK_FORMAT_R32_SINT);
AddFormat(DXGI_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16_SNORM);
AddFormat(DXGI_FORMAT_R16G16_SINT, VK_FORMAT_R16G16_SINT);
AddFormat(DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_R32_UINT); AddColorFormat(DXGI_FORMAT_R8G8_TYPELESS, VK_FORMAT_R8G8_UINT);
AddFormat(DXGI_FORMAT_R32_FLOAT, VK_FORMAT_R32_SFLOAT); AddColorFormat(DXGI_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8_UNORM);
AddFormat(DXGI_FORMAT_R32_UINT, VK_FORMAT_R32_UINT); AddColorFormat(DXGI_FORMAT_R8G8_UINT, VK_FORMAT_R8G8_UINT);
AddFormat(DXGI_FORMAT_R32_SINT, VK_FORMAT_R32_SINT); AddColorFormat(DXGI_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8_SNORM);
AddColorFormat(DXGI_FORMAT_R8G8_SINT, VK_FORMAT_R8G8_SINT);
AddFormat(DXGI_FORMAT_R8G8_TYPELESS, VK_FORMAT_R8G8_UINT); AddColorFormat(DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_R16_UINT);
AddFormat(DXGI_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8_UNORM); AddColorFormat(DXGI_FORMAT_R16_FLOAT, VK_FORMAT_R16_SFLOAT);
AddFormat(DXGI_FORMAT_R8G8_UINT, VK_FORMAT_R8G8_UINT); AddColorFormat(DXGI_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM);
AddFormat(DXGI_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8_SNORM); AddColorFormat(DXGI_FORMAT_R16_UINT, VK_FORMAT_R16_UINT);
AddFormat(DXGI_FORMAT_R8G8_SINT, VK_FORMAT_R8G8_SINT); AddColorFormat(DXGI_FORMAT_R16_SNORM, VK_FORMAT_R16_SNORM);
AddColorFormat(DXGI_FORMAT_R16_SINT, VK_FORMAT_R16_SINT);
AddFormat(DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_R16_UINT); AddColorFormat(DXGI_FORMAT_R8_TYPELESS, VK_FORMAT_R8_UINT);
AddFormat(DXGI_FORMAT_R16_FLOAT, VK_FORMAT_R16_SFLOAT); AddColorFormat(DXGI_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM);
AddFormat(DXGI_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM); AddColorFormat(DXGI_FORMAT_R8_UINT, VK_FORMAT_R8_UINT);
AddFormat(DXGI_FORMAT_R16_UINT, VK_FORMAT_R16_UINT); AddColorFormat(DXGI_FORMAT_R8_SNORM, VK_FORMAT_R8_SNORM);
AddFormat(DXGI_FORMAT_R16_SNORM, VK_FORMAT_R16_SNORM); AddColorFormat(DXGI_FORMAT_R8_SINT, VK_FORMAT_R8_SINT);
AddFormat(DXGI_FORMAT_R16_SINT, VK_FORMAT_R16_SINT);
AddFormat(DXGI_FORMAT_R8_TYPELESS, VK_FORMAT_R8_UINT); // AddColorFormat(DXGI_FORMAT_A8_UNORM, VK_FORMAT_UNDEFINED);
AddFormat(DXGI_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM);
AddFormat(DXGI_FORMAT_R8_UINT, VK_FORMAT_R8_UINT);
AddFormat(DXGI_FORMAT_R8_SNORM, VK_FORMAT_R8_SNORM);
AddFormat(DXGI_FORMAT_R8_SINT, VK_FORMAT_R8_SINT);
// AddFormat(DXGI_FORMAT_A8_UNORM, VK_FORMAT_UNDEFINED);
// AddFormat(DXGI_FORMAT_R1_UNORM, VK_FORMAT_UNDEFINED); // AddColorFormat(DXGI_FORMAT_R1_UNORM, VK_FORMAT_UNDEFINED);
AddFormat(DXGI_FORMAT_R9G9B9E5_SHAREDEXP, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32); AddColorFormat(DXGI_FORMAT_R9G9B9E5_SHAREDEXP, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32);
// AddFormat(DXGI_FORMAT_R8G8_B8G8_UNORM, VK_FORMAT_UNDEFINED); // AddColorFormat(DXGI_FORMAT_R8G8_B8G8_UNORM, VK_FORMAT_UNDEFINED);
AddFormat(DXGI_FORMAT_G8R8_G8B8_UNORM, VK_FORMAT_UNDEFINED); // AddColorFormat(DXGI_FORMAT_G8R8_G8B8_UNORM, VK_FORMAT_UNDEFINED);
AddFormat(DXGI_FORMAT_BC1_TYPELESS, VK_FORMAT_BC1_RGBA_UNORM_BLOCK); AddColorFormat(DXGI_FORMAT_B5G6R5_UNORM, VK_FORMAT_B5G6R5_UNORM_PACK16);
AddFormat(DXGI_FORMAT_BC1_UNORM, VK_FORMAT_BC1_RGBA_UNORM_BLOCK); AddColorFormat(DXGI_FORMAT_B5G5R5A1_UNORM, VK_FORMAT_B5G5R5A1_UNORM_PACK16);
AddFormat(DXGI_FORMAT_BC1_UNORM_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK);
AddFormat(DXGI_FORMAT_BC2_TYPELESS, VK_FORMAT_BC2_UNORM_BLOCK); AddColorFormat(DXGI_FORMAT_B8G8R8A8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM);
AddFormat(DXGI_FORMAT_BC2_UNORM, VK_FORMAT_BC2_UNORM_BLOCK); AddColorFormat(DXGI_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM);
AddFormat(DXGI_FORMAT_BC2_UNORM_SRGB, VK_FORMAT_BC2_SRGB_BLOCK); AddColorFormat(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB);
AddFormat(DXGI_FORMAT_BC3_TYPELESS, VK_FORMAT_BC3_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC3_UNORM, VK_FORMAT_BC3_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC3_UNORM_SRGB, VK_FORMAT_BC3_SRGB_BLOCK);
AddFormat(DXGI_FORMAT_BC4_TYPELESS, VK_FORMAT_BC4_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC4_UNORM, VK_FORMAT_BC4_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC4_SNORM, VK_FORMAT_BC4_SNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC5_TYPELESS, VK_FORMAT_BC5_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC5_UNORM, VK_FORMAT_BC5_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC5_SNORM, VK_FORMAT_BC5_SNORM_BLOCK);
AddFormat(DXGI_FORMAT_B5G6R5_UNORM, VK_FORMAT_B5G6R5_UNORM_PACK16);
AddFormat(DXGI_FORMAT_B5G5R5A1_UNORM, VK_FORMAT_B5G5R5A1_UNORM_PACK16);
AddFormat(DXGI_FORMAT_B8G8R8A8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM);
AddFormat(DXGI_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM);
AddFormat(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB);
// TODO implement component swizzle // TODO implement component swizzle
AddFormat(DXGI_FORMAT_B8G8R8X8_UNORM, VK_FORMAT_B8G8R8A8_UNORM); AddColorFormat(DXGI_FORMAT_B8G8R8X8_UNORM, VK_FORMAT_B8G8R8A8_UNORM);
AddFormat(DXGI_FORMAT_B8G8R8X8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM); AddColorFormat(DXGI_FORMAT_B8G8R8X8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM);
AddFormat(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB); AddColorFormat(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB);
// AddColorFormat(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, VK_FORMAT_UNDEFINED);
// AddFormat(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, VK_FORMAT_UNDEFINED); /***********************************************************************************/
/* B L O C K F O R M A T S */
AddColorFormat(DXGI_FORMAT_BC1_TYPELESS, VK_FORMAT_BC1_RGBA_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC1_UNORM, VK_FORMAT_BC1_RGBA_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC1_UNORM_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK);
AddFormat(DXGI_FORMAT_BC6H_TYPELESS, VK_FORMAT_BC6H_UFLOAT_BLOCK); AddColorFormat(DXGI_FORMAT_BC2_TYPELESS, VK_FORMAT_BC2_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC6H_UF16, VK_FORMAT_BC6H_UFLOAT_BLOCK); AddColorFormat(DXGI_FORMAT_BC2_UNORM, VK_FORMAT_BC2_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC6H_SF16, VK_FORMAT_BC6H_SFLOAT_BLOCK); AddColorFormat(DXGI_FORMAT_BC2_UNORM_SRGB, VK_FORMAT_BC2_SRGB_BLOCK);
AddFormat(DXGI_FORMAT_BC7_TYPELESS, VK_FORMAT_BC7_UNORM_BLOCK); AddColorFormat(DXGI_FORMAT_BC3_TYPELESS, VK_FORMAT_BC3_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC7_UNORM, VK_FORMAT_BC7_UNORM_BLOCK); AddColorFormat(DXGI_FORMAT_BC3_UNORM, VK_FORMAT_BC3_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC7_UNORM_SRGB, VK_FORMAT_BC7_SRGB_BLOCK); AddColorFormat(DXGI_FORMAT_BC3_UNORM_SRGB, VK_FORMAT_BC3_SRGB_BLOCK);
AddFormat( AddColorFormat(DXGI_FORMAT_BC4_TYPELESS, VK_FORMAT_BC4_UNORM_BLOCK);
DXGI_FORMAT_D32_FLOAT, AddColorFormat(DXGI_FORMAT_BC4_UNORM, VK_FORMAT_BC4_UNORM_BLOCK);
VK_FORMAT_D32_SFLOAT, { AddColorFormat(DXGI_FORMAT_BC4_SNORM, VK_FORMAT_BC4_SNORM_BLOCK);
VK_FORMAT_D32_SFLOAT_S8_UINT,
},
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
AddFormat( AddColorFormat(DXGI_FORMAT_BC5_TYPELESS, VK_FORMAT_BC5_UNORM_BLOCK);
DXGI_FORMAT_D24_UNORM_S8_UINT, AddColorFormat(DXGI_FORMAT_BC5_UNORM, VK_FORMAT_BC5_UNORM_BLOCK);
VK_FORMAT_D24_UNORM_S8_UINT, { AddColorFormat(DXGI_FORMAT_BC5_SNORM, VK_FORMAT_BC5_SNORM_BLOCK);
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); AddColorFormat(DXGI_FORMAT_BC6H_TYPELESS, VK_FORMAT_BC6H_UFLOAT_BLOCK);
AddColorFormat(DXGI_FORMAT_BC6H_UF16, VK_FORMAT_BC6H_UFLOAT_BLOCK);
AddColorFormat(DXGI_FORMAT_BC6H_SF16, VK_FORMAT_BC6H_SFLOAT_BLOCK);
// AddFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_UNDEFINED); AddColorFormat(DXGI_FORMAT_BC7_TYPELESS, VK_FORMAT_BC7_UNORM_BLOCK);
// AddFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_UNDEFINED); AddColorFormat(DXGI_FORMAT_BC7_UNORM, VK_FORMAT_BC7_UNORM_BLOCK);
// AddFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_UNDEFINED); AddColorFormat(DXGI_FORMAT_BC7_UNORM_SRGB, VK_FORMAT_BC7_SRGB_BLOCK);
// TODO finish me /***********************************************************************************/
/* D E P T H F O R M A T S */
AddDepthFormat(DXGI_FORMAT_D16_UNORM, VK_FORMAT_D16_UNORM);
AddDepthFormat(DXGI_FORMAT_R16_UNORM, VK_FORMAT_D16_UNORM);
AddDepthFormat(DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_D16_UNORM);
AddDepthFormat(DXGI_FORMAT_D32_FLOAT, VK_FORMAT_D32_SFLOAT);
AddDepthFormat(DXGI_FORMAT_R32_FLOAT, VK_FORMAT_D32_SFLOAT);
AddDepthFormat(DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_D32_SFLOAT);
AddDepthFormat(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT);
AddDepthFormat(DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT);
AddDepthFormat(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT);
AddDepthFormat(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT);
// Vulkan implementations are not required to support 24-bit depth buffers natively
// and AMD decided to not implement them, so we'll fall back to 32-bit depth buffers
if (HasFormatSupport(VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
AddDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT);
AddDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT);
AddDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D24_UNORM_S8_UINT);
} else {
Logger::warn("DxgiAdapter: DXGI_FORMAT_D24_UNORM_S8_UINT -> VK_FORMAT_D32_SFLOAT_S8_UINT");
AddDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT);
AddDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT);
AddDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT);
}
} }

View File

@ -49,24 +49,25 @@ namespace dxvk {
Rc<DxvkAdapter> STDMETHODCALLTYPE GetDXVKAdapter() final; Rc<DxvkAdapter> STDMETHODCALLTYPE GetDXVKAdapter() final;
DxgiFormatPair STDMETHODCALLTYPE LookupFormat( DxgiFormatPair STDMETHODCALLTYPE LookupFormat(
DXGI_FORMAT format) final; DXGI_FORMAT format, DxgiFormatMode mode) final;
private: private:
using FormatMap = std::unordered_map<DXGI_FORMAT, DxgiFormatPair>;
Com<DxgiFactory> m_factory; Com<DxgiFactory> m_factory;
Rc<DxvkAdapter> m_adapter; Rc<DxvkAdapter> m_adapter;
std::unordered_map<DXGI_FORMAT, DxgiFormatPair> m_formats; FormatMap m_colorFormats;
FormatMap m_depthFormats;
void AddFormat( void AddColorFormat(
DXGI_FORMAT srcFormat, DXGI_FORMAT srcFormat,
VkFormat dstFormat); VkFormat dstFormat);
void AddFormat( void AddDepthFormat(
DXGI_FORMAT srcFormat, DXGI_FORMAT srcFormat,
VkFormat dstFormat, VkFormat dstFormat);
const std::initializer_list<VkFormat>& fallbacks,
VkFormatFeatureFlags features);
void SetupFormatTable(); void SetupFormatTable();

View File

@ -24,6 +24,20 @@ namespace dxvk {
VkFormat wanted = VK_FORMAT_UNDEFINED; VkFormat wanted = VK_FORMAT_UNDEFINED;
VkFormat actual = VK_FORMAT_UNDEFINED; VkFormat actual = VK_FORMAT_UNDEFINED;
}; };
/**
* \brief Format lookup mode
*
* When looking up an image format, additional information
* might be needed on how the image is going to be used.
* This is used to properly map typeless formats and color
* formats to depth formats if they are used on depth images.
*/
enum class DxgiFormatMode : uint32_t {
Any = 0,
Color = 1,
Depth = 2,
};
} }
/** /**
@ -39,8 +53,20 @@ IDXGIAdapterPrivate : public IDXGIAdapter1 {
virtual dxvk::Rc<dxvk::DxvkAdapter> STDMETHODCALLTYPE GetDXVKAdapter() = 0; virtual dxvk::Rc<dxvk::DxvkAdapter> STDMETHODCALLTYPE GetDXVKAdapter() = 0;
/**
* \brief Maps a DXGI format to a compatible Vulkan format
*
* For color formats, the returned Vulkan format has the
* same memory layout as the DXGI format so that it can
* be mapped and copied to buffers. For depth-stencil
* formats, this is not guaranteed.
* \param [in] format The DXGI format
* \param [in] mode Format lookup mode
* \returns Vulkan format pair
*/
virtual dxvk::DxgiFormatPair STDMETHODCALLTYPE LookupFormat( virtual dxvk::DxgiFormatPair STDMETHODCALLTYPE LookupFormat(
DXGI_FORMAT format) = 0; DXGI_FORMAT format,
dxvk::DxgiFormatMode mode) = 0;
}; };

View File

@ -22,7 +22,7 @@ namespace dxvk {
// Create swap chain for the surface // Create swap chain for the surface
DxvkSwapchainProperties swapchainProperties; DxvkSwapchainProperties swapchainProperties;
swapchainProperties.preferredSurfaceFormat = this->pickFormat(bufferFormat); swapchainProperties.preferredSurfaceFormat = this->pickFormat(bufferFormat);
swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
swapchainProperties.preferredBufferSize.width = bufferWidth; swapchainProperties.preferredBufferSize.width = bufferWidth;
swapchainProperties.preferredBufferSize.height = bufferHeight; swapchainProperties.preferredBufferSize.height = bufferHeight;
@ -315,7 +315,7 @@ namespace dxvk {
DXGI_FORMAT bufferFormat) { DXGI_FORMAT bufferFormat) {
DxvkSwapchainProperties swapchainProperties; DxvkSwapchainProperties swapchainProperties;
swapchainProperties.preferredSurfaceFormat = this->pickFormat(bufferFormat); swapchainProperties.preferredSurfaceFormat = this->pickFormat(bufferFormat);
swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_FIFO_KHR;
swapchainProperties.preferredBufferSize.width = bufferWidth; swapchainProperties.preferredBufferSize.width = bufferWidth;
swapchainProperties.preferredBufferSize.height = bufferHeight; swapchainProperties.preferredBufferSize.height = bufferHeight;

View File

@ -331,7 +331,7 @@ namespace dxvk {
const Rc<DxvkImage> backBuffer = m_presenter->createBackBuffer( const Rc<DxvkImage> backBuffer = m_presenter->createBackBuffer(
m_desc.BufferDesc.Width, m_desc.BufferDesc.Height, m_desc.BufferDesc.Width, m_desc.BufferDesc.Height,
m_adapter->LookupFormat(m_desc.BufferDesc.Format).actual, m_adapter->LookupFormat(m_desc.BufferDesc.Format, DxgiFormatMode::Color).actual,
sampleCount); sampleCount);
const Com<IDXGIImageResourcePrivate> resource const Com<IDXGIImageResourcePrivate> resource