vkd3d: Handle multiple planes in subresource conversion for copies.
Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
e02031220a
commit
0e93af9700
|
@ -5166,11 +5166,15 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(d3d12_command_
|
|||
}
|
||||
|
||||
static void vk_image_subresource_layers_from_d3d12(VkImageSubresourceLayers *subresource,
|
||||
const struct vkd3d_format *format, unsigned int sub_resource_idx, unsigned int miplevel_count)
|
||||
const struct vkd3d_format *format, unsigned int sub_resource_idx,
|
||||
unsigned int miplevel_count, unsigned int layer_count, bool all_aspects)
|
||||
{
|
||||
subresource->aspectMask = format->vk_aspect_mask;
|
||||
subresource->mipLevel = sub_resource_idx % miplevel_count;
|
||||
subresource->baseArrayLayer = sub_resource_idx / miplevel_count;
|
||||
VkImageSubresource sub = vk_image_subresource_from_d3d12(
|
||||
format, sub_resource_idx, miplevel_count, layer_count, all_aspects);
|
||||
|
||||
subresource->aspectMask = sub.aspectMask;
|
||||
subresource->mipLevel = sub.mipLevel;
|
||||
subresource->baseArrayLayer = sub.arrayLayer;
|
||||
subresource->layerCount = 1;
|
||||
}
|
||||
|
||||
|
@ -5198,7 +5202,8 @@ static void vk_buffer_image_copy_from_d3d12(VkBufferImageCopy *copy,
|
|||
(format->byte_count * format->block_byte_count) * format->block_width;
|
||||
copy->bufferImageHeight = footprint->Footprint.Height;
|
||||
vk_image_subresource_layers_from_d3d12(©->imageSubresource,
|
||||
format, sub_resource_idx, image_desc->MipLevels);
|
||||
format, sub_resource_idx, image_desc->MipLevels,
|
||||
d3d12_resource_desc_get_layer_count(image_desc), true);
|
||||
copy->imageOffset.x = dst_x;
|
||||
copy->imageOffset.y = dst_y;
|
||||
copy->imageOffset.z = dst_z;
|
||||
|
@ -5236,7 +5241,8 @@ static void vk_image_buffer_copy_from_d3d12(VkBufferImageCopy *copy,
|
|||
(format->byte_count * format->block_byte_count) * format->block_width;
|
||||
copy->bufferImageHeight = footprint->Footprint.Height;
|
||||
vk_image_subresource_layers_from_d3d12(©->imageSubresource,
|
||||
format, sub_resource_idx, image_desc->MipLevels);
|
||||
format, sub_resource_idx, image_desc->MipLevels,
|
||||
d3d12_resource_desc_get_layer_count(image_desc), false);
|
||||
copy->imageOffset.x = src_box ? src_box->left : 0;
|
||||
copy->imageOffset.y = src_box ? src_box->top : 0;
|
||||
copy->imageOffset.z = src_box ? src_box->front : 0;
|
||||
|
@ -5260,12 +5266,14 @@ static void vk_image_copy_from_d3d12(VkImageCopy *image_copy,
|
|||
const D3D12_BOX *src_box, unsigned int dst_x, unsigned int dst_y, unsigned int dst_z)
|
||||
{
|
||||
vk_image_subresource_layers_from_d3d12(&image_copy->srcSubresource,
|
||||
src_format, src_sub_resource_idx, src_desc->MipLevels);
|
||||
src_format, src_sub_resource_idx, src_desc->MipLevels,
|
||||
d3d12_resource_desc_get_sub_resource_count(src_desc), false);
|
||||
image_copy->srcOffset.x = src_box ? src_box->left : 0;
|
||||
image_copy->srcOffset.y = src_box ? src_box->top : 0;
|
||||
image_copy->srcOffset.z = src_box ? src_box->front : 0;
|
||||
vk_image_subresource_layers_from_d3d12(&image_copy->dstSubresource,
|
||||
dst_format, dst_sub_resource_idx, dst_desc->MipLevels);
|
||||
dst_format, dst_sub_resource_idx, dst_desc->MipLevels,
|
||||
d3d12_resource_desc_get_layer_count(dst_desc), true);
|
||||
image_copy->dstOffset.x = dst_x;
|
||||
image_copy->dstOffset.y = dst_y;
|
||||
image_copy->dstOffset.z = dst_z;
|
||||
|
@ -5368,6 +5376,13 @@ static void d3d12_command_list_copy_image(struct d3d12_command_list *list,
|
|||
vk_image_barriers[1].image = src_resource->res.vk_image;
|
||||
vk_image_barriers[1].subresourceRange = vk_subresource_range_from_layers(®ion->srcSubresource);
|
||||
|
||||
/* If we're copying from a depth or stencil image we can only sample from one aspect,
|
||||
* but barriers needs to cover the entire resource.
|
||||
* We can avoid this requirement with VK_KHR_separate_depth_stencil_layouts,
|
||||
* but there is no compelling reason to require that just for this case. */
|
||||
vk_image_barriers[0].subresourceRange.aspectMask = dst_resource->format->vk_aspect_mask;
|
||||
vk_image_barriers[1].subresourceRange.aspectMask = src_resource->format->vk_aspect_mask;
|
||||
|
||||
VK_CALL(vkCmdPipelineBarrier(list->vk_command_buffer,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, src_stages | dst_stages,
|
||||
0, 0, NULL, 0, NULL, ARRAY_SIZE(vk_image_barriers),
|
||||
|
@ -5384,7 +5399,9 @@ static void d3d12_command_list_copy_image(struct d3d12_command_list *list,
|
|||
{
|
||||
dst_view = src_view = NULL;
|
||||
|
||||
if (!(dst_format = vkd3d_meta_get_copy_image_attachment_format(&list->device->meta_ops, dst_format, src_format)))
|
||||
if (!(dst_format = vkd3d_meta_get_copy_image_attachment_format(&list->device->meta_ops, dst_format, src_format,
|
||||
region->dstSubresource.aspectMask,
|
||||
region->srcSubresource.aspectMask)))
|
||||
{
|
||||
ERR("No attachment format found for source format %u.\n", src_format->vk_format);
|
||||
goto cleanup;
|
||||
|
@ -5413,6 +5430,7 @@ static void d3d12_command_list_copy_image(struct d3d12_command_list *list,
|
|||
dst_view_desc.miplevel_count = 1;
|
||||
dst_view_desc.layer_idx = region->dstSubresource.baseArrayLayer;
|
||||
dst_view_desc.layer_count = region->dstSubresource.layerCount;
|
||||
dst_view_desc.aspect_mask = region->dstSubresource.aspectMask;
|
||||
dst_view_desc.allowed_swizzle = false;
|
||||
|
||||
memset(&src_view_desc, 0, sizeof(src_view_desc));
|
||||
|
@ -5424,6 +5442,7 @@ static void d3d12_command_list_copy_image(struct d3d12_command_list *list,
|
|||
src_view_desc.miplevel_count = 1;
|
||||
src_view_desc.layer_idx = region->srcSubresource.baseArrayLayer;
|
||||
src_view_desc.layer_count = region->srcSubresource.layerCount;
|
||||
src_view_desc.aspect_mask = region->srcSubresource.aspectMask;
|
||||
src_view_desc.allowed_swizzle = false;
|
||||
|
||||
if (!vkd3d_create_texture_view(list->device, &dst_view_desc, &dst_view) ||
|
||||
|
@ -5969,10 +5988,14 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(d3d12_comman
|
|||
}
|
||||
|
||||
vk_image_subresource_layers_from_d3d12(&vk_image_resolve.srcSubresource,
|
||||
src_resource->format, src_sub_resource_idx, src_resource->desc.MipLevels);
|
||||
src_resource->format, src_sub_resource_idx,
|
||||
src_resource->desc.MipLevels,
|
||||
d3d12_resource_desc_get_layer_count(&src_resource->desc), false);
|
||||
memset(&vk_image_resolve.srcOffset, 0, sizeof(vk_image_resolve.srcOffset));
|
||||
vk_image_subresource_layers_from_d3d12(&vk_image_resolve.dstSubresource,
|
||||
dst_resource->format, dst_sub_resource_idx, dst_resource->desc.MipLevels);
|
||||
dst_resource->format, dst_sub_resource_idx,
|
||||
dst_resource->desc.MipLevels,
|
||||
d3d12_resource_desc_get_layer_count(&dst_resource->desc), false);
|
||||
memset(&vk_image_resolve.dstOffset, 0, sizeof(vk_image_resolve.dstOffset));
|
||||
vk_extent_3d_from_d3d12_miplevel(&vk_image_resolve.extent,
|
||||
&dst_resource->desc, vk_image_resolve.dstSubresource.mipLevel);
|
||||
|
@ -7489,6 +7512,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(d3
|
|||
view_desc.miplevel_count = 1;
|
||||
view_desc.layer_idx = base_view->info.texture.layer_idx;
|
||||
view_desc.layer_count = base_view->info.texture.layer_count;
|
||||
view_desc.aspect_mask = view_desc.format->vk_aspect_mask;
|
||||
view_desc.allowed_swizzle = false;
|
||||
|
||||
if (!vkd3d_create_texture_view(list->device, &view_desc, &args.u.view))
|
||||
|
|
|
@ -899,23 +899,32 @@ VkImageViewType vkd3d_meta_get_copy_image_view_type(D3D12_RESOURCE_DIMENSION dim
|
|||
}
|
||||
|
||||
const struct vkd3d_format *vkd3d_meta_get_copy_image_attachment_format(struct vkd3d_meta_ops *meta_ops,
|
||||
const struct vkd3d_format *dst_format, const struct vkd3d_format *src_format)
|
||||
const struct vkd3d_format *dst_format, const struct vkd3d_format *src_format,
|
||||
VkImageAspectFlags dst_aspect, VkImageAspectFlags src_aspect)
|
||||
{
|
||||
DXGI_FORMAT dxgi_format = DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
if (dst_format->vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
|
||||
if (dst_aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
|
||||
return dst_format;
|
||||
|
||||
assert(src_format->vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
assert(src_aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
|
||||
|
||||
switch (src_format->vk_format)
|
||||
{
|
||||
case VK_FORMAT_D16_UNORM:
|
||||
dxgi_format = DXGI_FORMAT_R16_UNORM;
|
||||
break;
|
||||
case VK_FORMAT_D16_UNORM_S8_UINT:
|
||||
dxgi_format = (src_aspect & VK_IMAGE_ASPECT_DEPTH_BIT) ?
|
||||
DXGI_FORMAT_R16_UNORM : DXGI_FORMAT_R8_UINT;
|
||||
break;
|
||||
case VK_FORMAT_D32_SFLOAT:
|
||||
dxgi_format = DXGI_FORMAT_R32_FLOAT;
|
||||
break;
|
||||
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
||||
dxgi_format = (src_aspect & VK_IMAGE_ASPECT_DEPTH_BIT) ?
|
||||
DXGI_FORMAT_R32_FLOAT : DXGI_FORMAT_R8_UINT;
|
||||
break;
|
||||
default:
|
||||
ERR("Unhandled format %u.\n", src_format->vk_format);
|
||||
return NULL;
|
||||
|
|
|
@ -1759,21 +1759,23 @@ struct d3d12_resource *unsafe_impl_from_ID3D12Resource(ID3D12Resource *iface)
|
|||
return unsafe_impl_from_ID3D12Resource1((ID3D12Resource1 *)iface);
|
||||
}
|
||||
|
||||
VkImageSubresource d3d12_resource_get_vk_subresource(const struct d3d12_resource *resource, uint32_t subresource_idx, bool all_aspects)
|
||||
VkImageSubresource vk_image_subresource_from_d3d12(
|
||||
const struct vkd3d_format *format, uint32_t subresource_idx,
|
||||
unsigned int miplevel_count, unsigned int layer_count,
|
||||
bool all_aspects)
|
||||
{
|
||||
uint32_t layer_count = d3d12_resource_desc_get_layer_count(&resource->desc);
|
||||
VkImageSubresource subresource;
|
||||
|
||||
subresource.aspectMask = resource->format->vk_aspect_mask;
|
||||
subresource.mipLevel = subresource_idx % resource->desc.MipLevels;
|
||||
subresource.arrayLayer = (subresource_idx / resource->desc.MipLevels) % layer_count;
|
||||
subresource.aspectMask = format->vk_aspect_mask;
|
||||
subresource.mipLevel = subresource_idx % miplevel_count;
|
||||
subresource.arrayLayer = (subresource_idx / miplevel_count) % layer_count;
|
||||
|
||||
if (!all_aspects)
|
||||
{
|
||||
/* For all formats we currently handle, the n-th aspect bit in Vulkan
|
||||
* corresponds to the n-th plane in D3D12, so isolate the respective
|
||||
* bit in the aspect mask. */
|
||||
uint32_t i, plane_idx = subresource_idx / d3d12_resource_desc_get_sub_resource_count(&resource->desc);
|
||||
uint32_t i, plane_idx = subresource_idx / (miplevel_count * layer_count);
|
||||
|
||||
for (i = 0; i < plane_idx; i++)
|
||||
subresource.aspectMask &= (subresource.aspectMask - 1);
|
||||
|
@ -1784,6 +1786,15 @@ VkImageSubresource d3d12_resource_get_vk_subresource(const struct d3d12_resource
|
|||
return subresource;
|
||||
}
|
||||
|
||||
VkImageSubresource d3d12_resource_get_vk_subresource(const struct d3d12_resource *resource,
|
||||
uint32_t subresource_idx, bool all_aspects)
|
||||
{
|
||||
return vk_image_subresource_from_d3d12(
|
||||
resource->format, subresource_idx,
|
||||
resource->desc.MipLevels, d3d12_resource_desc_get_layer_count(&resource->desc),
|
||||
all_aspects);
|
||||
}
|
||||
|
||||
static void d3d12_validate_resource_flags(D3D12_RESOURCE_FLAGS flags)
|
||||
{
|
||||
unsigned int unknown_flags = flags & ~(D3D12_RESOURCE_FLAG_NONE
|
||||
|
@ -3281,6 +3292,7 @@ static bool init_default_texture_view_desc(struct vkd3d_texture_view_desc *desc,
|
|||
return false;
|
||||
}
|
||||
|
||||
desc->aspect_mask = desc->format->vk_aspect_mask;
|
||||
desc->image = resource->res.vk_image;
|
||||
desc->layout = resource->common_layout;
|
||||
desc->miplevel_idx = 0;
|
||||
|
@ -3336,7 +3348,7 @@ bool vkd3d_create_texture_view(struct d3d12_device *device, const struct vkd3d_t
|
|||
vkd3d_set_view_swizzle_for_format(&view_desc.components, format, desc->allowed_swizzle);
|
||||
if (desc->allowed_swizzle)
|
||||
vk_component_mapping_compose(&view_desc.components, &desc->components);
|
||||
view_desc.subresourceRange.aspectMask = format->vk_aspect_mask;
|
||||
view_desc.subresourceRange.aspectMask = desc->aspect_mask;
|
||||
view_desc.subresourceRange.baseMipLevel = desc->miplevel_idx;
|
||||
view_desc.subresourceRange.levelCount = desc->miplevel_count;
|
||||
view_desc.subresourceRange.baseArrayLayer = desc->layer_idx;
|
||||
|
@ -3840,6 +3852,7 @@ static void vkd3d_create_texture_srv(struct d3d12_desc *descriptor,
|
|||
key.u.texture.components.b = VK_COMPONENT_SWIZZLE_ZERO;
|
||||
key.u.texture.components.a = VK_COMPONENT_SWIZZLE_ZERO;
|
||||
key.u.texture.allowed_swizzle = true;
|
||||
key.u.texture.aspect_mask = key.u.texture.format->vk_aspect_mask;
|
||||
|
||||
if (!(view = vkd3d_view_map_create_view(&device->null_resources.view_map, device, &key)))
|
||||
return;
|
||||
|
@ -4199,6 +4212,7 @@ static void vkd3d_create_texture_uav(struct d3d12_desc *descriptor,
|
|||
key.u.texture.components.b = VK_COMPONENT_SWIZZLE_B;
|
||||
key.u.texture.components.a = VK_COMPONENT_SWIZZLE_A;
|
||||
key.u.texture.allowed_swizzle = false;
|
||||
key.u.texture.aspect_mask = key.u.texture.format->vk_aspect_mask;
|
||||
|
||||
if (!(view = vkd3d_view_map_create_view(&device->null_resources.view_map, device, &key)))
|
||||
return;
|
||||
|
|
|
@ -840,7 +840,12 @@ LONG64 vkd3d_allocate_cookie();
|
|||
|
||||
bool d3d12_resource_is_cpu_accessible(const struct d3d12_resource *resource);
|
||||
HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC *desc, struct d3d12_device *device);
|
||||
VkImageSubresource d3d12_resource_get_vk_subresource(const struct d3d12_resource *resource, uint32_t subresource_idx, bool all_aspects);
|
||||
VkImageSubresource d3d12_resource_get_vk_subresource(const struct d3d12_resource *resource,
|
||||
uint32_t subresource_idx, bool all_aspects);
|
||||
VkImageSubresource vk_image_subresource_from_d3d12(
|
||||
const struct vkd3d_format *format, uint32_t subresource_idx,
|
||||
unsigned int miplevel_count, unsigned int layer_count,
|
||||
bool all_aspects);
|
||||
|
||||
HRESULT d3d12_resource_create_committed(struct d3d12_device *device, const D3D12_RESOURCE_DESC *desc,
|
||||
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, D3D12_RESOURCE_STATES initial_state,
|
||||
|
@ -922,6 +927,7 @@ struct vkd3d_texture_view_desc
|
|||
VkImage image;
|
||||
VkImageViewType view_type;
|
||||
VkImageLayout layout;
|
||||
VkImageAspectFlags aspect_mask;
|
||||
const struct vkd3d_format *format;
|
||||
unsigned int miplevel_idx;
|
||||
unsigned int miplevel_count;
|
||||
|
@ -2433,7 +2439,8 @@ HRESULT vkd3d_meta_get_copy_image_pipeline(struct vkd3d_meta_ops *meta_ops,
|
|||
const struct vkd3d_copy_image_pipeline_key *key, struct vkd3d_copy_image_info *info);
|
||||
VkImageViewType vkd3d_meta_get_copy_image_view_type(D3D12_RESOURCE_DIMENSION dim);
|
||||
const struct vkd3d_format *vkd3d_meta_get_copy_image_attachment_format(struct vkd3d_meta_ops *meta_ops,
|
||||
const struct vkd3d_format *dst_format, const struct vkd3d_format *src_format);
|
||||
const struct vkd3d_format *dst_format, const struct vkd3d_format *src_format,
|
||||
VkImageAspectFlags dst_aspect, VkImageAspectFlags src_aspect);
|
||||
HRESULT vkd3d_meta_get_swapchain_pipeline(struct vkd3d_meta_ops *meta_ops,
|
||||
const struct vkd3d_swapchain_pipeline_key *key, struct vkd3d_swapchain_info *info);
|
||||
|
||||
|
|
Loading…
Reference in New Issue