[d3d11] Added DXGI format properties

This commit is contained in:
Philip Rebohle 2017-12-20 14:54:24 +01:00
parent b4e10b7f06
commit 659ec7b59d
9 changed files with 153 additions and 54 deletions

View File

@ -161,10 +161,13 @@ namespace dxvk {
// Fill in the view info. The view type depends solely
// on the view dimension field in the view description,
// not on the resource type.
const DxgiFormatInfo formatInfo = m_dxgiAdapter
->LookupFormat(desc.Format, textureInfo.formatMode);
DxvkImageViewCreateInfo viewInfo;
viewInfo.format = m_dxgiAdapter->LookupFormat(
desc.Format, textureInfo.formatMode).actual;
viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask;
viewInfo.format = formatInfo.format;
viewInfo.aspect = formatInfo.aspect;
viewInfo.swizzle = formatInfo.swizzle;
switch (desc.ViewDimension) {
case D3D11_SRV_DIMENSION_TEXTURE1D:
@ -306,7 +309,7 @@ namespace dxvk {
// Fill in Vulkan image view info
DxvkImageViewCreateInfo viewInfo;
viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Color).actual;
viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Color).format;
viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask;
switch (desc.ViewDimension) {
@ -400,7 +403,7 @@ namespace dxvk {
// Fill in Vulkan image view info
DxvkImageViewCreateInfo viewInfo;
viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Depth).actual;
viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Depth).format;
viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask;
switch (desc.ViewDimension) {
@ -494,7 +497,7 @@ namespace dxvk {
attrib.location = entry->registerId;
attrib.binding = pInputElementDescs[i].InputSlot;
attrib.format = m_dxgiAdapter->LookupFormat(
pInputElementDescs[i].Format, DxgiFormatMode::Color).actual;
pInputElementDescs[i].Format, DxgiFormatMode::Color).format;
attrib.offset = pInputElementDescs[i].AlignedByteOffset;
// The application may choose to let the implementation
@ -886,7 +889,7 @@ namespace dxvk {
// We need to check whether the format is
VkFormat format = m_dxgiAdapter->LookupFormat(
Format, DxgiFormatMode::Any).actual;
Format, DxgiFormatMode::Any).format;
if (format == VK_FORMAT_UNDEFINED) {
Logger::err(str::format("D3D11: Unsupported format: ", Format));
@ -1024,7 +1027,7 @@ namespace dxvk {
}
DxgiFormatPair STDMETHODCALLTYPE D3D11Device::LookupFormat(
DxgiFormatInfo STDMETHODCALLTYPE D3D11Device::LookupFormat(
DXGI_FORMAT format,
DxgiFormatMode mode) const {
return m_dxgiAdapter->LookupFormat(format, mode);
@ -1382,7 +1385,7 @@ namespace dxvk {
HRESULT D3D11Device::GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const {
const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format, DxgiFormatMode::Any).actual;
const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format, DxgiFormatMode::Any).format;
const VkFormatProperties fmtInfo = m_dxvkAdapter->formatProperties(fmt);
if (fmt == VK_FORMAT_UNDEFINED)

View File

@ -228,7 +228,7 @@ namespace dxvk {
VkPipelineStageFlags GetEnabledShaderStages() const;
DxgiFormatPair STDMETHODCALLTYPE LookupFormat(
DxgiFormatInfo STDMETHODCALLTYPE LookupFormat(
DXGI_FORMAT format,
DxgiFormatMode mode) const;

View File

@ -24,7 +24,7 @@ namespace dxvk {
DxvkImageCreateInfo info;
info.type = VK_IMAGE_TYPE_2D;
info.format = pDevice->LookupFormat(
pDesc->Format, m_formatMode).actual;
pDesc->Format, m_formatMode).format;
info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
info.sampleCount = VK_SAMPLE_COUNT_1_BIT;
info.extent.width = pDesc->Width;

View File

@ -1253,6 +1253,13 @@ namespace dxvk {
sampledImageId, coord.id);
} break;
case DxbcOpcode::SampleC: {
result.id = m_module.opImageSampleDrefImplicitLod(
getVectorTypeId(result.type),
sampledImageId, coord.id,
referenceValue.id);
} break;
case DxbcOpcode::SampleClz: {
result.id = m_module.opImageSampleDrefExplicitLod(
getVectorTypeId(result.type),

View File

@ -138,7 +138,7 @@ namespace dxvk {
}
DxgiFormatPair STDMETHODCALLTYPE DxgiAdapter::LookupFormat(DXGI_FORMAT format, DxgiFormatMode mode) {
DxgiFormatInfo 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);
@ -153,26 +153,52 @@ namespace dxvk {
return depth->second;
}
return DxgiFormatPair();
Logger::err(str::format("DxgiAdapter: No format mapping for ", format));
return DxgiFormatInfo();
}
void DxgiAdapter::AddColorFormat(
DXGI_FORMAT srcFormat,
VkFormat dstFormat) {
DxgiFormatPair formatPair;
formatPair.wanted = dstFormat;
formatPair.actual = dstFormat;
DxgiFormatInfo formatPair;
formatPair.format = dstFormat;
formatPair.aspect = VK_IMAGE_ASPECT_COLOR_BIT;
formatPair.swizzle = {
VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY,
};
m_colorFormats.insert(std::make_pair(srcFormat, formatPair));
}
void DxgiAdapter::AddColorFormat(
DXGI_FORMAT srcFormat,
VkFormat dstFormat,
VkComponentMapping swizzle) {
DxgiFormatInfo formatPair;
formatPair.format = dstFormat;
formatPair.aspect = VK_IMAGE_ASPECT_COLOR_BIT;
formatPair.swizzle = swizzle;
m_colorFormats.insert(std::make_pair(srcFormat, formatPair));
}
void DxgiAdapter::AddDepthFormat(
DXGI_FORMAT srcFormat,
VkFormat dstFormat) {
DxgiFormatPair formatPair;
formatPair.wanted = dstFormat;
formatPair.actual = dstFormat;
VkFormat dstFormat,
VkImageAspectFlags srvAspect) {
DxgiFormatInfo formatPair;
formatPair.format = dstFormat;
formatPair.aspect = srvAspect;
formatPair.swizzle = {
VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY,
};
m_depthFormats.insert(std::make_pair(srcFormat, formatPair));
}
@ -263,10 +289,18 @@ namespace dxvk {
AddColorFormat(DXGI_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM);
AddColorFormat(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB);
// TODO implement component swizzle
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_B8G8R8X8_UNORM, VK_FORMAT_B8G8R8A8_UNORM,
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE });
AddColorFormat(DXGI_FORMAT_B8G8R8X8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM,
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE });
AddColorFormat(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB,
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE });
// AddColorFormat(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, VK_FORMAT_UNDEFINED);
/***********************************************************************************/
@ -301,30 +335,32 @@ namespace dxvk {
/***********************************************************************************/
/* 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_D16_UNORM, VK_FORMAT_D16_UNORM, 0);
AddDepthFormat(DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_D16_UNORM, 0);
AddDepthFormat(DXGI_FORMAT_R16_UNORM, VK_FORMAT_D16_UNORM, VK_IMAGE_ASPECT_DEPTH_BIT);
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, VK_FORMAT_D32_SFLOAT, 0);
AddDepthFormat(DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_D32_SFLOAT, 0);
AddDepthFormat(DXGI_FORMAT_R32_FLOAT, VK_FORMAT_D32_SFLOAT, VK_IMAGE_ASPECT_DEPTH_BIT);
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);
AddDepthFormat(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 0);
AddDepthFormat(DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 0);
AddDepthFormat(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT);
AddDepthFormat(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_STENCIL_BIT);
// 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);
AddDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, 0);
AddDepthFormat(DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, 0);
AddDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT);
AddDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_ASPECT_STENCIL_BIT);
} 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);
AddDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 0);
AddDepthFormat(DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 0);
AddDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT);
AddDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_STENCIL_BIT);
}
}
@ -332,7 +368,7 @@ namespace dxvk {
bool DxgiAdapter::HasFormatSupport(
VkFormat format,
VkFormatFeatureFlags features) const {
VkFormatProperties info = m_adapter->formatProperties(format);
const VkFormatProperties info = m_adapter->formatProperties(format);
return ((info.optimalTilingFeatures | info.bufferFeatures) & features) == features;
}

View File

@ -48,12 +48,12 @@ namespace dxvk {
Rc<DxvkAdapter> STDMETHODCALLTYPE GetDXVKAdapter() final;
DxgiFormatPair STDMETHODCALLTYPE LookupFormat(
DxgiFormatInfo STDMETHODCALLTYPE LookupFormat(
DXGI_FORMAT format, DxgiFormatMode mode) final;
private:
using FormatMap = std::unordered_map<DXGI_FORMAT, DxgiFormatPair>;
using FormatMap = std::unordered_map<DXGI_FORMAT, DxgiFormatInfo>;
Com<DxgiFactory> m_factory;
Rc<DxvkAdapter> m_adapter;
@ -65,9 +65,15 @@ namespace dxvk {
DXGI_FORMAT srcFormat,
VkFormat dstFormat);
void AddColorFormat(
DXGI_FORMAT srcFormat,
VkFormat dstFormat,
VkComponentMapping swizzle);
void AddDepthFormat(
DXGI_FORMAT srcFormat,
VkFormat dstFormat);
VkFormat dstFormat,
VkImageAspectFlags srvAspect);
void SetupFormatTable();

View File

@ -12,17 +12,17 @@ namespace dxvk {
class DxvkImage;
/**
* \brief Format pair
* \brief Format info
*
* 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.
* Stores a Vulkan image format for a given
* DXGI format and some additional information
* on how resources with the particular format
* are supposed to be used.
*/
struct DxgiFormatPair {
VkFormat wanted = VK_FORMAT_UNDEFINED;
VkFormat actual = VK_FORMAT_UNDEFINED;
struct DxgiFormatInfo {
VkFormat format;
VkImageAspectFlags aspect;
VkComponentMapping swizzle;
};
/**
@ -64,7 +64,7 @@ IDXGIAdapterPrivate : public IDXGIAdapter1 {
* \param [in] mode Format lookup mode
* \returns Vulkan format pair
*/
virtual dxvk::DxgiFormatPair STDMETHODCALLTYPE LookupFormat(
virtual dxvk::DxgiFormatInfo STDMETHODCALLTYPE LookupFormat(
DXGI_FORMAT format,
dxvk::DxgiFormatMode mode) = 0;
};

View File

@ -1533,6 +1533,41 @@ namespace dxvk {
}
uint32_t SpirvModule::opImageSampleExplicitLod(
uint32_t resultType,
uint32_t sampledImage,
uint32_t coordinates,
uint32_t lod) {
uint32_t resultId = this->allocateId();
m_code.putIns (spv::OpImageSampleExplicitLod, 7);
m_code.putWord(resultType);
m_code.putWord(resultId);
m_code.putWord(sampledImage);
m_code.putWord(coordinates);
m_code.putWord(spv::ImageOperandsLodMask);
m_code.putWord(lod);
return resultId;
}
uint32_t SpirvModule::opImageSampleDrefImplicitLod(
uint32_t resultType,
uint32_t sampledImage,
uint32_t coordinates,
uint32_t reference) {
uint32_t resultId = this->allocateId();
m_code.putIns (spv::OpImageSampleDrefImplicitLod, 6);
m_code.putWord(resultType);
m_code.putWord(resultId);
m_code.putWord(sampledImage);
m_code.putWord(coordinates);
m_code.putWord(reference);
return resultId;
}
uint32_t SpirvModule::opImageSampleDrefExplicitLod(
uint32_t resultType,
uint32_t sampledImage,

View File

@ -520,6 +520,18 @@ namespace dxvk {
uint32_t sampledImage,
uint32_t coordinates);
uint32_t opImageSampleExplicitLod(
uint32_t resultType,
uint32_t sampledImage,
uint32_t coordinates,
uint32_t lod);
uint32_t opImageSampleDrefImplicitLod(
uint32_t resultType,
uint32_t sampledImage,
uint32_t coordinates,
uint32_t reference);
uint32_t opImageSampleDrefExplicitLod(
uint32_t resultType,
uint32_t sampledImage,