vkd3d: Implement ID3D12Device::GetResourceTiling() for buffers.

This commit is contained in:
Conor McCarthy 2023-05-25 16:40:03 +10:00 committed by Alexandre Julliard
parent 1e178efa01
commit 71a9feac8e
Notes: Alexandre Julliard 2023-07-31 21:19:05 +09:00
Approved-by: Giovanni Mascellani (@giomasce)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/267
4 changed files with 137 additions and 5 deletions

View File

@ -72,6 +72,7 @@ const UINT D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT = 4096;
const UINT D3D12_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE = 4;
const UINT D3D12_TEXTURE_DATA_PITCH_ALIGNMENT = 256;
const UINT D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT = 512;
const UINT D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES = 65536;
const UINT D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT = 4096;
const UINT D3D12_VS_INPUT_REGISTER_COUNT = 32;
const UINT D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE = 16;

View File

@ -3893,12 +3893,18 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device *iface
UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling,
D3D12_SUBRESOURCE_TILING *sub_resource_tilings)
{
FIXME("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, "
const struct d3d12_resource *resource_impl = impl_from_ID3D12Resource(resource);
struct d3d12_device *device = impl_from_ID3D12Device(iface);
TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, "
"standard_title_shape %p, sub_resource_tiling_count %p, "
"first_sub_resource_tiling %u, sub_resource_tilings %p stub!\n",
"first_sub_resource_tiling %u, sub_resource_tilings %p.\n",
iface, resource, total_tile_count, packed_mip_info, standard_tile_shape,
sub_resource_tiling_count, first_sub_resource_tiling,
sub_resource_tilings);
d3d12_resource_get_tiling(device, resource_impl, total_tile_count, packed_mip_info, standard_tile_shape,
sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings);
}
static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device *iface, LUID *luid)

View File

@ -971,6 +971,11 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device,
return hr;
}
static void d3d12_resource_tile_info_cleanup(struct d3d12_resource *resource)
{
vkd3d_free(resource->tiles.subresources);
}
static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12_device *device)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
@ -986,6 +991,8 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12
else
VK_CALL(vkDestroyImage(device->vk_device, resource->u.vk_image, NULL));
d3d12_resource_tile_info_cleanup(resource);
if (resource->heap)
d3d12_heap_resource_destroyed(resource->heap);
}
@ -1057,9 +1064,101 @@ static void d3d12_resource_get_level_box(const struct d3d12_resource *resource,
box->back = d3d12_resource_desc_get_depth(&resource->desc, level);
}
static void d3d12_resource_init_tiles(struct d3d12_resource *resource)
void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource,
UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape,
UINT *subresource_tiling_count, UINT first_subresource_tiling,
D3D12_SUBRESOURCE_TILING *subresource_tilings)
{
resource->tiles.subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc);
unsigned int i, subresource, subresource_count, count;
const struct vkd3d_subresource_tile_info *tile_info;
const VkExtent3D *tile_extent;
if (d3d12_resource_is_texture(resource))
{
FIXME("Not implemented for textures.\n");
return;
}
tile_extent = &resource->tiles.tile_extent;
if (packed_mip_info)
{
packed_mip_info->NumStandardMips = resource->tiles.standard_mip_count;
packed_mip_info->NumPackedMips = 0;
packed_mip_info->NumTilesForPackedMips = 0;
packed_mip_info->StartTileIndexInOverallResource = 0;
}
if (standard_tile_shape)
{
/* D3D12 docs say tile shape is cleared to zero if there is no standard mip, but drivers don't to do this. */
standard_tile_shape->WidthInTexels = tile_extent->width;
standard_tile_shape->HeightInTexels = tile_extent->height;
standard_tile_shape->DepthInTexels = tile_extent->depth;
}
if (total_tile_count)
*total_tile_count = resource->tiles.total_count;
if (!subresource_tiling_count)
return;
subresource_count = resource->tiles.subresource_count;
count = subresource_count - min(first_subresource_tiling, subresource_count);
count = min(count, *subresource_tiling_count);
for (i = 0; i < count; ++i)
{
subresource = i + first_subresource_tiling;
tile_info = &resource->tiles.subresources[subresource];
subresource_tilings[i].StartTileIndexInOverallResource = tile_info->offset;
subresource_tilings[i].WidthInTiles = tile_info->extent.width;
subresource_tilings[i].HeightInTiles = tile_info->extent.height;
subresource_tilings[i].DepthInTiles = tile_info->extent.depth;
}
*subresource_tiling_count = i;
}
static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3d12_device *device)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct vkd3d_subresource_tile_info *tile_info;
VkMemoryRequirements requirements;
unsigned int subresource_count;
subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc);
if (d3d12_resource_is_buffer(resource))
{
assert(subresource_count == 1);
if (!(resource->tiles.subresources = vkd3d_calloc(subresource_count, sizeof(*resource->tiles.subresources))))
{
ERR("Failed to allocate subresource info array.\n");
return false;
}
VK_CALL(vkGetBufferMemoryRequirements(device->vk_device, resource->u.vk_buffer, &requirements));
if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES)
FIXME("Vulkan device tile size is greater than the standard D3D12 tile size.\n");
tile_info = &resource->tiles.subresources[0];
tile_info->offset = 0;
tile_info->extent.width = align(resource->desc.Width, D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES)
/ D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES;
tile_info->extent.height = 1;
tile_info->extent.depth = 1;
tile_info->count = tile_info->extent.width;
resource->tiles.tile_extent.width = D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES;
resource->tiles.tile_extent.height = 1;
resource->tiles.tile_extent.depth = 1;
resource->tiles.total_count = tile_info->extent.width;
resource->tiles.subresource_count = 1;
resource->tiles.standard_mip_count = 1;
}
return true;
}
/* ID3D12Resource */
@ -2013,7 +2112,11 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
desc, initial_state, optimized_clear_value, &object)))
return hr;
d3d12_resource_init_tiles(object);
if (!d3d12_resource_init_tiles(object, device))
{
d3d12_resource_Release(&object->ID3D12Resource_iface);
return E_OUTOFMEMORY;
}
TRACE("Created reserved resource %p.\n", object);

View File

@ -687,9 +687,27 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface);
#define VKD3D_RESOURCE_DEDICATED_HEAP 0x00000008
#define VKD3D_RESOURCE_LINEAR_TILING 0x00000010
struct vkd3d_tiled_region_extent
{
unsigned int width;
unsigned int height;
unsigned int depth;
};
struct vkd3d_subresource_tile_info
{
unsigned int offset;
unsigned int count;
struct vkd3d_tiled_region_extent extent;
};
struct d3d12_resource_tile_info
{
VkExtent3D tile_extent;
unsigned int total_count;
unsigned int standard_mip_count;
unsigned int subresource_count;
struct vkd3d_subresource_tile_info *subresources;
};
/* ID3D12Resource */
@ -742,6 +760,10 @@ static inline bool d3d12_resource_is_texture(const struct d3d12_resource *resour
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);
void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource,
UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape,
UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling,
D3D12_SUBRESOURCE_TILING *sub_resource_tilings);
HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,