libs/vkd3d: Implement depth/stencil resource views.

This commit is contained in:
Józef Kucia 2017-08-16 17:38:33 +02:00
parent 67697f2b8f
commit 1d5b8b7d32
6 changed files with 79 additions and 30 deletions

View File

@ -1203,7 +1203,7 @@ static void d3d12_command_list_transition_resource_to_initial_state(struct d3d12
assert(!d3d12_resource_is_buffer(resource));
if (!(format = vkd3d_get_format(resource->desc.Format)))
if (!(format = vkd3d_format_from_d3d12_resource_desc(&resource->desc, 0)))
{
ERR("Resource %p has invalid format %#x.\n", resource, resource->desc.Format);
return;
@ -1818,7 +1818,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic
if (src->Type == D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX
&& dst->Type == D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT)
{
if (!(format = vkd3d_get_format(dst->u.PlacedFootprint.Footprint.Format)))
assert(d3d12_resource_is_buffer(dst_resource));
assert(!d3d12_resource_is_buffer(src_resource));
if (!(format = vkd3d_format_from_d3d12_resource_desc(&src_resource->desc,
dst->u.PlacedFootprint.Footprint.Format)))
{
WARN("Invalid format %#x.\n", dst->u.PlacedFootprint.Footprint.Format);
return;
@ -1828,9 +1832,6 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic
&& (format->vk_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT))
FIXME("Depth-stencil format %#x not fully supported yet.\n", format->dxgi_format);
assert(d3d12_resource_is_buffer(dst_resource));
assert(!d3d12_resource_is_buffer(src_resource));
vk_buffer_image_copy_from_d3d12(&buffer_image_copy, &dst->u.PlacedFootprint,
src->u.SubresourceIndex, &src_resource->desc, format, dst_x, dst_y, dst_z);
VK_CALL(vkCmdCopyImageToBuffer(list->vk_command_buffer,
@ -1840,7 +1841,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic
else if (src->Type == D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT
&& dst->Type == D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX)
{
if (!(format = vkd3d_get_format(src->u.PlacedFootprint.Footprint.Format)))
assert(!d3d12_resource_is_buffer(dst_resource));
assert(d3d12_resource_is_buffer(src_resource));
if (!(format = vkd3d_format_from_d3d12_resource_desc(&dst_resource->desc,
src->u.PlacedFootprint.Footprint.Format)))
{
WARN("Invalid format %#x.\n", src->u.PlacedFootprint.Footprint.Format);
return;
@ -1850,9 +1855,6 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic
&& (format->vk_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT))
FIXME("Depth-stencil format %#x not fully supported yet.\n", format->dxgi_format);
assert(!d3d12_resource_is_buffer(dst_resource));
assert(d3d12_resource_is_buffer(src_resource));
vk_buffer_image_copy_from_d3d12(&buffer_image_copy, &src->u.PlacedFootprint,
dst->u.SubresourceIndex, &dst_resource->desc, format, dst_x, dst_y, dst_z);
VK_CALL(vkCmdCopyBufferToImage(list->vk_command_buffer,
@ -2150,7 +2152,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC
const struct vkd3d_format *format;
VkImageMemoryBarrier vk_barrier;
if (!(format = vkd3d_get_format(resource->desc.Format)))
if (!(format = vkd3d_format_from_d3d12_resource_desc(&resource->desc, 0)))
{
ERR("Resource %p has invalid format %#x.\n", resource, resource->desc.Format);
continue;

View File

@ -1311,7 +1311,7 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device *i
{
format = &vkd3d_format_unknown;
}
else if (!(format = vkd3d_get_format(desc->Format)))
else if (!(format = vkd3d_format_from_d3d12_resource_desc(desc, 0)))
{
WARN("Invalid format %#x.\n", desc->Format);
return;

View File

@ -108,7 +108,7 @@ static HRESULT vkd3d_create_image(struct d3d12_resource *resource, struct d3d12_
VkImageCreateInfo image_info;
VkResult vr;
if (!(format = vkd3d_get_format(desc->Format)))
if (!(format = vkd3d_format_from_d3d12_resource_desc(desc, 0)))
{
WARN("Invalid DXGI format %#x.\n", desc->Format);
return E_INVALIDARG;
@ -117,7 +117,7 @@ static HRESULT vkd3d_create_image(struct d3d12_resource *resource, struct d3d12_
image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
image_info.pNext = NULL;
image_info.flags = 0;
if (dxgi_format_is_typeless(desc->Format))
if (!(desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) && dxgi_format_is_typeless(desc->Format))
image_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
if (desc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D && desc->Width == desc->Height)
image_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
@ -815,10 +815,20 @@ static VkResult vkd3d_create_texture_view(struct d3d12_device *device,
view_desc.image = resource->u.vk_image;
view_desc.viewType = VK_IMAGE_VIEW_TYPE_2D;
view_desc.format = format->vk_format;
view_desc.components.r = VK_COMPONENT_SWIZZLE_R;
view_desc.components.g = VK_COMPONENT_SWIZZLE_G;
view_desc.components.b = VK_COMPONENT_SWIZZLE_B;
view_desc.components.a = VK_COMPONENT_SWIZZLE_A;
if (format->vk_aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT)
{
view_desc.components.r = VK_COMPONENT_SWIZZLE_ZERO;
view_desc.components.g = VK_COMPONENT_SWIZZLE_R;
view_desc.components.b = VK_COMPONENT_SWIZZLE_ZERO;
view_desc.components.a = VK_COMPONENT_SWIZZLE_ZERO;
}
else
{
view_desc.components.r = VK_COMPONENT_SWIZZLE_R;
view_desc.components.g = VK_COMPONENT_SWIZZLE_G;
view_desc.components.b = VK_COMPONENT_SWIZZLE_B;
view_desc.components.a = VK_COMPONENT_SWIZZLE_A;
}
view_desc.subresourceRange.aspectMask = format->vk_aspect_mask;
view_desc.subresourceRange.baseMipLevel = miplevel_idx;
view_desc.subresourceRange.levelCount = miplevel_count;
@ -882,9 +892,9 @@ void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
if (desc)
FIXME("Unhandled SRV desc %p.\n", desc);
if (!(format = vkd3d_get_format(resource->desc.Format)))
if (!(format = vkd3d_format_from_d3d12_resource_desc(&resource->desc, desc ? desc->Format : 0)))
{
ERR("Failed to find format for %#x.\n", resource->desc.Format);
FIXME("Failed to find format for %#x.\n", resource->desc.Format);
return;
}
@ -902,7 +912,7 @@ static void vkd3d_create_buffer_uav(struct d3d12_desc *descriptor,
{
const struct vkd3d_format *format;
if (!(format = vkd3d_get_format(desc->Format)))
if (!(format = vkd3d_format_from_d3d12_resource_desc(&resource->desc, desc->Format)))
{
ERR("Failed to find format for %#x.\n", resource->desc.Format);
return;
@ -942,7 +952,7 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor,
return;
}
if (!(format = vkd3d_get_format(desc->Format)))
if (!(format = vkd3d_format_from_d3d12_resource_desc(&resource->desc, 0)))
{
ERR("Failed to find format for %#x.\n", resource->desc.Format);
return;
@ -1002,7 +1012,7 @@ bool vkd3d_create_raw_buffer_uav(struct d3d12_device *device,
const struct vkd3d_format *format;
struct d3d12_resource *resource;
format = vkd3d_get_format(DXGI_FORMAT_R32_UINT);
format = vkd3d_get_format(DXGI_FORMAT_R32_UINT, false);
resource = vkd3d_gpu_va_allocator_dereference(&device->gpu_va_allocator, gpu_address);
return !vkd3d_create_buffer_view(device, resource, format,
gpu_address - resource->gpu_address, VK_WHOLE_SIZE, vk_buffer_view);
@ -1169,7 +1179,7 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev
return;
}
if (!(format = vkd3d_get_format(desc ? desc->Format : resource->desc.Format)))
if (!(format = vkd3d_format_from_d3d12_resource_desc(&resource->desc, desc ? desc->Format : 0)))
{
WARN("Invalid DXGI format.\n");
return;
@ -1224,7 +1234,7 @@ void d3d12_dsv_desc_create_dsv(struct d3d12_dsv_desc *dsv_desc, struct d3d12_dev
return;
}
if (!(format = vkd3d_get_format(desc ? desc->Format : resource->desc.Format)))
if (!(format = vkd3d_format_from_d3d12_resource_desc(&resource->desc, desc ? desc->Format : 0)))
{
WARN("Invalid DXGI format.\n");
return;

View File

@ -1571,7 +1571,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
{
const D3D12_INPUT_ELEMENT_DESC *e = &desc->InputLayout.pInputElementDescs[i];
if (!(format = vkd3d_get_format(e->Format)))
if (!(format = vkd3d_get_format(e->Format, false)))
{
WARN("Invalid DXGI format %#x.\n", e->Format);
hr = E_FAIL;
@ -1633,7 +1633,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
graphics->rt_idx = 0;
if (desc->DepthStencilState.DepthEnable || desc->DepthStencilState.StencilEnable)
{
if (!(format = vkd3d_get_format(desc->DSVFormat)))
if (!(format = vkd3d_get_format(desc->DSVFormat, true)))
{
WARN("Invalid DXGI format %#x.\n", desc->DSVFormat);
hr = E_FAIL;
@ -1676,7 +1676,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
unsigned int blend_idx = desc->BlendState.IndependentBlendEnable ? i : 0;
size_t idx = graphics->rt_idx + i;
if (!(format = vkd3d_get_format(desc->RTVFormats[i])))
if (!(format = vkd3d_get_format(desc->RTVFormats[i], false)))
{
WARN("Invalid DXGI format %#x.\n", desc->RTVFormats[i]);
hr = E_FAIL;

View File

@ -62,10 +62,40 @@ static const struct vkd3d_format vkd3d_formats[] =
{DXGI_FORMAT_BC7_UNORM_SRGB, VK_FORMAT_BC7_SRGB_BLOCK, 1, 4, 4, 16, VK_IMAGE_ASPECT_COLOR_BIT},
};
const struct vkd3d_format *vkd3d_get_format(DXGI_FORMAT dxgi_format)
/* Each depth/stencil format is only compatible with itself in Vulkan. */
static const struct vkd3d_format vkd3d_depth_stencil_formats[] =
{
{DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_D32_SFLOAT, 4, 1, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT},
{DXGI_FORMAT_R32_FLOAT, VK_FORMAT_D32_SFLOAT, 4, 1, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT},
{DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_D16_UNORM, 2, 1, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT},
{DXGI_FORMAT_R16_UNORM, VK_FORMAT_D16_UNORM, 2, 1, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT},
};
/* We use overrides for depth/stencil formats. This is required in order to
* properly support typeless formats because depth/stencil formats are only
* compatible with themselves in Vulkan.
*/
static const struct vkd3d_format *vkd3d_get_depth_stencil_format(DXGI_FORMAT dxgi_format)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(vkd3d_depth_stencil_formats); ++i)
{
if (vkd3d_depth_stencil_formats[i].dxgi_format == dxgi_format)
return &vkd3d_depth_stencil_formats[i];
}
return NULL;
}
const struct vkd3d_format *vkd3d_get_format(DXGI_FORMAT dxgi_format, bool depth_stencil)
{
const struct vkd3d_format *format;
unsigned int i;
if (depth_stencil && (format = vkd3d_get_depth_stencil_format(dxgi_format)))
return format;
for (i = 0; i < ARRAY_SIZE(vkd3d_formats); ++i)
{
if (vkd3d_formats[i].dxgi_format == dxgi_format)
@ -80,7 +110,7 @@ VkFormat vkd3d_get_vk_format(DXGI_FORMAT format)
{
const struct vkd3d_format *vkd3d_format;
if (!(vkd3d_format = vkd3d_get_format(format)))
if (!(vkd3d_format = vkd3d_get_format(format, false)))
return VK_FORMAT_UNDEFINED;
return vkd3d_format->vk_format;

View File

@ -545,10 +545,17 @@ static inline bool vkd3d_format_is_compressed(const struct vkd3d_format *format)
return format->block_byte_count != 1;
}
const struct vkd3d_format *vkd3d_get_format(DXGI_FORMAT dxgi_format) DECLSPEC_HIDDEN;
const struct vkd3d_format *vkd3d_get_format(DXGI_FORMAT dxgi_format, bool depth_stencil) DECLSPEC_HIDDEN;
bool dxgi_format_is_typeless(DXGI_FORMAT dxgi_format) DECLSPEC_HIDDEN;
static inline const struct vkd3d_format *vkd3d_format_from_d3d12_resource_desc(
const D3D12_RESOURCE_DESC *desc, DXGI_FORMAT view_format)
{
return vkd3d_get_format(view_format ? view_format : desc->Format,
desc->Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
}
enum VkCompareOp vk_compare_op_from_d3d12(D3D12_COMPARISON_FUNC op) DECLSPEC_HIDDEN;
bool is_valid_feature_level(D3D_FEATURE_LEVEL feature_level) DECLSPEC_HIDDEN;