2017-11-27 15:52:24 +01:00
|
|
|
#include "d3d11_device.h"
|
2019-06-15 10:28:49 +02:00
|
|
|
#include "d3d11_gdi.h"
|
2017-11-27 15:52:24 +01:00
|
|
|
#include "d3d11_texture.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
2018-03-14 01:16:31 +01:00
|
|
|
D3D11CommonTexture::D3D11CommonTexture(
|
|
|
|
D3D11Device* pDevice,
|
|
|
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
2020-12-29 22:39:04 +01:00
|
|
|
D3D11_RESOURCE_DIMENSION Dimension,
|
2021-02-12 01:52:20 +01:00
|
|
|
DXGI_USAGE DxgiUsage,
|
2020-12-29 22:39:04 +01:00
|
|
|
VkImage vkImage)
|
2021-06-21 22:53:13 +02:00
|
|
|
: m_device(pDevice), m_dimension(Dimension), m_desc(*pDesc), m_dxgiUsage(DxgiUsage) {
|
2018-07-03 12:44:56 +02:00
|
|
|
DXGI_VK_FORMAT_MODE formatMode = GetFormatMode();
|
|
|
|
DXGI_VK_FORMAT_INFO formatInfo = m_device->LookupFormat(m_desc.Format, formatMode);
|
|
|
|
DXGI_VK_FORMAT_FAMILY formatFamily = m_device->LookupFamily(m_desc.Format, formatMode);
|
2021-06-22 04:09:07 +02:00
|
|
|
DXGI_VK_FORMAT_INFO formatPacked = m_device->LookupPackedFormat(m_desc.Format, formatMode);
|
|
|
|
m_packedFormat = formatPacked.Format;
|
2018-07-03 12:44:56 +02:00
|
|
|
|
2018-03-14 01:16:31 +01:00
|
|
|
DxvkImageCreateInfo imageInfo;
|
2021-06-22 08:04:21 +02:00
|
|
|
imageInfo.type = GetVkImageType();
|
2018-07-03 12:44:56 +02:00
|
|
|
imageInfo.format = formatInfo.Format;
|
|
|
|
imageInfo.flags = 0;
|
|
|
|
imageInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
imageInfo.extent.width = m_desc.Width;
|
|
|
|
imageInfo.extent.height = m_desc.Height;
|
|
|
|
imageInfo.extent.depth = m_desc.Depth;
|
|
|
|
imageInfo.numLayers = m_desc.ArraySize;
|
|
|
|
imageInfo.mipLevels = m_desc.MipLevels;
|
|
|
|
imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT
|
|
|
|
| VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
|
|
|
imageInfo.stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
|
|
|
imageInfo.access = VK_ACCESS_TRANSFER_READ_BIT
|
|
|
|
| VK_ACCESS_TRANSFER_WRITE_BIT;
|
|
|
|
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
|
|
imageInfo.layout = VK_IMAGE_LAYOUT_GENERAL;
|
2019-09-19 18:22:04 +02:00
|
|
|
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
2021-02-14 03:42:12 +01:00
|
|
|
imageInfo.shared = vkImage != VK_NULL_HANDLE;
|
2018-06-28 16:47:54 +02:00
|
|
|
|
2018-05-05 20:16:01 +02:00
|
|
|
DecodeSampleCount(m_desc.SampleDesc.Count, &imageInfo.sampleCount);
|
2018-08-09 17:13:35 +02:00
|
|
|
|
2018-07-03 13:31:22 +02:00
|
|
|
// Integer clear operations on UAVs are implemented using
|
|
|
|
// a view with a bit-compatible integer format, so we'll
|
|
|
|
// have to include that format in the format family
|
2018-07-03 12:44:56 +02:00
|
|
|
if (m_desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS) {
|
2018-07-03 13:31:22 +02:00
|
|
|
DXGI_VK_FORMAT_INFO formatBase = m_device->LookupFormat(
|
|
|
|
m_desc.Format, DXGI_VK_FORMAT_MODE_RAW);
|
|
|
|
|
|
|
|
if (formatBase.Format != formatInfo.Format
|
|
|
|
&& formatBase.Format != VK_FORMAT_UNDEFINED) {
|
|
|
|
formatFamily.Add(formatBase.Format);
|
|
|
|
formatFamily.Add(formatInfo.Format);
|
|
|
|
}
|
2018-07-03 12:44:56 +02:00
|
|
|
}
|
2018-06-24 17:01:05 +02:00
|
|
|
|
2018-07-03 13:31:22 +02:00
|
|
|
// The image must be marked as mutable if it can be reinterpreted
|
|
|
|
// by a view with a different format. Depth-stencil formats cannot
|
|
|
|
// be reinterpreted in Vulkan, so we'll ignore those.
|
2018-08-09 17:13:35 +02:00
|
|
|
auto formatProperties = imageFormatInfo(formatInfo.Format);
|
2018-05-05 00:49:23 +02:00
|
|
|
|
2018-07-03 13:31:22 +02:00
|
|
|
bool isTypeless = formatInfo.Aspect == 0;
|
|
|
|
bool isMutable = formatFamily.FormatCount > 1;
|
2021-05-14 12:33:10 +02:00
|
|
|
bool isMultiPlane = (formatProperties->aspectMask & VK_IMAGE_ASPECT_PLANE_0_BIT) != 0;
|
2018-09-29 14:59:36 +02:00
|
|
|
bool isColorFormat = (formatProperties->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) != 0;
|
2018-07-03 13:31:22 +02:00
|
|
|
|
2021-05-14 12:33:10 +02:00
|
|
|
if (isMutable && (isColorFormat || isMultiPlane)) {
|
2018-09-27 11:32:23 +02:00
|
|
|
imageInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
|
2018-07-03 13:31:22 +02:00
|
|
|
|
|
|
|
// Typeless UAV images have relaxed reinterpretation rules
|
|
|
|
if (!isTypeless || !(m_desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS)) {
|
|
|
|
imageInfo.viewFormatCount = formatFamily.FormatCount;
|
|
|
|
imageInfo.viewFormats = formatFamily.Formats;
|
|
|
|
}
|
|
|
|
}
|
2018-08-09 17:13:35 +02:00
|
|
|
|
|
|
|
// Some games will try to create an SRGB image with the UAV
|
|
|
|
// bind flag set. This works on Windows, but no UAVs can be
|
|
|
|
// created for the image in practice.
|
|
|
|
bool noUav = formatProperties->flags.test(DxvkFormatFlag::ColorSpaceSrgb)
|
|
|
|
&& !CheckFormatFeatureSupport(formatInfo.Format, VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT);
|
2018-05-05 00:49:23 +02:00
|
|
|
|
2018-03-14 16:03:48 +01:00
|
|
|
// Adjust image flags based on the corresponding D3D flags
|
2018-03-14 01:16:31 +01:00
|
|
|
if (m_desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) {
|
|
|
|
imageInfo.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
|
|
imageInfo.stages |= pDevice->GetEnabledShaderStages();
|
|
|
|
imageInfo.access |= VK_ACCESS_SHADER_READ_BIT;
|
2017-12-23 17:05:07 +01:00
|
|
|
}
|
|
|
|
|
2019-01-22 14:52:35 +01:00
|
|
|
if (m_desc.BindFlags & D3D11_BIND_RENDER_TARGET) {
|
2018-03-14 01:16:31 +01:00
|
|
|
imageInfo.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
2019-01-22 14:52:35 +01:00
|
|
|
imageInfo.stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
|
|
imageInfo.access |= VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
|
|
|
| VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
|
|
}
|
2017-12-23 17:05:07 +01:00
|
|
|
|
2019-01-22 14:52:35 +01:00
|
|
|
if (m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) {
|
2018-03-14 01:16:31 +01:00
|
|
|
imageInfo.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
2019-01-22 14:52:35 +01:00
|
|
|
imageInfo.stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
|
|
|
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
|
|
|
|
imageInfo.access |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
|
|
|
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
|
|
|
}
|
2017-12-23 17:05:07 +01:00
|
|
|
|
2018-08-09 17:13:35 +02:00
|
|
|
if (m_desc.BindFlags & D3D11_BIND_UNORDERED_ACCESS && !noUav) {
|
2018-03-14 01:16:31 +01:00
|
|
|
imageInfo.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
|
|
|
|
imageInfo.stages |= pDevice->GetEnabledShaderStages();
|
|
|
|
imageInfo.access |= VK_ACCESS_SHADER_READ_BIT
|
2018-03-14 14:49:45 +01:00
|
|
|
| VK_ACCESS_SHADER_WRITE_BIT;
|
2017-12-23 17:05:07 +01:00
|
|
|
}
|
2021-05-14 12:33:10 +02:00
|
|
|
|
|
|
|
// Multi-plane formats need views to be created with color formats, and
|
|
|
|
// may not report all relevant usage flags as supported on their own.
|
|
|
|
// Also, enable sampled bit to enable use with video processor APIs.
|
|
|
|
if (isMultiPlane) {
|
|
|
|
imageInfo.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
|
|
imageInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
|
|
|
|
| VK_IMAGE_CREATE_EXTENDED_USAGE_BIT;
|
|
|
|
}
|
2017-12-23 17:05:07 +01:00
|
|
|
|
2018-06-28 16:47:54 +02:00
|
|
|
// Access pattern for meta-resolve operations
|
2018-09-29 14:59:36 +02:00
|
|
|
if (imageInfo.sampleCount != VK_SAMPLE_COUNT_1_BIT && isColorFormat) {
|
2018-06-28 16:47:54 +02:00
|
|
|
imageInfo.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
|
|
imageInfo.stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
|
|
imageInfo.access |= VK_ACCESS_SHADER_READ_BIT;
|
|
|
|
}
|
|
|
|
|
2018-03-14 14:40:09 +01:00
|
|
|
if (m_desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE)
|
|
|
|
imageInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
|
|
|
|
2019-01-02 17:32:43 +01:00
|
|
|
if (Dimension == D3D11_RESOURCE_DIMENSION_TEXTURE3D &&
|
|
|
|
(m_desc.BindFlags & D3D11_BIND_RENDER_TARGET))
|
2020-01-16 20:13:06 +01:00
|
|
|
imageInfo.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
|
2018-03-14 20:40:11 +01:00
|
|
|
|
2021-02-12 03:11:38 +01:00
|
|
|
// Swap chain back buffers need to be shader readable
|
|
|
|
if (DxgiUsage & DXGI_USAGE_BACK_BUFFER) {
|
|
|
|
imageInfo.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
|
|
imageInfo.stages |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
|
|
|
imageInfo.access |= VK_ACCESS_SHADER_READ_BIT;
|
2021-02-14 03:42:12 +01:00
|
|
|
imageInfo.shared = VK_TRUE;
|
2021-02-12 03:11:38 +01:00
|
|
|
}
|
|
|
|
|
2018-04-29 14:43:24 +02:00
|
|
|
// Some image formats (i.e. the R32G32B32 ones) are
|
|
|
|
// only supported with linear tiling on most GPUs
|
|
|
|
if (!CheckImageSupport(&imageInfo, VK_IMAGE_TILING_OPTIMAL))
|
|
|
|
imageInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
2018-03-14 16:03:48 +01:00
|
|
|
|
|
|
|
// Determine map mode based on our findings
|
|
|
|
m_mapMode = DetermineMapMode(&imageInfo);
|
|
|
|
|
2018-03-14 14:49:45 +01:00
|
|
|
// If the image is mapped directly to host memory, we need
|
|
|
|
// to enable linear tiling, and DXVK needs to be aware that
|
|
|
|
// the image can be accessed by the host.
|
2018-03-14 14:40:09 +01:00
|
|
|
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
|
2019-09-19 18:22:04 +02:00
|
|
|
imageInfo.tiling = VK_IMAGE_TILING_LINEAR;
|
|
|
|
imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
|
2017-12-23 17:05:07 +01:00
|
|
|
}
|
|
|
|
|
2021-06-21 22:53:13 +02:00
|
|
|
// If necessary, create the mapped linear buffer
|
|
|
|
if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) {
|
|
|
|
for (uint32_t i = 0; i < m_desc.ArraySize; i++) {
|
|
|
|
for (uint32_t j = 0; j < m_desc.MipLevels; j++) {
|
|
|
|
if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
|
|
|
|
m_buffers.push_back(CreateMappedBuffer(j));
|
|
|
|
|
|
|
|
m_mapTypes.push_back(D3D11_MAP(~0u));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Skip image creation if possible
|
|
|
|
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_STAGING)
|
|
|
|
return;
|
|
|
|
|
2018-03-14 14:49:45 +01:00
|
|
|
// We must keep LINEAR images in GENERAL layout, but we
|
|
|
|
// can choose a better layout for the image based on how
|
|
|
|
// it is going to be used by the game.
|
2021-05-14 12:33:10 +02:00
|
|
|
if (imageInfo.tiling == VK_IMAGE_TILING_OPTIMAL && !isMultiPlane)
|
2018-03-14 01:16:31 +01:00
|
|
|
imageInfo.layout = OptimizeLayout(imageInfo.usage);
|
2018-09-27 11:32:23 +02:00
|
|
|
|
|
|
|
// For some formats, we need to enable sampled and/or
|
|
|
|
// render target capabilities if available, but these
|
|
|
|
// should in no way affect the default image layout
|
|
|
|
imageInfo.usage |= EnableMetaCopyUsage(imageInfo.format, imageInfo.tiling);
|
2018-11-08 18:06:04 +01:00
|
|
|
imageInfo.usage |= EnableMetaPackUsage(imageInfo.format, m_desc.CPUAccessFlags);
|
2017-12-19 16:01:50 +01:00
|
|
|
|
2018-04-29 14:43:24 +02:00
|
|
|
// Check if we can actually create the image
|
|
|
|
if (!CheckImageSupport(&imageInfo, imageInfo.tiling)) {
|
|
|
|
throw DxvkError(str::format(
|
|
|
|
"D3D11: Cannot create texture:",
|
2019-01-08 10:34:48 +01:00
|
|
|
"\n Format: ", m_desc.Format,
|
|
|
|
"\n Extent: ", m_desc.Width,
|
|
|
|
"x", m_desc.Height,
|
|
|
|
"x", m_desc.Depth,
|
|
|
|
"\n Samples: ", m_desc.SampleDesc.Count,
|
|
|
|
"\n Layers: ", m_desc.ArraySize,
|
|
|
|
"\n Levels: ", m_desc.MipLevels,
|
|
|
|
"\n Usage: ", std::hex, m_desc.BindFlags,
|
|
|
|
"\n Flags: ", std::hex, m_desc.MiscFlags));
|
2018-04-29 14:43:24 +02:00
|
|
|
}
|
|
|
|
|
2018-03-14 16:03:48 +01:00
|
|
|
// Create the image on a host-visible memory type
|
|
|
|
// in case it is going to be mapped directly.
|
|
|
|
VkMemoryPropertyFlags memoryProperties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
|
|
|
|
|
|
|
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
|
|
|
|
memoryProperties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
2019-04-07 14:42:01 +02:00
|
|
|
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
|
|
|
| VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
2018-03-14 16:03:48 +01:00
|
|
|
}
|
|
|
|
|
2020-12-29 22:39:04 +01:00
|
|
|
if (vkImage == VK_NULL_HANDLE)
|
|
|
|
m_image = m_device->GetDXVKDevice()->createImage(imageInfo, memoryProperties);
|
|
|
|
else
|
|
|
|
m_image = m_device->GetDXVKDevice()->createImageFromVkImage(imageInfo, vkImage);
|
2018-03-13 23:51:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11CommonTexture::~D3D11CommonTexture() {
|
|
|
|
|
2017-12-23 17:05:07 +01:00
|
|
|
}
|
|
|
|
|
2018-03-13 23:51:30 +01:00
|
|
|
|
2021-06-22 06:45:37 +02:00
|
|
|
VkDeviceSize D3D11CommonTexture::ComputeMappedOffset(UINT Subresource, UINT Plane, VkOffset3D Offset) const {
|
|
|
|
auto packedFormatInfo = imageFormatInfo(m_packedFormat);
|
|
|
|
|
|
|
|
VkImageAspectFlags aspectMask = packedFormatInfo->aspectMask;
|
|
|
|
VkDeviceSize elementSize = packedFormatInfo->elementSize;
|
|
|
|
|
|
|
|
if (packedFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) {
|
|
|
|
auto plane = &packedFormatInfo->planes[Plane];
|
|
|
|
elementSize = plane->elementSize;
|
|
|
|
Offset.x /= plane->blockSize.width;
|
|
|
|
Offset.y /= plane->blockSize.height;
|
|
|
|
aspectMask = vk::getPlaneAspect(Plane);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto layout = GetSubresourceLayout(aspectMask, Subresource);
|
|
|
|
auto blockOffset = util::computeBlockOffset(Offset, packedFormatInfo->blockSize);
|
|
|
|
|
|
|
|
return VkDeviceSize(blockOffset.z) * layout.DepthPitch
|
|
|
|
+ VkDeviceSize(blockOffset.y) * layout.RowPitch
|
|
|
|
+ VkDeviceSize(blockOffset.x) * elementSize
|
|
|
|
+ VkDeviceSize(layout.Offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-13 23:51:30 +01:00
|
|
|
VkImageSubresource D3D11CommonTexture::GetSubresourceFromIndex(
|
|
|
|
VkImageAspectFlags Aspect,
|
2018-03-14 00:45:07 +01:00
|
|
|
UINT Subresource) const {
|
2018-03-13 23:51:30 +01:00
|
|
|
VkImageSubresource result;
|
|
|
|
result.aspectMask = Aspect;
|
|
|
|
result.mipLevel = Subresource % m_desc.MipLevels;
|
|
|
|
result.arrayLayer = Subresource / m_desc.MipLevels;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-19 17:01:07 +02:00
|
|
|
D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT D3D11CommonTexture::GetSubresourceLayout(
|
2021-06-22 06:45:37 +02:00
|
|
|
VkImageAspectFlags AspectMask,
|
2021-05-19 17:01:07 +02:00
|
|
|
UINT Subresource) const {
|
2021-06-22 06:45:37 +02:00
|
|
|
VkImageSubresource subresource = GetSubresourceFromIndex(AspectMask, Subresource);
|
2021-05-19 17:01:07 +02:00
|
|
|
D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT layout = { };
|
|
|
|
|
|
|
|
switch (m_mapMode) {
|
|
|
|
case D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT: {
|
|
|
|
auto vkLayout = m_image->querySubresourceLayout(subresource);
|
|
|
|
layout.Offset = vkLayout.offset;
|
|
|
|
layout.Size = vkLayout.size;
|
|
|
|
layout.RowPitch = vkLayout.rowPitch;
|
|
|
|
layout.DepthPitch = vkLayout.depthPitch;
|
|
|
|
} break;
|
|
|
|
|
2021-06-21 22:53:13 +02:00
|
|
|
case D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER:
|
|
|
|
case D3D11_COMMON_TEXTURE_MAP_MODE_STAGING: {
|
2021-06-22 06:45:37 +02:00
|
|
|
auto packedFormatInfo = imageFormatInfo(m_packedFormat);
|
2021-05-19 17:01:07 +02:00
|
|
|
|
2021-06-22 06:45:37 +02:00
|
|
|
VkImageAspectFlags aspects = packedFormatInfo->aspectMask;
|
2021-06-21 22:53:13 +02:00
|
|
|
VkExtent3D mipExtent = MipLevelExtent(subresource.mipLevel);
|
2021-05-19 17:01:07 +02:00
|
|
|
|
|
|
|
while (aspects) {
|
|
|
|
auto aspect = vk::getNextAspect(aspects);
|
|
|
|
auto extent = mipExtent;
|
2021-06-22 04:09:07 +02:00
|
|
|
auto elementSize = packedFormatInfo->elementSize;
|
2021-05-19 17:01:07 +02:00
|
|
|
|
2021-06-22 04:09:07 +02:00
|
|
|
if (packedFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) {
|
|
|
|
auto plane = &packedFormatInfo->planes[vk::getPlaneIndex(aspect)];
|
2021-05-19 17:01:07 +02:00
|
|
|
extent.width /= plane->blockSize.width;
|
|
|
|
extent.height /= plane->blockSize.height;
|
|
|
|
elementSize = plane->elementSize;
|
|
|
|
}
|
|
|
|
|
2021-06-22 04:09:07 +02:00
|
|
|
auto blockCount = util::computeBlockCount(extent, packedFormatInfo->blockSize);
|
2021-05-19 17:01:07 +02:00
|
|
|
|
|
|
|
if (!layout.RowPitch) {
|
|
|
|
layout.RowPitch = elementSize * blockCount.width;
|
|
|
|
layout.DepthPitch = elementSize * blockCount.width * blockCount.height;
|
|
|
|
}
|
|
|
|
|
2021-06-22 06:45:37 +02:00
|
|
|
VkDeviceSize size = elementSize * blockCount.width * blockCount.height * blockCount.depth;
|
|
|
|
|
|
|
|
if (aspect & AspectMask)
|
|
|
|
layout.Size += size;
|
|
|
|
else if (!layout.Size)
|
|
|
|
layout.Offset += size;
|
2021-05-19 17:01:07 +02:00
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
|
|
|
case D3D11_COMMON_TEXTURE_MAP_MODE_NONE:
|
|
|
|
break; /* no op */
|
|
|
|
}
|
|
|
|
|
|
|
|
// D3D wants us to return the total subresource size in some instances
|
2021-06-21 22:53:13 +02:00
|
|
|
if (m_dimension < D3D11_RESOURCE_DIMENSION_TEXTURE2D) layout.RowPitch = layout.Size;
|
|
|
|
if (m_dimension < D3D11_RESOURCE_DIMENSION_TEXTURE3D) layout.DepthPitch = layout.Size;
|
2021-05-19 17:01:07 +02:00
|
|
|
return layout;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-12 17:49:14 +02:00
|
|
|
DXGI_VK_FORMAT_MODE D3D11CommonTexture::GetFormatMode() const {
|
2018-03-13 23:51:30 +01:00
|
|
|
if (m_desc.BindFlags & D3D11_BIND_RENDER_TARGET)
|
2018-04-12 17:49:14 +02:00
|
|
|
return DXGI_VK_FORMAT_MODE_COLOR;
|
2018-03-13 23:51:30 +01:00
|
|
|
|
|
|
|
if (m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL)
|
2018-04-12 17:49:14 +02:00
|
|
|
return DXGI_VK_FORMAT_MODE_DEPTH;
|
2018-03-13 23:51:30 +01:00
|
|
|
|
2018-04-12 17:49:14 +02:00
|
|
|
return DXGI_VK_FORMAT_MODE_ANY;
|
2018-03-13 23:51:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-05-20 16:50:15 +02:00
|
|
|
uint32_t D3D11CommonTexture::GetPlaneCount() const {
|
|
|
|
return vk::getPlaneCount(m_image->formatInfo()->aspectMask);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool D3D11CommonTexture::CheckViewCompatibility(UINT BindFlags, DXGI_FORMAT Format, UINT Plane) const {
|
2018-08-09 23:34:03 +02:00
|
|
|
const DxvkImageCreateInfo& imageInfo = m_image->info();
|
|
|
|
|
2018-08-09 21:58:58 +02:00
|
|
|
// Check whether the given bind flags are supported
|
2020-03-08 01:26:25 +01:00
|
|
|
if ((m_desc.BindFlags & BindFlags) != BindFlags)
|
2018-08-09 21:58:58 +02:00
|
|
|
return false;
|
|
|
|
|
|
|
|
// Check whether the view format is compatible
|
2018-05-05 20:16:01 +02:00
|
|
|
DXGI_VK_FORMAT_MODE formatMode = GetFormatMode();
|
2018-08-09 21:58:58 +02:00
|
|
|
DXGI_VK_FORMAT_INFO viewFormat = m_device->LookupFormat(Format, formatMode);
|
2018-08-09 23:34:03 +02:00
|
|
|
DXGI_VK_FORMAT_INFO baseFormat = m_device->LookupFormat(m_desc.Format, formatMode);
|
2018-05-05 20:16:01 +02:00
|
|
|
|
2021-05-20 16:50:15 +02:00
|
|
|
// Check whether the plane index is valid for the given format
|
|
|
|
uint32_t planeCount = GetPlaneCount();
|
|
|
|
|
|
|
|
if (Plane >= planeCount)
|
|
|
|
return false;
|
|
|
|
|
2018-08-09 23:34:03 +02:00
|
|
|
if (imageInfo.flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
|
|
|
|
// Check whether the given combination of image
|
|
|
|
// view type and view format is actually supported
|
|
|
|
VkFormatFeatureFlags features = GetImageFormatFeatures(BindFlags);
|
|
|
|
|
|
|
|
if (!CheckFormatFeatureSupport(viewFormat.Format, features))
|
|
|
|
return false;
|
|
|
|
|
2021-05-20 16:50:15 +02:00
|
|
|
// Using the image format itself is supported for non-planar formats
|
|
|
|
if (viewFormat.Format == baseFormat.Format && planeCount == 1)
|
2018-08-09 23:34:03 +02:00
|
|
|
return true;
|
|
|
|
|
2021-05-20 16:50:15 +02:00
|
|
|
// If there is a list of compatible formats, the view format must be
|
|
|
|
// included in that list. For planar formats, the list is laid out in
|
|
|
|
// such a way that the n-th format is supported for the n-th plane.
|
|
|
|
for (size_t i = Plane; i < imageInfo.viewFormatCount; i += planeCount) {
|
|
|
|
if (imageInfo.viewFormats[i] == viewFormat.Format) {
|
2018-08-09 23:34:03 +02:00
|
|
|
return true;
|
2021-05-20 16:50:15 +02:00
|
|
|
}
|
2018-08-09 23:34:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, all bit-compatible formats can be used.
|
2021-05-20 16:50:15 +02:00
|
|
|
if (imageInfo.viewFormatCount == 0 && planeCount == 1) {
|
2018-08-09 23:34:03 +02:00
|
|
|
auto baseFormatInfo = imageFormatInfo(baseFormat.Format);
|
|
|
|
auto viewFormatInfo = imageFormatInfo(viewFormat.Format);
|
|
|
|
|
|
|
|
return baseFormatInfo->aspectMask == viewFormatInfo->aspectMask
|
|
|
|
&& baseFormatInfo->elementSize == viewFormatInfo->elementSize;
|
|
|
|
}
|
|
|
|
|
2018-05-05 15:13:35 +02:00
|
|
|
return false;
|
2018-08-09 23:34:03 +02:00
|
|
|
} else {
|
|
|
|
// For non-mutable images, the view format
|
|
|
|
// must be identical to the image format.
|
2021-05-20 16:50:15 +02:00
|
|
|
return viewFormat.Format == baseFormat.Format && planeCount == 1;
|
2018-08-09 23:34:03 +02:00
|
|
|
}
|
2018-05-05 15:13:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-13 23:51:30 +01:00
|
|
|
HRESULT D3D11CommonTexture::NormalizeTextureProperties(D3D11_COMMON_TEXTURE_DESC* pDesc) {
|
2019-10-11 17:11:01 +02:00
|
|
|
if (pDesc->Width == 0 || pDesc->Height == 0 || pDesc->Depth == 0 || pDesc->ArraySize == 0)
|
2018-09-18 21:33:27 +02:00
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2018-04-13 13:46:45 +02:00
|
|
|
if (FAILED(DecodeSampleCount(pDesc->SampleDesc.Count, nullptr)))
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2019-06-15 10:28:49 +02:00
|
|
|
if ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE)
|
|
|
|
&& (pDesc->Usage == D3D11_USAGE_STAGING
|
|
|
|
|| (pDesc->Format != DXGI_FORMAT_B8G8R8A8_TYPELESS
|
|
|
|
&& pDesc->Format != DXGI_FORMAT_B8G8R8A8_UNORM
|
|
|
|
&& pDesc->Format != DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)))
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2019-06-13 02:57:56 +02:00
|
|
|
if ((pDesc->MiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS)
|
|
|
|
&& (pDesc->BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
|
|
|
|
!= (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2019-09-15 18:40:57 +02:00
|
|
|
// TILE_POOL is invalid, but we don't support TILED either
|
|
|
|
if (pDesc->MiscFlags & (D3D11_RESOURCE_MISC_TILE_POOL | D3D11_RESOURCE_MISC_TILED))
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2018-04-13 13:46:45 +02:00
|
|
|
// Use the maximum possible mip level count if the supplied
|
|
|
|
// mip level count is either unspecified (0) or invalid
|
|
|
|
const uint32_t maxMipLevelCount = pDesc->SampleDesc.Count <= 1
|
2018-04-12 23:42:11 +02:00
|
|
|
? util::computeMipLevelCount({ pDesc->Width, pDesc->Height, pDesc->Depth })
|
|
|
|
: 1u;
|
|
|
|
|
|
|
|
if (pDesc->MipLevels == 0 || pDesc->MipLevels > maxMipLevelCount)
|
|
|
|
pDesc->MipLevels = maxMipLevelCount;
|
2018-03-13 23:51:30 +01:00
|
|
|
|
2019-09-16 13:50:39 +02:00
|
|
|
// Row-major is only supported for textures with one single
|
|
|
|
// subresource and one sample and cannot have bind flags.
|
|
|
|
if (pDesc->TextureLayout == D3D11_TEXTURE_LAYOUT_ROW_MAJOR
|
|
|
|
&& (pDesc->MipLevels != 1 || pDesc->SampleDesc.Count != 1 || pDesc->BindFlags))
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
// Standard swizzle is unsupported
|
|
|
|
if (pDesc->TextureLayout == D3D11_TEXTURE_LAYOUT_64K_STANDARD_SWIZZLE)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
2018-03-13 23:51:30 +01:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-14 16:03:48 +01:00
|
|
|
BOOL D3D11CommonTexture::CheckImageSupport(
|
|
|
|
const DxvkImageCreateInfo* pImageInfo,
|
|
|
|
VkImageTiling Tiling) const {
|
|
|
|
const Rc<DxvkAdapter> adapter = m_device->GetDXVKDevice()->adapter();
|
|
|
|
|
2021-05-14 12:33:10 +02:00
|
|
|
VkImageUsageFlags usage = pImageInfo->usage;
|
|
|
|
|
|
|
|
if (pImageInfo->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT)
|
|
|
|
usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
|
|
|
|
2018-03-14 16:03:48 +01:00
|
|
|
VkImageFormatProperties formatProps = { };
|
|
|
|
VkResult status = adapter->imageFormatProperties(
|
|
|
|
pImageInfo->format, pImageInfo->type, Tiling,
|
2021-05-14 12:33:10 +02:00
|
|
|
usage, pImageInfo->flags, formatProps);
|
2018-03-14 16:03:48 +01:00
|
|
|
|
|
|
|
if (status != VK_SUCCESS)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return (pImageInfo->extent.width <= formatProps.maxExtent.width)
|
|
|
|
&& (pImageInfo->extent.height <= formatProps.maxExtent.height)
|
|
|
|
&& (pImageInfo->extent.depth <= formatProps.maxExtent.depth)
|
|
|
|
&& (pImageInfo->numLayers <= formatProps.maxArrayLayers)
|
|
|
|
&& (pImageInfo->mipLevels <= formatProps.maxMipLevels)
|
|
|
|
&& (pImageInfo->sampleCount & formatProps.sampleCounts);
|
|
|
|
}
|
2018-08-09 17:13:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
BOOL D3D11CommonTexture::CheckFormatFeatureSupport(
|
|
|
|
VkFormat Format,
|
|
|
|
VkFormatFeatureFlags Features) const {
|
|
|
|
VkFormatProperties properties = m_device->GetDXVKDevice()->adapter()->formatProperties(Format);
|
|
|
|
|
|
|
|
return (properties.linearTilingFeatures & Features) == Features
|
|
|
|
|| (properties.optimalTilingFeatures & Features) == Features;
|
|
|
|
}
|
2018-03-14 16:03:48 +01:00
|
|
|
|
|
|
|
|
2018-09-27 11:32:23 +02:00
|
|
|
VkImageUsageFlags D3D11CommonTexture::EnableMetaCopyUsage(
|
|
|
|
VkFormat Format,
|
|
|
|
VkImageTiling Tiling) const {
|
|
|
|
VkFormatFeatureFlags requestedFeatures = 0;
|
|
|
|
|
|
|
|
if (Format == VK_FORMAT_D16_UNORM || Format == VK_FORMAT_D32_SFLOAT) {
|
|
|
|
requestedFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
|
|
|
|
| VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Format == VK_FORMAT_R16_UNORM || Format == VK_FORMAT_R32_SFLOAT) {
|
|
|
|
requestedFeatures |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
|
|
|
|
| VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
|
|
|
|
}
|
|
|
|
|
2019-07-18 16:56:34 +02:00
|
|
|
if (Format == VK_FORMAT_D32_SFLOAT_S8_UINT || Format == VK_FORMAT_D24_UNORM_S8_UINT)
|
|
|
|
requestedFeatures |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
|
|
|
|
2018-09-27 11:32:23 +02:00
|
|
|
if (requestedFeatures == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// Enable usage flags for all supported and requested features
|
|
|
|
VkFormatProperties properties = m_device->GetDXVKDevice()->adapter()->formatProperties(Format);
|
|
|
|
|
|
|
|
requestedFeatures &= Tiling == VK_IMAGE_TILING_OPTIMAL
|
|
|
|
? properties.optimalTilingFeatures
|
|
|
|
: properties.linearTilingFeatures;
|
|
|
|
|
|
|
|
VkImageUsageFlags requestedUsage = 0;
|
|
|
|
|
|
|
|
if (requestedFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)
|
|
|
|
requestedUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
|
|
|
|
|
|
if (requestedFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
|
|
|
requestedUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
|
|
|
|
|
|
|
if (requestedFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)
|
|
|
|
requestedUsage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
|
|
|
|
|
|
|
return requestedUsage;
|
|
|
|
}
|
|
|
|
|
2018-11-08 18:06:04 +01:00
|
|
|
|
|
|
|
VkImageUsageFlags D3D11CommonTexture::EnableMetaPackUsage(
|
|
|
|
VkFormat Format,
|
|
|
|
UINT CpuAccess) const {
|
|
|
|
if ((CpuAccess & D3D11_CPU_ACCESS_READ) == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
const auto dsMask = VK_IMAGE_ASPECT_DEPTH_BIT
|
|
|
|
| VK_IMAGE_ASPECT_STENCIL_BIT;
|
|
|
|
|
|
|
|
auto formatInfo = imageFormatInfo(Format);
|
|
|
|
|
|
|
|
return formatInfo->aspectMask == dsMask
|
|
|
|
? VK_IMAGE_USAGE_SAMPLED_BIT
|
|
|
|
: 0;
|
|
|
|
}
|
|
|
|
|
2018-09-27 11:32:23 +02:00
|
|
|
|
2018-03-14 16:03:48 +01:00
|
|
|
D3D11_COMMON_TEXTURE_MAP_MODE D3D11CommonTexture::DetermineMapMode(
|
|
|
|
const DxvkImageCreateInfo* pImageInfo) const {
|
|
|
|
// Don't map an image unless the application requests it
|
|
|
|
if (m_desc.CPUAccessFlags == 0)
|
|
|
|
return D3D11_COMMON_TEXTURE_MAP_MODE_NONE;
|
|
|
|
|
|
|
|
// Write-only images should go through a buffer for multiple reasons:
|
|
|
|
// 1. Some games do not respect the row and depth pitch that is returned
|
|
|
|
// by the Map() method, which leads to incorrect rendering (e.g. Nier)
|
|
|
|
// 2. Since the image will most likely be read for rendering by the GPU,
|
|
|
|
// writing the image to device-local image may be more efficient than
|
|
|
|
// reading its contents from host-visible memory.
|
2019-09-16 13:50:39 +02:00
|
|
|
if (m_desc.Usage == D3D11_USAGE_DYNAMIC
|
2019-09-18 13:15:22 +02:00
|
|
|
&& m_desc.BindFlags != 0
|
2019-09-16 13:50:39 +02:00
|
|
|
&& m_desc.TextureLayout != D3D11_TEXTURE_LAYOUT_ROW_MAJOR)
|
2018-03-14 16:03:48 +01:00
|
|
|
return D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER;
|
|
|
|
|
2018-11-08 18:06:04 +01:00
|
|
|
// Depth-stencil formats in D3D11 can be mapped and follow special
|
|
|
|
// packing rules, so we need to copy that data into a buffer first
|
|
|
|
if (GetPackedDepthStencilFormat(m_desc.Format))
|
|
|
|
return D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER;
|
2021-05-19 19:18:51 +02:00
|
|
|
|
|
|
|
// Multi-plane images have a sepcial memory layout in D3D11
|
|
|
|
if (imageFormatInfo(pImageInfo->format)->flags.test(DxvkFormatFlag::MultiPlane))
|
|
|
|
return D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER;
|
|
|
|
|
2018-03-14 16:03:48 +01:00
|
|
|
// Images that can be read by the host should be mapped directly in
|
|
|
|
// order to avoid expensive synchronization with the GPU. This does
|
|
|
|
// however require linear tiling, which may not be supported for all
|
|
|
|
// combinations of image parameters.
|
|
|
|
return this->CheckImageSupport(pImageInfo, VK_IMAGE_TILING_LINEAR)
|
|
|
|
? D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT
|
2018-03-14 14:40:09 +01:00
|
|
|
: D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-22 00:17:02 +02:00
|
|
|
D3D11CommonTexture::MappedBuffer D3D11CommonTexture::CreateMappedBuffer(UINT MipLevel) const {
|
2018-03-14 01:16:31 +01:00
|
|
|
const DxvkFormatInfo* formatInfo = imageFormatInfo(
|
2019-03-26 17:36:07 +01:00
|
|
|
m_device->LookupPackedFormat(m_desc.Format, GetFormatMode()).Format);
|
2018-03-14 01:16:31 +01:00
|
|
|
|
|
|
|
DxvkBufferCreateInfo info;
|
2021-05-19 17:01:07 +02:00
|
|
|
info.size = GetSubresourceLayout(formatInfo->aspectMask, MipLevel).Size;
|
2018-03-14 01:16:31 +01:00
|
|
|
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
2019-03-26 15:14:56 +01:00
|
|
|
| VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
2021-06-23 16:02:55 +02:00
|
|
|
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT
|
|
|
|
| VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT
|
|
|
|
| VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
|
|
|
|
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
|
|
|
|
| VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
2018-03-14 01:16:31 +01:00
|
|
|
info.access = VK_ACCESS_TRANSFER_READ_BIT
|
2021-06-23 16:02:55 +02:00
|
|
|
| VK_ACCESS_TRANSFER_WRITE_BIT
|
|
|
|
| VK_ACCESS_SHADER_READ_BIT
|
|
|
|
| VK_ACCESS_SHADER_WRITE_BIT;
|
2018-03-14 01:16:31 +01:00
|
|
|
|
2019-04-07 14:47:43 +02:00
|
|
|
VkMemoryPropertyFlags memType = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
|
|
|
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
|
|
|
|
|
|
|
|
if (m_desc.Usage == D3D11_USAGE_STAGING)
|
|
|
|
memType |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
|
|
|
|
|
2021-06-22 00:17:02 +02:00
|
|
|
MappedBuffer result;
|
|
|
|
result.buffer = m_device->GetDXVKDevice()->createBuffer(info, memType);
|
|
|
|
result.slice = result.buffer->getSliceHandle();
|
|
|
|
return result;
|
2018-03-14 01:16:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-13 23:51:30 +01:00
|
|
|
VkImageType D3D11CommonTexture::GetImageTypeFromResourceDim(D3D11_RESOURCE_DIMENSION Dimension) {
|
|
|
|
switch (Dimension) {
|
|
|
|
case D3D11_RESOURCE_DIMENSION_TEXTURE1D: return VK_IMAGE_TYPE_1D;
|
|
|
|
case D3D11_RESOURCE_DIMENSION_TEXTURE2D: return VK_IMAGE_TYPE_2D;
|
|
|
|
case D3D11_RESOURCE_DIMENSION_TEXTURE3D: return VK_IMAGE_TYPE_3D;
|
|
|
|
default: throw DxvkError("D3D11CommonTexture: Unhandled resource dimension");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-14 01:16:31 +01:00
|
|
|
VkImageLayout D3D11CommonTexture::OptimizeLayout(VkImageUsageFlags Usage) {
|
|
|
|
const VkImageUsageFlags usageFlags = Usage;
|
|
|
|
|
|
|
|
// Filter out unnecessary flags. Transfer operations
|
|
|
|
// are handled by the backend in a transparent manner.
|
|
|
|
Usage &= ~(VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
|
|
|
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
|
|
|
|
|
|
|
|
// If the image is used only as an attachment, we never
|
|
|
|
// have to transform the image back to a different layout
|
|
|
|
if (Usage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
|
|
|
|
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
|
|
|
|
|
|
if (Usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
|
|
|
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
|
|
|
|
|
|
Usage &= ~(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
|
|
|
|
| VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
|
|
|
|
|
|
|
// If the image is used for reading but not as a storage
|
|
|
|
// image, we can optimize the image for texture access
|
|
|
|
if (Usage == VK_IMAGE_USAGE_SAMPLED_BIT) {
|
|
|
|
return usageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
|
|
|
|
? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL
|
|
|
|
: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, we have to stick with the default layout
|
|
|
|
return VK_IMAGE_LAYOUT_GENERAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-09-20 05:59:54 +02:00
|
|
|
|
|
|
|
|
2019-04-27 15:35:20 +02:00
|
|
|
D3D11DXGISurface::D3D11DXGISurface(
|
2019-04-27 16:25:55 +02:00
|
|
|
ID3D11Resource* pResource,
|
2019-04-27 15:35:20 +02:00
|
|
|
D3D11CommonTexture* pTexture)
|
2019-06-15 10:28:49 +02:00
|
|
|
: m_resource (pResource),
|
|
|
|
m_texture (pTexture),
|
|
|
|
m_gdiSurface(nullptr) {
|
|
|
|
if (pTexture->Desc()->MiscFlags & D3D11_RESOURCE_MISC_GDI_COMPATIBLE)
|
|
|
|
m_gdiSurface = new D3D11GDISurface(m_resource, 0);
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11DXGISurface::~D3D11DXGISurface() {
|
2019-06-15 10:28:49 +02:00
|
|
|
if (m_gdiSurface)
|
|
|
|
delete m_gdiSurface;
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ULONG STDMETHODCALLTYPE D3D11DXGISurface::AddRef() {
|
2019-04-27 16:25:55 +02:00
|
|
|
return m_resource->AddRef();
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ULONG STDMETHODCALLTYPE D3D11DXGISurface::Release() {
|
2019-04-27 16:25:55 +02:00
|
|
|
return m_resource->Release();
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::QueryInterface(
|
|
|
|
REFIID riid,
|
|
|
|
void** ppvObject) {
|
2019-04-27 16:25:55 +02:00
|
|
|
return m_resource->QueryInterface(riid, ppvObject);
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetPrivateData(
|
|
|
|
REFGUID Name,
|
|
|
|
UINT* pDataSize,
|
|
|
|
void* pData) {
|
2019-04-27 16:25:55 +02:00
|
|
|
return m_resource->GetPrivateData(Name, pDataSize, pData);
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::SetPrivateData(
|
|
|
|
REFGUID Name,
|
|
|
|
UINT DataSize,
|
|
|
|
const void* pData) {
|
2019-04-27 16:25:55 +02:00
|
|
|
return m_resource->SetPrivateData(Name, DataSize, pData);
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::SetPrivateDataInterface(
|
|
|
|
REFGUID Name,
|
|
|
|
const IUnknown* pUnknown) {
|
2019-04-27 16:25:55 +02:00
|
|
|
return m_resource->SetPrivateDataInterface(Name, pUnknown);
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetParent(
|
|
|
|
REFIID riid,
|
|
|
|
void** ppParent) {
|
|
|
|
return GetDevice(riid, ppParent);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetDevice(
|
|
|
|
REFIID riid,
|
|
|
|
void** ppDevice) {
|
|
|
|
Com<ID3D11Device> device;
|
2019-04-27 16:25:55 +02:00
|
|
|
m_resource->GetDevice(&device);
|
2019-04-27 15:35:20 +02:00
|
|
|
return device->QueryInterface(riid, ppDevice);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetDesc(
|
|
|
|
DXGI_SURFACE_DESC* pDesc) {
|
|
|
|
if (!pDesc)
|
|
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
|
|
|
|
auto desc = m_texture->Desc();
|
|
|
|
pDesc->Width = desc->Width;
|
|
|
|
pDesc->Height = desc->Height;
|
|
|
|
pDesc->Format = desc->Format;
|
|
|
|
pDesc->SampleDesc = desc->SampleDesc;
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::Map(
|
2019-04-27 16:17:50 +02:00
|
|
|
DXGI_MAPPED_RECT* pLockedRect,
|
|
|
|
UINT MapFlags) {
|
|
|
|
Com<ID3D11Device> device;
|
|
|
|
Com<ID3D11DeviceContext> context;
|
2019-04-27 15:35:20 +02:00
|
|
|
|
2019-04-27 16:25:55 +02:00
|
|
|
m_resource->GetDevice(&device);
|
2019-04-27 16:17:50 +02:00
|
|
|
device->GetImmediateContext(&context);
|
2019-04-27 15:35:20 +02:00
|
|
|
|
2019-04-27 16:17:50 +02:00
|
|
|
if (pLockedRect) {
|
|
|
|
pLockedRect->Pitch = 0;
|
|
|
|
pLockedRect->pBits = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
D3D11_MAP mapType;
|
|
|
|
|
|
|
|
if (MapFlags & (DXGI_MAP_READ | DXGI_MAP_WRITE))
|
|
|
|
mapType = D3D11_MAP_READ_WRITE;
|
|
|
|
else if (MapFlags & DXGI_MAP_READ)
|
|
|
|
mapType = D3D11_MAP_READ;
|
|
|
|
else if (MapFlags & (DXGI_MAP_WRITE | DXGI_MAP_DISCARD))
|
|
|
|
mapType = D3D11_MAP_WRITE_DISCARD;
|
|
|
|
else if (MapFlags & DXGI_MAP_WRITE)
|
|
|
|
mapType = D3D11_MAP_WRITE;
|
|
|
|
else
|
|
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
|
|
|
|
D3D11_MAPPED_SUBRESOURCE sr;
|
2019-04-27 16:25:55 +02:00
|
|
|
HRESULT hr = context->Map(m_resource, 0,
|
2019-04-27 16:17:50 +02:00
|
|
|
mapType, 0, pLockedRect ? &sr : nullptr);
|
|
|
|
|
|
|
|
if (hr != S_OK)
|
|
|
|
return hr;
|
|
|
|
|
|
|
|
pLockedRect->Pitch = sr.RowPitch;
|
|
|
|
pLockedRect->pBits = reinterpret_cast<unsigned char*>(sr.pData);
|
|
|
|
return hr;
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::Unmap() {
|
2019-04-27 16:17:50 +02:00
|
|
|
Com<ID3D11Device> device;
|
|
|
|
Com<ID3D11DeviceContext> context;
|
2019-04-27 15:35:20 +02:00
|
|
|
|
2019-04-27 16:25:55 +02:00
|
|
|
m_resource->GetDevice(&device);
|
2019-04-27 16:17:50 +02:00
|
|
|
device->GetImmediateContext(&context);
|
|
|
|
|
2019-04-27 16:25:55 +02:00
|
|
|
context->Unmap(m_resource, 0);
|
2019-04-27 16:17:50 +02:00
|
|
|
return S_OK;
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetDC(
|
|
|
|
BOOL Discard,
|
|
|
|
HDC* phdc) {
|
2019-06-15 10:28:49 +02:00
|
|
|
if (!m_gdiSurface)
|
|
|
|
return DXGI_ERROR_INVALID_CALL;
|
|
|
|
|
|
|
|
return m_gdiSurface->Acquire(Discard, phdc);
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::ReleaseDC(
|
|
|
|
RECT* pDirtyRect) {
|
2019-06-15 10:28:49 +02:00
|
|
|
if (!m_gdiSurface)
|
|
|
|
return DXGI_ERROR_INVALID_CALL;
|
2019-04-27 15:35:20 +02:00
|
|
|
|
2019-06-15 10:28:49 +02:00
|
|
|
return m_gdiSurface->Release(pDirtyRect);
|
2019-04-27 15:35:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DXGISurface::GetResource(
|
|
|
|
REFIID riid,
|
|
|
|
void** ppParentResource,
|
|
|
|
UINT* pSubresourceIndex) {
|
2019-04-27 16:25:55 +02:00
|
|
|
HRESULT hr = m_resource->QueryInterface(riid, ppParentResource);
|
2019-04-27 15:35:20 +02:00
|
|
|
if (pSubresourceIndex)
|
|
|
|
*pSubresourceIndex = 0;
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool D3D11DXGISurface::isSurfaceCompatible() const {
|
|
|
|
auto desc = m_texture->Desc();
|
|
|
|
|
|
|
|
return desc->ArraySize == 1
|
|
|
|
&& desc->MipLevels == 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-04-20 10:38:39 +02:00
|
|
|
D3D11VkInteropSurface::D3D11VkInteropSurface(
|
2019-04-27 16:25:55 +02:00
|
|
|
ID3D11Resource* pResource,
|
2018-04-20 10:38:39 +02:00
|
|
|
D3D11CommonTexture* pTexture)
|
2019-04-27 16:25:55 +02:00
|
|
|
: m_resource(pResource),
|
|
|
|
m_texture (pTexture) {
|
2018-04-20 10:38:39 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11VkInteropSurface::~D3D11VkInteropSurface() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ULONG STDMETHODCALLTYPE D3D11VkInteropSurface::AddRef() {
|
2019-04-27 16:25:55 +02:00
|
|
|
return m_resource->AddRef();
|
2018-04-20 10:38:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ULONG STDMETHODCALLTYPE D3D11VkInteropSurface::Release() {
|
2019-04-27 16:25:55 +02:00
|
|
|
return m_resource->Release();
|
2018-04-20 10:38:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11VkInteropSurface::QueryInterface(
|
|
|
|
REFIID riid,
|
|
|
|
void** ppvObject) {
|
2019-04-27 16:25:55 +02:00
|
|
|
return m_resource->QueryInterface(riid, ppvObject);
|
2018-04-20 10:38:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-05-01 23:30:39 +02:00
|
|
|
HRESULT STDMETHODCALLTYPE D3D11VkInteropSurface::GetDevice(
|
|
|
|
IDXGIVkInteropDevice** ppDevice) {
|
|
|
|
Com<ID3D11Device> device;
|
2019-04-27 16:25:55 +02:00
|
|
|
m_resource->GetDevice(&device);
|
2018-05-01 23:30:39 +02:00
|
|
|
|
|
|
|
return device->QueryInterface(
|
|
|
|
__uuidof(IDXGIVkInteropDevice),
|
|
|
|
reinterpret_cast<void**>(ppDevice));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-20 10:38:39 +02:00
|
|
|
HRESULT STDMETHODCALLTYPE D3D11VkInteropSurface::GetVulkanImageInfo(
|
|
|
|
VkImage* pHandle,
|
|
|
|
VkImageLayout* pLayout,
|
|
|
|
VkImageCreateInfo* pInfo) {
|
|
|
|
const Rc<DxvkImage> image = m_texture->GetImage();
|
|
|
|
const DxvkImageCreateInfo& info = image->info();
|
|
|
|
|
|
|
|
if (pHandle != nullptr)
|
|
|
|
*pHandle = image->handle();
|
|
|
|
|
|
|
|
if (pLayout != nullptr)
|
|
|
|
*pLayout = info.layout;
|
|
|
|
|
|
|
|
if (pInfo != nullptr) {
|
|
|
|
// We currently don't support any extended structures
|
|
|
|
if (pInfo->sType != VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
|
|
|
|
|| pInfo->pNext != nullptr)
|
|
|
|
return E_INVALIDARG;
|
|
|
|
|
|
|
|
pInfo->flags = 0;
|
|
|
|
pInfo->imageType = info.type;
|
|
|
|
pInfo->format = info.format;
|
|
|
|
pInfo->extent = info.extent;
|
|
|
|
pInfo->mipLevels = info.mipLevels;
|
|
|
|
pInfo->arrayLayers = info.numLayers;
|
|
|
|
pInfo->samples = info.sampleCount;
|
|
|
|
pInfo->tiling = info.tiling;
|
|
|
|
pInfo->usage = info.usage;
|
|
|
|
pInfo->sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
|
|
|
pInfo->queueFamilyIndexCount = 0;
|
|
|
|
pInfo->initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-23 17:05:07 +01:00
|
|
|
///////////////////////////////////////////
|
|
|
|
// D 3 D 1 1 T E X T U R E 1 D
|
2018-03-13 23:51:30 +01:00
|
|
|
D3D11Texture1D::D3D11Texture1D(
|
|
|
|
D3D11Device* pDevice,
|
|
|
|
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
2021-01-07 21:08:55 +01:00
|
|
|
: D3D11DeviceChild<ID3D11Texture1D>(pDevice),
|
2021-02-12 01:52:20 +01:00
|
|
|
m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE1D, 0, VK_NULL_HANDLE),
|
2018-08-11 18:45:41 +02:00
|
|
|
m_interop (this, &m_texture),
|
2019-06-13 04:37:35 +02:00
|
|
|
m_surface (this, &m_texture),
|
2019-04-27 19:33:47 +02:00
|
|
|
m_resource(this),
|
2019-10-05 23:42:45 +02:00
|
|
|
m_d3d10 (this) {
|
2018-03-13 23:51:30 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-23 17:05:07 +01:00
|
|
|
D3D11Texture1D::~D3D11Texture1D() {
|
2017-12-19 16:01:50 +01:00
|
|
|
|
2017-12-23 17:05:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11Texture1D::QueryInterface(REFIID riid, void** ppvObject) {
|
2019-02-10 08:01:01 +01:00
|
|
|
if (ppvObject == nullptr)
|
|
|
|
return E_POINTER;
|
|
|
|
|
2018-04-02 12:52:02 +02:00
|
|
|
*ppvObject = nullptr;
|
|
|
|
|
|
|
|
if (riid == __uuidof(IUnknown)
|
|
|
|
|| riid == __uuidof(ID3D11DeviceChild)
|
|
|
|
|| riid == __uuidof(ID3D11Resource)
|
|
|
|
|| riid == __uuidof(ID3D11Texture1D)) {
|
|
|
|
*ppvObject = ref(this);
|
|
|
|
return S_OK;
|
|
|
|
}
|
2017-12-19 16:01:50 +01:00
|
|
|
|
2018-08-11 18:45:41 +02:00
|
|
|
if (riid == __uuidof(ID3D10DeviceChild)
|
|
|
|
|| riid == __uuidof(ID3D10Resource)
|
|
|
|
|| riid == __uuidof(ID3D10Texture1D)) {
|
|
|
|
*ppvObject = ref(&m_d3d10);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-06-13 04:37:35 +02:00
|
|
|
if (m_surface.isSurfaceCompatible()
|
|
|
|
&& (riid == __uuidof(IDXGISurface)
|
|
|
|
|| riid == __uuidof(IDXGISurface1)
|
|
|
|
|| riid == __uuidof(IDXGISurface2))) {
|
|
|
|
*ppvObject = ref(&m_surface);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-01 01:50:50 +02:00
|
|
|
if (riid == __uuidof(IDXGIObject)
|
|
|
|
|| riid == __uuidof(IDXGIDeviceSubObject)
|
|
|
|
|| riid == __uuidof(IDXGIResource)
|
2019-04-27 19:33:47 +02:00
|
|
|
|| riid == __uuidof(IDXGIResource1)) {
|
|
|
|
*ppvObject = ref(&m_resource);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2018-04-20 11:12:54 +02:00
|
|
|
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
|
|
|
*ppvObject = ref(&m_interop);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2017-12-23 17:05:07 +01:00
|
|
|
Logger::warn("D3D11Texture1D::QueryInterface: Unknown interface query");
|
2018-03-12 12:05:43 +01:00
|
|
|
Logger::warn(str::format(riid));
|
2017-12-23 17:05:07 +01:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11Texture1D::GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) {
|
|
|
|
*pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE1D;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UINT STDMETHODCALLTYPE D3D11Texture1D::GetEvictionPriority() {
|
|
|
|
return DXGI_RESOURCE_PRIORITY_NORMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11Texture1D::SetEvictionPriority(UINT EvictionPriority) {
|
2019-01-12 15:22:34 +01:00
|
|
|
static bool s_errorShown = false;
|
|
|
|
|
|
|
|
if (!std::exchange(s_errorShown, true))
|
|
|
|
Logger::warn("D3D11Texture1D::SetEvictionPriority: Stub");
|
2017-12-23 17:05:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11Texture1D::GetDesc(D3D11_TEXTURE1D_DESC *pDesc) {
|
2018-03-13 23:51:30 +01:00
|
|
|
pDesc->Width = m_texture.Desc()->Width;
|
|
|
|
pDesc->MipLevels = m_texture.Desc()->MipLevels;
|
|
|
|
pDesc->ArraySize = m_texture.Desc()->ArraySize;
|
|
|
|
pDesc->Format = m_texture.Desc()->Format;
|
|
|
|
pDesc->Usage = m_texture.Desc()->Usage;
|
|
|
|
pDesc->BindFlags = m_texture.Desc()->BindFlags;
|
|
|
|
pDesc->CPUAccessFlags = m_texture.Desc()->CPUAccessFlags;
|
|
|
|
pDesc->MiscFlags = m_texture.Desc()->MiscFlags;
|
2017-12-23 17:05:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////
|
|
|
|
// D 3 D 1 1 T E X T U R E 2 D
|
|
|
|
D3D11Texture2D::D3D11Texture2D(
|
|
|
|
D3D11Device* pDevice,
|
2018-03-13 23:51:30 +01:00
|
|
|
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
2021-01-07 21:08:55 +01:00
|
|
|
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
|
2021-02-12 01:52:20 +01:00
|
|
|
m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, 0, VK_NULL_HANDLE),
|
2020-12-29 22:39:04 +01:00
|
|
|
m_interop (this, &m_texture),
|
|
|
|
m_surface (this, &m_texture),
|
|
|
|
m_resource(this),
|
|
|
|
m_d3d10 (this) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11Texture2D::D3D11Texture2D(
|
|
|
|
D3D11Device* pDevice,
|
|
|
|
const D3D11_COMMON_TEXTURE_DESC* pDesc,
|
2021-02-12 01:52:20 +01:00
|
|
|
DXGI_USAGE DxgiUsage,
|
|
|
|
VkImage vkImage)
|
2021-01-07 21:08:55 +01:00
|
|
|
: D3D11DeviceChild<ID3D11Texture2D1>(pDevice),
|
2021-02-12 01:52:20 +01:00
|
|
|
m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE2D, DxgiUsage, vkImage),
|
2018-08-11 18:45:41 +02:00
|
|
|
m_interop (this, &m_texture),
|
2019-04-27 15:35:20 +02:00
|
|
|
m_surface (this, &m_texture),
|
2019-04-27 19:33:47 +02:00
|
|
|
m_resource(this),
|
2019-10-05 23:42:45 +02:00
|
|
|
m_d3d10 (this) {
|
2017-12-19 16:01:50 +01:00
|
|
|
|
2017-11-27 15:52:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11Texture2D::~D3D11Texture2D() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
HRESULT STDMETHODCALLTYPE D3D11Texture2D::QueryInterface(REFIID riid, void** ppvObject) {
|
2019-02-10 08:01:01 +01:00
|
|
|
if (ppvObject == nullptr)
|
|
|
|
return E_POINTER;
|
|
|
|
|
2018-04-02 12:52:02 +02:00
|
|
|
*ppvObject = nullptr;
|
|
|
|
|
|
|
|
if (riid == __uuidof(IUnknown)
|
|
|
|
|| riid == __uuidof(ID3D11DeviceChild)
|
|
|
|
|| riid == __uuidof(ID3D11Resource)
|
2019-09-16 13:50:39 +02:00
|
|
|
|| riid == __uuidof(ID3D11Texture2D)
|
|
|
|
|| riid == __uuidof(ID3D11Texture2D1)) {
|
2018-04-02 12:52:02 +02:00
|
|
|
*ppvObject = ref(this);
|
|
|
|
return S_OK;
|
|
|
|
}
|
2018-08-11 18:45:41 +02:00
|
|
|
|
|
|
|
if (riid == __uuidof(ID3D10DeviceChild)
|
|
|
|
|| riid == __uuidof(ID3D10Resource)
|
|
|
|
|| riid == __uuidof(ID3D10Texture2D)) {
|
|
|
|
*ppvObject = ref(&m_d3d10);
|
|
|
|
return S_OK;
|
|
|
|
}
|
2019-04-27 15:35:20 +02:00
|
|
|
|
|
|
|
if (m_surface.isSurfaceCompatible()
|
|
|
|
&& (riid == __uuidof(IDXGISurface)
|
|
|
|
|| riid == __uuidof(IDXGISurface1)
|
|
|
|
|| riid == __uuidof(IDXGISurface2))) {
|
|
|
|
*ppvObject = ref(&m_surface);
|
|
|
|
return S_OK;
|
|
|
|
}
|
2017-11-27 15:52:24 +01:00
|
|
|
|
2019-05-01 01:50:50 +02:00
|
|
|
if (riid == __uuidof(IDXGIObject)
|
|
|
|
|| riid == __uuidof(IDXGIDeviceSubObject)
|
|
|
|
|| riid == __uuidof(IDXGIResource)
|
2019-04-27 19:33:47 +02:00
|
|
|
|| riid == __uuidof(IDXGIResource1)) {
|
|
|
|
*ppvObject = ref(&m_resource);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2018-04-20 11:12:54 +02:00
|
|
|
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
|
|
|
*ppvObject = ref(&m_interop);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2017-11-27 15:52:24 +01:00
|
|
|
Logger::warn("D3D11Texture2D::QueryInterface: Unknown interface query");
|
2018-03-12 12:05:43 +01:00
|
|
|
Logger::warn(str::format(riid));
|
2017-11-27 15:52:24 +01:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11Texture2D::GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) {
|
2017-11-27 15:52:24 +01:00
|
|
|
*pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D;
|
|
|
|
}
|
|
|
|
|
2017-11-29 07:55:44 +01:00
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
UINT STDMETHODCALLTYPE D3D11Texture2D::GetEvictionPriority() {
|
2017-12-19 16:01:50 +01:00
|
|
|
return DXGI_RESOURCE_PRIORITY_NORMAL;
|
2017-11-29 15:16:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11Texture2D::SetEvictionPriority(UINT EvictionPriority) {
|
2019-01-12 15:22:34 +01:00
|
|
|
static bool s_errorShown = false;
|
|
|
|
|
|
|
|
if (!std::exchange(s_errorShown, true))
|
|
|
|
Logger::warn("D3D11Texture2D::SetEvictionPriority: Stub");
|
2017-11-29 15:16:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-09-16 13:50:39 +02:00
|
|
|
void STDMETHODCALLTYPE D3D11Texture2D::GetDesc(D3D11_TEXTURE2D_DESC* pDesc) {
|
|
|
|
pDesc->Width = m_texture.Desc()->Width;
|
|
|
|
pDesc->Height = m_texture.Desc()->Height;
|
|
|
|
pDesc->MipLevels = m_texture.Desc()->MipLevels;
|
|
|
|
pDesc->ArraySize = m_texture.Desc()->ArraySize;
|
|
|
|
pDesc->Format = m_texture.Desc()->Format;
|
|
|
|
pDesc->SampleDesc = m_texture.Desc()->SampleDesc;
|
|
|
|
pDesc->Usage = m_texture.Desc()->Usage;
|
|
|
|
pDesc->BindFlags = m_texture.Desc()->BindFlags;
|
|
|
|
pDesc->CPUAccessFlags = m_texture.Desc()->CPUAccessFlags;
|
|
|
|
pDesc->MiscFlags = m_texture.Desc()->MiscFlags;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11Texture2D::GetDesc1(D3D11_TEXTURE2D_DESC1* pDesc) {
|
2018-03-13 23:51:30 +01:00
|
|
|
pDesc->Width = m_texture.Desc()->Width;
|
|
|
|
pDesc->Height = m_texture.Desc()->Height;
|
|
|
|
pDesc->MipLevels = m_texture.Desc()->MipLevels;
|
|
|
|
pDesc->ArraySize = m_texture.Desc()->ArraySize;
|
|
|
|
pDesc->Format = m_texture.Desc()->Format;
|
|
|
|
pDesc->SampleDesc = m_texture.Desc()->SampleDesc;
|
|
|
|
pDesc->Usage = m_texture.Desc()->Usage;
|
|
|
|
pDesc->BindFlags = m_texture.Desc()->BindFlags;
|
|
|
|
pDesc->CPUAccessFlags = m_texture.Desc()->CPUAccessFlags;
|
|
|
|
pDesc->MiscFlags = m_texture.Desc()->MiscFlags;
|
2019-09-16 13:50:39 +02:00
|
|
|
pDesc->TextureLayout = m_texture.Desc()->TextureLayout;
|
2017-11-27 15:52:24 +01:00
|
|
|
}
|
|
|
|
|
2017-12-19 16:01:50 +01:00
|
|
|
|
2017-12-23 17:05:07 +01:00
|
|
|
///////////////////////////////////////////
|
2018-03-10 23:32:15 +01:00
|
|
|
// D 3 D 1 1 T E X T U R E 3 D
|
2017-12-23 17:05:07 +01:00
|
|
|
D3D11Texture3D::D3D11Texture3D(
|
|
|
|
D3D11Device* pDevice,
|
2018-03-13 23:51:30 +01:00
|
|
|
const D3D11_COMMON_TEXTURE_DESC* pDesc)
|
2021-01-07 21:08:55 +01:00
|
|
|
: D3D11DeviceChild<ID3D11Texture3D1>(pDevice),
|
2021-02-12 01:52:20 +01:00
|
|
|
m_texture (pDevice, pDesc, D3D11_RESOURCE_DIMENSION_TEXTURE3D, 0, VK_NULL_HANDLE),
|
2018-08-11 18:45:41 +02:00
|
|
|
m_interop (this, &m_texture),
|
2019-04-27 19:33:47 +02:00
|
|
|
m_resource(this),
|
2019-10-05 23:42:45 +02:00
|
|
|
m_d3d10 (this) {
|
2018-01-06 02:09:07 +01:00
|
|
|
|
2017-12-23 17:05:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11Texture3D::~D3D11Texture3D() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE D3D11Texture3D::QueryInterface(REFIID riid, void** ppvObject) {
|
2019-02-10 08:01:01 +01:00
|
|
|
if (ppvObject == nullptr)
|
|
|
|
return E_POINTER;
|
|
|
|
|
2018-04-02 12:52:02 +02:00
|
|
|
*ppvObject = nullptr;
|
|
|
|
|
|
|
|
if (riid == __uuidof(IUnknown)
|
|
|
|
|| riid == __uuidof(ID3D11DeviceChild)
|
|
|
|
|| riid == __uuidof(ID3D11Resource)
|
2019-09-16 13:50:39 +02:00
|
|
|
|| riid == __uuidof(ID3D11Texture3D)
|
|
|
|
|| riid == __uuidof(ID3D11Texture3D1)) {
|
2018-04-02 12:52:02 +02:00
|
|
|
*ppvObject = ref(this);
|
|
|
|
return S_OK;
|
2018-04-20 11:12:54 +02:00
|
|
|
}
|
|
|
|
|
2018-08-11 18:45:41 +02:00
|
|
|
if (riid == __uuidof(ID3D10DeviceChild)
|
|
|
|
|| riid == __uuidof(ID3D10Resource)
|
|
|
|
|| riid == __uuidof(ID3D10Texture3D)) {
|
|
|
|
*ppvObject = ref(&m_d3d10);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2019-05-01 01:50:50 +02:00
|
|
|
if (riid == __uuidof(IDXGIObject)
|
|
|
|
|| riid == __uuidof(IDXGIDeviceSubObject)
|
|
|
|
|| riid == __uuidof(IDXGIResource)
|
2019-04-27 19:33:47 +02:00
|
|
|
|| riid == __uuidof(IDXGIResource1)) {
|
|
|
|
*ppvObject = ref(&m_resource);
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
2018-04-20 11:12:54 +02:00
|
|
|
if (riid == __uuidof(IDXGIVkInteropSurface)) {
|
|
|
|
*ppvObject = ref(&m_interop);
|
|
|
|
return S_OK;
|
2018-04-02 12:52:02 +02:00
|
|
|
}
|
2017-12-23 17:05:07 +01:00
|
|
|
|
|
|
|
Logger::warn("D3D11Texture3D::QueryInterface: Unknown interface query");
|
2018-03-12 12:05:43 +01:00
|
|
|
Logger::warn(str::format(riid));
|
2017-12-23 17:05:07 +01:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11Texture3D::GetType(D3D11_RESOURCE_DIMENSION *pResourceDimension) {
|
|
|
|
*pResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE3D;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UINT STDMETHODCALLTYPE D3D11Texture3D::GetEvictionPriority() {
|
|
|
|
return DXGI_RESOURCE_PRIORITY_NORMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void STDMETHODCALLTYPE D3D11Texture3D::SetEvictionPriority(UINT EvictionPriority) {
|
2019-01-12 15:22:34 +01:00
|
|
|
static bool s_errorShown = false;
|
|
|
|
|
|
|
|
if (!std::exchange(s_errorShown, true))
|
|
|
|
Logger::warn("D3D11Texture3D::SetEvictionPriority: Stub");
|
2017-12-23 17:05:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-09-16 13:50:39 +02:00
|
|
|
void STDMETHODCALLTYPE D3D11Texture3D::GetDesc(D3D11_TEXTURE3D_DESC* pDesc) {
|
2018-03-13 23:51:30 +01:00
|
|
|
pDesc->Width = m_texture.Desc()->Width;
|
|
|
|
pDesc->Height = m_texture.Desc()->Height;
|
|
|
|
pDesc->Depth = m_texture.Desc()->Depth;
|
|
|
|
pDesc->MipLevels = m_texture.Desc()->MipLevels;
|
|
|
|
pDesc->Format = m_texture.Desc()->Format;
|
|
|
|
pDesc->Usage = m_texture.Desc()->Usage;
|
|
|
|
pDesc->BindFlags = m_texture.Desc()->BindFlags;
|
|
|
|
pDesc->CPUAccessFlags = m_texture.Desc()->CPUAccessFlags;
|
|
|
|
pDesc->MiscFlags = m_texture.Desc()->MiscFlags;
|
2017-12-23 17:05:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-09-16 13:50:39 +02:00
|
|
|
void STDMETHODCALLTYPE D3D11Texture3D::GetDesc1(D3D11_TEXTURE3D_DESC1* pDesc) {
|
|
|
|
pDesc->Width = m_texture.Desc()->Width;
|
|
|
|
pDesc->Height = m_texture.Desc()->Height;
|
|
|
|
pDesc->Depth = m_texture.Desc()->Depth;
|
|
|
|
pDesc->MipLevels = m_texture.Desc()->MipLevels;
|
|
|
|
pDesc->Format = m_texture.Desc()->Format;
|
|
|
|
pDesc->Usage = m_texture.Desc()->Usage;
|
|
|
|
pDesc->BindFlags = m_texture.Desc()->BindFlags;
|
|
|
|
pDesc->CPUAccessFlags = m_texture.Desc()->CPUAccessFlags;
|
|
|
|
pDesc->MiscFlags = m_texture.Desc()->MiscFlags;
|
|
|
|
}
|
|
|
|
|
2017-12-19 16:01:50 +01:00
|
|
|
|
2018-03-14 00:45:07 +01:00
|
|
|
D3D11CommonTexture* GetCommonTexture(ID3D11Resource* pResource) {
|
2017-12-19 16:01:50 +01:00
|
|
|
D3D11_RESOURCE_DIMENSION dimension = D3D11_RESOURCE_DIMENSION_UNKNOWN;
|
|
|
|
pResource->GetType(&dimension);
|
|
|
|
|
|
|
|
switch (dimension) {
|
2018-01-05 01:15:56 +01:00
|
|
|
case D3D11_RESOURCE_DIMENSION_TEXTURE1D:
|
2018-03-14 00:45:07 +01:00
|
|
|
return static_cast<D3D11Texture1D*>(pResource)->GetCommonTexture();
|
2017-12-23 17:05:07 +01:00
|
|
|
|
2018-01-05 01:15:56 +01:00
|
|
|
case D3D11_RESOURCE_DIMENSION_TEXTURE2D:
|
2018-03-14 00:45:07 +01:00
|
|
|
return static_cast<D3D11Texture2D*>(pResource)->GetCommonTexture();
|
2017-12-19 16:01:50 +01:00
|
|
|
|
2018-01-05 01:15:56 +01:00
|
|
|
case D3D11_RESOURCE_DIMENSION_TEXTURE3D:
|
2018-03-14 00:45:07 +01:00
|
|
|
return static_cast<D3D11Texture3D*>(pResource)->GetCommonTexture();
|
2017-12-23 17:05:07 +01:00
|
|
|
|
2017-12-19 16:01:50 +01:00
|
|
|
default:
|
2018-01-05 01:15:56 +01:00
|
|
|
return nullptr;
|
2017-12-19 16:01:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-27 15:52:24 +01:00
|
|
|
}
|