[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_SUBRESOURCE_DATA* pInitialData,
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;
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.sampleCount = VK_SAMPLE_COUNT_1_BIT;
info.extent.width = pDesc->Width;
@ -187,7 +195,7 @@ namespace dxvk {
return hr;
*ppTexture2D = ref(new D3D11Texture2D(
this, image.ptr(), *pDesc));
this, image.ptr(), formatMode, *pDesc));
InitTexture(image.ptr(), pInitialData);
}
@ -235,11 +243,20 @@ namespace dxvk {
reinterpret_cast<void**>(&imageResource))))
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
// on the view dimension field in the view description,
// not on the resource type.
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;
switch (desc.ViewDimension) {
@ -383,7 +400,7 @@ namespace dxvk {
// Fill in Vulkan image view info
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;
switch (desc.ViewDimension) {
@ -478,7 +495,7 @@ namespace dxvk {
// Fill in Vulkan image view info
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;
switch (desc.ViewDimension) {
@ -573,7 +590,7 @@ namespace dxvk {
attrib.location = entry->registerId;
attrib.binding = pInputElementDescs[i].InputSlot;
attrib.format = m_dxgiAdapter->LookupFormat(
pInputElementDescs[i].Format).actual;
pInputElementDescs[i].Format, DxgiFormatMode::Color).actual;
attrib.offset = pInputElementDescs[i].AlignedByteOffset;
// The application may choose to let the implementation
@ -964,7 +981,8 @@ namespace dxvk {
*pNumQualityLevels = 0;
// 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) {
Logger::err(str::format("D3D11: Unsupported format: ", Format));
@ -1466,7 +1484,7 @@ namespace dxvk {
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);
if (fmt == VK_FORMAT_UNDEFINED)

View File

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

View File

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

View File

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

View File

@ -138,200 +138,194 @@ namespace dxvk {
}
DxgiFormatPair STDMETHODCALLTYPE DxgiAdapter::LookupFormat(DXGI_FORMAT format) {
auto pair = m_formats.find(format);
DxgiFormatPair STDMETHODCALLTYPE DxgiAdapter::LookupFormat(DXGI_FORMAT format, DxgiFormatMode mode) {
// If the mode is 'Any', probe color formats first
if (mode != DxgiFormatMode::Depth) {
auto color = m_colorFormats.find(format);
if (color != m_colorFormats.end())
return color->second;
}
return pair != m_formats.end()
? pair->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,
VkFormat dstFormat) {
DxgiFormatPair formatPair;
formatPair.wanted = 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,
VkFormat dstFormat,
const std::initializer_list<VkFormat>& fallbacks,
VkFormatFeatureFlags features) {
VkFormat dstFormat) {
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));
formatPair.actual = dstFormat;
m_depthFormats.insert(std::make_pair(srcFormat, formatPair));
}
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);
AddFormat(DXGI_FORMAT_R32G32B32A32_FLOAT, VK_FORMAT_R32G32B32A32_SFLOAT);
AddFormat(DXGI_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_UINT);
AddFormat(DXGI_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SINT);
AddColorFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS, VK_FORMAT_R32G32B32A32_UINT);
AddColorFormat(DXGI_FORMAT_R32G32B32A32_FLOAT, VK_FORMAT_R32G32B32A32_SFLOAT);
AddColorFormat(DXGI_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_UINT);
AddColorFormat(DXGI_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SINT);
AddFormat(DXGI_FORMAT_R32G32B32_TYPELESS, VK_FORMAT_R32G32B32_UINT);
AddFormat(DXGI_FORMAT_R32G32B32_FLOAT, VK_FORMAT_R32G32B32_SFLOAT);
AddFormat(DXGI_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_UINT);
AddFormat(DXGI_FORMAT_R32G32B32_SINT, VK_FORMAT_R32G32B32_SINT);
AddColorFormat(DXGI_FORMAT_R32G32B32_TYPELESS, VK_FORMAT_R32G32B32_UINT);
AddColorFormat(DXGI_FORMAT_R32G32B32_FLOAT, VK_FORMAT_R32G32B32_SFLOAT);
AddColorFormat(DXGI_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_UINT);
AddColorFormat(DXGI_FORMAT_R32G32B32_SINT, VK_FORMAT_R32G32B32_SINT);
AddFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS, VK_FORMAT_R16G16B16A16_UINT);
AddFormat(DXGI_FORMAT_R16G16B16A16_FLOAT, VK_FORMAT_R16G16B16A16_SFLOAT);
AddFormat(DXGI_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM);
AddFormat(DXGI_FORMAT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_UINT);
AddFormat(DXGI_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM);
AddFormat(DXGI_FORMAT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SINT);
AddColorFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS, VK_FORMAT_R16G16B16A16_UINT);
AddColorFormat(DXGI_FORMAT_R16G16B16A16_FLOAT, VK_FORMAT_R16G16B16A16_SFLOAT);
AddColorFormat(DXGI_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM);
AddColorFormat(DXGI_FORMAT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_UINT);
AddColorFormat(DXGI_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM);
AddColorFormat(DXGI_FORMAT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SINT);
AddFormat(DXGI_FORMAT_R32G32_TYPELESS, VK_FORMAT_R32G32_UINT);
AddFormat(DXGI_FORMAT_R32G32_FLOAT, VK_FORMAT_R32G32_SFLOAT);
AddFormat(DXGI_FORMAT_R32G32_UINT, VK_FORMAT_R32G32_UINT);
AddFormat(DXGI_FORMAT_R32G32_SINT, VK_FORMAT_R32G32_SINT);
AddColorFormat(DXGI_FORMAT_R32G32_TYPELESS, VK_FORMAT_R32G32_UINT);
AddColorFormat(DXGI_FORMAT_R32G32_FLOAT, VK_FORMAT_R32G32_SFLOAT);
AddColorFormat(DXGI_FORMAT_R32G32_UINT, VK_FORMAT_R32G32_UINT);
AddColorFormat(DXGI_FORMAT_R32G32_SINT, VK_FORMAT_R32G32_SINT);
AddFormat(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT);
// AddFormat(DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_UNDEFINED);
// AddFormat(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_UNDEFINED);
// AddFormat(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_UNDEFINED);
AddColorFormat(DXGI_FORMAT_R10G10B10A2_TYPELESS, VK_FORMAT_A2R10G10B10_UINT_PACK32);
AddColorFormat(DXGI_FORMAT_R10G10B10A2_UINT, VK_FORMAT_A2R10G10B10_UINT_PACK32);
AddColorFormat(DXGI_FORMAT_R10G10B10A2_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32);
AddFormat(DXGI_FORMAT_R10G10B10A2_TYPELESS, VK_FORMAT_A2R10G10B10_UINT_PACK32);
AddFormat(DXGI_FORMAT_R10G10B10A2_UINT, VK_FORMAT_A2R10G10B10_UINT_PACK32);
AddFormat(DXGI_FORMAT_R10G10B10A2_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32);
AddColorFormat(DXGI_FORMAT_R11G11B10_FLOAT, VK_FORMAT_B10G11R11_UFLOAT_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);
AddFormat(DXGI_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM);
AddFormat(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, VK_FORMAT_R8G8B8A8_SRGB);
AddFormat(DXGI_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UINT);
AddFormat(DXGI_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SNORM);
AddFormat(DXGI_FORMAT_R8G8B8A8_SINT, VK_FORMAT_R8G8B8A8_SINT);
AddColorFormat(DXGI_FORMAT_R16G16_TYPELESS, VK_FORMAT_R16G16_UINT);
AddColorFormat(DXGI_FORMAT_R16G16_FLOAT, VK_FORMAT_R16G16_SFLOAT);
AddColorFormat(DXGI_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16_UNORM);
AddColorFormat(DXGI_FORMAT_R16G16_UINT, VK_FORMAT_R16G16_UINT);
AddColorFormat(DXGI_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16_SNORM);
AddColorFormat(DXGI_FORMAT_R16G16_SINT, VK_FORMAT_R16G16_SINT);
AddFormat(DXGI_FORMAT_R16G16_TYPELESS, VK_FORMAT_R16G16_UINT);
AddFormat(DXGI_FORMAT_R16G16_FLOAT, VK_FORMAT_R16G16_SFLOAT);
AddFormat(DXGI_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16_UNORM);
AddFormat(DXGI_FORMAT_R16G16_UINT, VK_FORMAT_R16G16_UINT);
AddFormat(DXGI_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16_SNORM);
AddFormat(DXGI_FORMAT_R16G16_SINT, VK_FORMAT_R16G16_SINT);
AddColorFormat(DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_R32_UINT);
AddColorFormat(DXGI_FORMAT_R32_FLOAT, VK_FORMAT_R32_SFLOAT);
AddColorFormat(DXGI_FORMAT_R32_UINT, VK_FORMAT_R32_UINT);
AddColorFormat(DXGI_FORMAT_R32_SINT, VK_FORMAT_R32_SINT);
AddFormat(DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_R32_UINT);
AddFormat(DXGI_FORMAT_R32_FLOAT, VK_FORMAT_R32_SFLOAT);
AddFormat(DXGI_FORMAT_R32_UINT, VK_FORMAT_R32_UINT);
AddFormat(DXGI_FORMAT_R32_SINT, VK_FORMAT_R32_SINT);
AddColorFormat(DXGI_FORMAT_R8G8_TYPELESS, VK_FORMAT_R8G8_UINT);
AddColorFormat(DXGI_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8_UNORM);
AddColorFormat(DXGI_FORMAT_R8G8_UINT, VK_FORMAT_R8G8_UINT);
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);
AddFormat(DXGI_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8_UNORM);
AddFormat(DXGI_FORMAT_R8G8_UINT, VK_FORMAT_R8G8_UINT);
AddFormat(DXGI_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8_SNORM);
AddFormat(DXGI_FORMAT_R8G8_SINT, VK_FORMAT_R8G8_SINT);
AddColorFormat(DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_R16_UINT);
AddColorFormat(DXGI_FORMAT_R16_FLOAT, VK_FORMAT_R16_SFLOAT);
AddColorFormat(DXGI_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM);
AddColorFormat(DXGI_FORMAT_R16_UINT, VK_FORMAT_R16_UINT);
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);
AddFormat(DXGI_FORMAT_R16_FLOAT, VK_FORMAT_R16_SFLOAT);
AddFormat(DXGI_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM);
AddFormat(DXGI_FORMAT_R16_UINT, VK_FORMAT_R16_UINT);
AddFormat(DXGI_FORMAT_R16_SNORM, VK_FORMAT_R16_SNORM);
AddFormat(DXGI_FORMAT_R16_SINT, VK_FORMAT_R16_SINT);
AddColorFormat(DXGI_FORMAT_R8_TYPELESS, VK_FORMAT_R8_UINT);
AddColorFormat(DXGI_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM);
AddColorFormat(DXGI_FORMAT_R8_UINT, VK_FORMAT_R8_UINT);
AddColorFormat(DXGI_FORMAT_R8_SNORM, VK_FORMAT_R8_SNORM);
AddColorFormat(DXGI_FORMAT_R8_SINT, VK_FORMAT_R8_SINT);
AddFormat(DXGI_FORMAT_R8_TYPELESS, VK_FORMAT_R8_UINT);
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);
// AddColorFormat(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);
// AddFormat(DXGI_FORMAT_R8G8_B8G8_UNORM, VK_FORMAT_UNDEFINED);
AddFormat(DXGI_FORMAT_G8R8_G8B8_UNORM, VK_FORMAT_UNDEFINED);
AddColorFormat(DXGI_FORMAT_R9G9B9E5_SHAREDEXP, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32);
// AddColorFormat(DXGI_FORMAT_R8G8_B8G8_UNORM, VK_FORMAT_UNDEFINED);
// AddColorFormat(DXGI_FORMAT_G8R8_G8B8_UNORM, VK_FORMAT_UNDEFINED);
AddFormat(DXGI_FORMAT_BC1_TYPELESS, VK_FORMAT_BC1_RGBA_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC1_UNORM, VK_FORMAT_BC1_RGBA_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC1_UNORM_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK);
AddColorFormat(DXGI_FORMAT_B5G6R5_UNORM, VK_FORMAT_B5G6R5_UNORM_PACK16);
AddColorFormat(DXGI_FORMAT_B5G5R5A1_UNORM, VK_FORMAT_B5G5R5A1_UNORM_PACK16);
AddFormat(DXGI_FORMAT_BC2_TYPELESS, VK_FORMAT_BC2_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC2_UNORM, VK_FORMAT_BC2_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC2_UNORM_SRGB, VK_FORMAT_BC2_SRGB_BLOCK);
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);
AddColorFormat(DXGI_FORMAT_B8G8R8A8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM);
AddColorFormat(DXGI_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM);
AddColorFormat(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB);
// TODO implement component swizzle
AddFormat(DXGI_FORMAT_B8G8R8X8_UNORM, VK_FORMAT_B8G8R8A8_UNORM);
AddFormat(DXGI_FORMAT_B8G8R8X8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM);
AddFormat(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB);
AddColorFormat(DXGI_FORMAT_B8G8R8X8_UNORM, VK_FORMAT_B8G8R8A8_UNORM);
AddColorFormat(DXGI_FORMAT_B8G8R8X8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM);
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);
AddFormat(DXGI_FORMAT_BC6H_UF16, VK_FORMAT_BC6H_UFLOAT_BLOCK);
AddFormat(DXGI_FORMAT_BC6H_SF16, VK_FORMAT_BC6H_SFLOAT_BLOCK);
AddColorFormat(DXGI_FORMAT_BC2_TYPELESS, VK_FORMAT_BC2_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC2_UNORM, VK_FORMAT_BC2_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC2_UNORM_SRGB, VK_FORMAT_BC2_SRGB_BLOCK);
AddFormat(DXGI_FORMAT_BC7_TYPELESS, VK_FORMAT_BC7_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC7_UNORM, VK_FORMAT_BC7_UNORM_BLOCK);
AddFormat(DXGI_FORMAT_BC7_UNORM_SRGB, VK_FORMAT_BC7_SRGB_BLOCK);
AddColorFormat(DXGI_FORMAT_BC3_TYPELESS, VK_FORMAT_BC3_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC3_UNORM, VK_FORMAT_BC3_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC3_UNORM_SRGB, VK_FORMAT_BC3_SRGB_BLOCK);
AddFormat(
DXGI_FORMAT_D32_FLOAT,
VK_FORMAT_D32_SFLOAT, {
VK_FORMAT_D32_SFLOAT_S8_UINT,
},
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
AddColorFormat(DXGI_FORMAT_BC4_TYPELESS, VK_FORMAT_BC4_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC4_UNORM, VK_FORMAT_BC4_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC4_SNORM, VK_FORMAT_BC4_SNORM_BLOCK);
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);
AddColorFormat(DXGI_FORMAT_BC5_TYPELESS, VK_FORMAT_BC5_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC5_UNORM, VK_FORMAT_BC5_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC5_SNORM, VK_FORMAT_BC5_SNORM_BLOCK);
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);
// AddFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_UNDEFINED);
// AddFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_UNDEFINED);
AddColorFormat(DXGI_FORMAT_BC7_TYPELESS, VK_FORMAT_BC7_UNORM_BLOCK);
AddColorFormat(DXGI_FORMAT_BC7_UNORM, VK_FORMAT_BC7_UNORM_BLOCK);
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;
DxgiFormatPair STDMETHODCALLTYPE LookupFormat(
DXGI_FORMAT format) final;
DXGI_FORMAT format, DxgiFormatMode mode) final;
private:
using FormatMap = std::unordered_map<DXGI_FORMAT, DxgiFormatPair>;
Com<DxgiFactory> m_factory;
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,
VkFormat dstFormat);
void AddFormat(
void AddDepthFormat(
DXGI_FORMAT srcFormat,
VkFormat dstFormat,
const std::initializer_list<VkFormat>& fallbacks,
VkFormatFeatureFlags features);
VkFormat dstFormat);
void SetupFormatTable();

View File

@ -24,6 +24,20 @@ namespace dxvk {
VkFormat wanted = 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;
/**
* \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(
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
DxvkSwapchainProperties swapchainProperties;
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.height = bufferHeight;
@ -315,7 +315,7 @@ namespace dxvk {
DXGI_FORMAT bufferFormat) {
DxvkSwapchainProperties swapchainProperties;
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.height = bufferHeight;

View File

@ -331,7 +331,7 @@ namespace dxvk {
const Rc<DxvkImage> backBuffer = m_presenter->createBackBuffer(
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);
const Com<IDXGIImageResourcePrivate> resource