Skip to content

Commit

Permalink
[dxgi] Use per-adapter format lookup tables
Browse files Browse the repository at this point in the history
Allows Nvidia cards to use 24-bit depth buffers.
  • Loading branch information
doitsujin committed May 6, 2018
1 parent fb3dbd8 commit 757be61
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 30 deletions.
5 changes: 3 additions & 2 deletions src/dxgi/dxgi_adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ namespace dxvk {
DxgiFactory* factory,
const Rc<DxvkAdapter>& adapter)
: m_factory (factory),
m_adapter (adapter) {
m_adapter (adapter),
m_formats (adapter) {

}

Expand Down Expand Up @@ -191,7 +192,7 @@ namespace dxvk {
DXGI_VK_FORMAT_INFO STDMETHODCALLTYPE DxgiAdapter::LookupFormat(
DXGI_FORMAT Format,
DXGI_VK_FORMAT_MODE Mode) {
return GetDXGIFormatInfo(Format, Mode);
return m_formats.GetFormatInfo(Format, Mode);
}


Expand Down
10 changes: 4 additions & 6 deletions src/dxgi/dxgi_adapter.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
#pragma once

#include <initializer_list>
#include <memory>
#include <mutex>
#include <unordered_map>
#include <vector>
#include <string>

#include <dxvk_adapter.h>

#include "dxgi_format.h"
#include "dxgi_interfaces.h"
#include "dxgi_output.h"

Expand Down Expand Up @@ -77,6 +73,8 @@ namespace dxvk {
Com<DxgiFactory> m_factory;
Rc<DxvkAdapter> m_adapter;

DXGIVkFormatTable m_formats;

std::mutex m_outputMutex;
OutputMap m_outputData;

Expand Down
61 changes: 47 additions & 14 deletions src/dxgi/dxgi_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,21 +216,21 @@ namespace dxvk {
VK_IMAGE_ASPECT_COLOR_BIT },
// DXGI_FORMAT_R24G8_TYPELESS
{ VK_FORMAT_UNDEFINED,
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_UNDEFINED },
// DXGI_FORMAT_D24_UNORM_S8_UINT
{ VK_FORMAT_UNDEFINED,
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_UNDEFINED,
0, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT },
// DXGI_FORMAT_R24_UNORM_X8_TYPELESS
{ VK_FORMAT_UNDEFINED,
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_UNDEFINED,
0, VK_IMAGE_ASPECT_DEPTH_BIT },
// DXGI_FORMAT_X24_TYPELESS_G8_UINT
{ VK_FORMAT_UNDEFINED,
VK_FORMAT_D32_SFLOAT_S8_UINT,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_UNDEFINED,
0, VK_IMAGE_ASPECT_STENCIL_BIT },
// DXGI_FORMAT_R8G8_TYPELESS
Expand Down Expand Up @@ -533,21 +533,36 @@ namespace dxvk {
}};


const DXGI_VK_FORMAT_MAPPING& GetDXGIFormatMapping(
DXGI_FORMAT Format) {
const size_t formatId = size_t(Format);
DXGIVkFormatTable::DXGIVkFormatTable(const Rc<DxvkAdapter>& adapter)
: m_dxgiFormats(g_dxgiFormats) {
// AMD do not support 24-bit depth buffers on Vulkan,
// so we have to fall back to a 32-bit depth format.
if (!CheckImageFormatSupport(adapter, VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
Logger::warn("DXGI: VK_FORMAT_D24_UNORM_S8_UINT -> VK_FORMAT_D32_SFLOAT_S8_UINT");
RemapDepthFormat(DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT);
RemapDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT);
RemapDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT);
RemapDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT);
}
}


DXGIVkFormatTable::~DXGIVkFormatTable() {

return formatId < g_dxgiFormats.size()
? g_dxgiFormats[formatId]
: g_dxgiFormats[0];
}


DXGI_VK_FORMAT_INFO GetDXGIFormatInfo(
DXGI_VK_FORMAT_INFO DXGIVkFormatTable::GetFormatInfo(
DXGI_FORMAT Format,
DXGI_VK_FORMAT_MODE Mode) {
DXGI_VK_FORMAT_MODE Mode) const {
const size_t formatId = size_t(Format);

const DXGI_VK_FORMAT_MAPPING& mapping
= GetDXGIFormatMapping(Format);
= formatId < m_dxgiFormats.size()
? m_dxgiFormats[formatId]
: m_dxgiFormats[0];

switch (Mode) {
case DXGI_VK_FORMAT_MODE_ANY:
Expand All @@ -565,8 +580,26 @@ namespace dxvk {
return { mapping.FormatRaw, mapping.AspectColor };
}

Logger::err("DXGI: GetDXGIFormatInfo: Internal error");
Logger::err("DXGI: GetFormatInfo: Internal error");
return DXGI_VK_FORMAT_INFO();
}


bool DXGIVkFormatTable::CheckImageFormatSupport(
const Rc<DxvkAdapter>& Adapter,
VkFormat Format,
VkFormatFeatureFlags Features) const {
VkFormatProperties supported = Adapter->formatProperties(VK_FORMAT_D24_UNORM_S8_UINT);

return (supported.linearTilingFeatures & Features) == Features
|| (supported.optimalTilingFeatures & Features) == Features;
}


void DXGIVkFormatTable::RemapDepthFormat(
DXGI_FORMAT Format,
VkFormat Target) {
m_dxgiFormats[uint32_t(Format)].FormatDepth = Target;
}

}
47 changes: 39 additions & 8 deletions src/dxgi/dxgi_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include "dxgi_include.h"

#include "../dxvk/dxvk_include.h"
#include "../dxvk/dxvk_adapter.h"

namespace dxvk {

Expand Down Expand Up @@ -53,15 +53,46 @@ namespace dxvk {
DXGI_VK_FORMAT_MODE_RAW = 3, ///< Unsigned integer format
};


/**
* \brief Retrieves info for a given DXGI format
* \brief Format table
*
* \param [in] Format The DXGI format to look up
* \param [in] Mode the format lookup mode
* \returns Format info
* Initializes a format table for a specific
* device and provides methods to look up
* formats.
*/
DXGI_VK_FORMAT_INFO GetDXGIFormatInfo(
DXGI_FORMAT Format,
DXGI_VK_FORMAT_MODE Mode);
class DXGIVkFormatTable {

public:

DXGIVkFormatTable(
const Rc<DxvkAdapter>& adapter);
~DXGIVkFormatTable();

/**
* \brief Retrieves info for a given DXGI format
*
* \param [in] Format The DXGI format to look up
* \param [in] Mode the format lookup mode
* \returns Format info
*/
DXGI_VK_FORMAT_INFO GetFormatInfo(
DXGI_FORMAT Format,
DXGI_VK_FORMAT_MODE Mode) const;

private:

std::array<DXGI_VK_FORMAT_MAPPING, 133> m_dxgiFormats;

bool CheckImageFormatSupport(
const Rc<DxvkAdapter>& Adapter,
VkFormat Format,
VkFormatFeatureFlags Features) const;

void RemapDepthFormat(
DXGI_FORMAT Format,
VkFormat Target);

};

};

0 comments on commit 757be61

Please sign in to comment.