mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d: Implement ID3D12Device::GetResourceTiling() for textures.
This commit is contained in:
parent
71a9feac8e
commit
4433dacb4f
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
@ -45,6 +45,7 @@ const UINT D3D12_DEFAULT_STENCIL_WRITE_MASK = 0xff;
|
|||||||
const UINT D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND = 0xffffffff;
|
const UINT D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND = 0xffffffff;
|
||||||
cpp_quote("#define D3D12_FLOAT32_MAX (3.402823466e+38f)")
|
cpp_quote("#define D3D12_FLOAT32_MAX (3.402823466e+38f)")
|
||||||
const UINT D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32;
|
const UINT D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32;
|
||||||
|
const UINT D3D12_PACKED_TILE = 0xffffffff;
|
||||||
const UINT D3D12_UAV_SLOT_COUNT = 64;
|
const UINT D3D12_UAV_SLOT_COUNT = 64;
|
||||||
const UINT D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT = 4096;
|
const UINT D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT = 4096;
|
||||||
const UINT D3D12_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT = 4096;
|
const UINT D3D12_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT = 4096;
|
||||||
|
@ -1064,29 +1064,38 @@ static void d3d12_resource_get_level_box(const struct d3d12_resource *resource,
|
|||||||
box->back = d3d12_resource_desc_get_depth(&resource->desc, level);
|
box->back = d3d12_resource_desc_get_depth(&resource->desc, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void compute_image_subresource_size_in_tiles(const VkExtent3D *tile_extent,
|
||||||
|
const struct D3D12_RESOURCE_DESC *desc, unsigned int miplevel_idx,
|
||||||
|
struct vkd3d_tiled_region_extent *size)
|
||||||
|
{
|
||||||
|
unsigned int width, height, depth;
|
||||||
|
|
||||||
|
width = d3d12_resource_desc_get_width(desc, miplevel_idx);
|
||||||
|
height = d3d12_resource_desc_get_height(desc, miplevel_idx);
|
||||||
|
depth = d3d12_resource_desc_get_depth(desc, miplevel_idx);
|
||||||
|
size->width = (width + tile_extent->width - 1) / tile_extent->width;
|
||||||
|
size->height = (height + tile_extent->height - 1) / tile_extent->height;
|
||||||
|
size->depth = (depth + tile_extent->depth - 1) / tile_extent->depth;
|
||||||
|
}
|
||||||
|
|
||||||
void d3d12_resource_get_tiling(struct d3d12_device *device, const 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 *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape,
|
||||||
UINT *subresource_tiling_count, UINT first_subresource_tiling,
|
UINT *subresource_tiling_count, UINT first_subresource_tiling,
|
||||||
D3D12_SUBRESOURCE_TILING *subresource_tilings)
|
D3D12_SUBRESOURCE_TILING *subresource_tilings)
|
||||||
{
|
{
|
||||||
unsigned int i, subresource, subresource_count, count;
|
unsigned int i, subresource, subresource_count, miplevel_idx, count;
|
||||||
const struct vkd3d_subresource_tile_info *tile_info;
|
const struct vkd3d_subresource_tile_info *tile_info;
|
||||||
const VkExtent3D *tile_extent;
|
const VkExtent3D *tile_extent;
|
||||||
|
|
||||||
if (d3d12_resource_is_texture(resource))
|
|
||||||
{
|
|
||||||
FIXME("Not implemented for textures.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tile_extent = &resource->tiles.tile_extent;
|
tile_extent = &resource->tiles.tile_extent;
|
||||||
|
|
||||||
if (packed_mip_info)
|
if (packed_mip_info)
|
||||||
{
|
{
|
||||||
packed_mip_info->NumStandardMips = resource->tiles.standard_mip_count;
|
packed_mip_info->NumStandardMips = resource->tiles.standard_mip_count;
|
||||||
packed_mip_info->NumPackedMips = 0;
|
packed_mip_info->NumPackedMips = resource->desc.MipLevels - packed_mip_info->NumStandardMips;
|
||||||
packed_mip_info->NumTilesForPackedMips = 0;
|
packed_mip_info->NumTilesForPackedMips = !!resource->tiles.packed_mip_tile_count; /* non-zero dummy value */
|
||||||
packed_mip_info->StartTileIndexInOverallResource = 0;
|
packed_mip_info->StartTileIndexInOverallResource = packed_mip_info->NumPackedMips
|
||||||
|
? resource->tiles.subresources[resource->tiles.standard_mip_count].offset : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (standard_tile_shape)
|
if (standard_tile_shape)
|
||||||
@ -1111,6 +1120,14 @@ void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_r
|
|||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
subresource = i + first_subresource_tiling;
|
subresource = i + first_subresource_tiling;
|
||||||
|
miplevel_idx = subresource % resource->desc.MipLevels;
|
||||||
|
if (miplevel_idx >= resource->tiles.standard_mip_count)
|
||||||
|
{
|
||||||
|
memset(&subresource_tilings[i], 0, sizeof(subresource_tilings[i]));
|
||||||
|
subresource_tilings[i].StartTileIndexInOverallResource = D3D12_PACKED_TILE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
tile_info = &resource->tiles.subresources[subresource];
|
tile_info = &resource->tiles.subresources[subresource];
|
||||||
subresource_tilings[i].StartTileIndexInOverallResource = tile_info->offset;
|
subresource_tilings[i].StartTileIndexInOverallResource = tile_info->offset;
|
||||||
subresource_tilings[i].WidthInTiles = tile_info->extent.width;
|
subresource_tilings[i].WidthInTiles = tile_info->extent.width;
|
||||||
@ -1122,22 +1139,27 @@ void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_r
|
|||||||
|
|
||||||
static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3d12_device *device)
|
static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3d12_device *device)
|
||||||
{
|
{
|
||||||
|
unsigned int i, start_idx, subresource_count, tile_count, miplevel_idx;
|
||||||
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
|
VkSparseImageMemoryRequirements *sparse_requirements_array;
|
||||||
|
VkSparseImageMemoryRequirements sparse_requirements = {0};
|
||||||
struct vkd3d_subresource_tile_info *tile_info;
|
struct vkd3d_subresource_tile_info *tile_info;
|
||||||
VkMemoryRequirements requirements;
|
VkMemoryRequirements requirements;
|
||||||
unsigned int subresource_count;
|
const VkExtent3D *tile_extent;
|
||||||
|
uint32_t requirement_count;
|
||||||
|
|
||||||
subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc);
|
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))))
|
if (!(resource->tiles.subresources = vkd3d_calloc(subresource_count, sizeof(*resource->tiles.subresources))))
|
||||||
{
|
{
|
||||||
ERR("Failed to allocate subresource info array.\n");
|
ERR("Failed to allocate subresource info array.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (d3d12_resource_is_buffer(resource))
|
||||||
|
{
|
||||||
|
assert(subresource_count == 1);
|
||||||
|
|
||||||
VK_CALL(vkGetBufferMemoryRequirements(device->vk_device, resource->u.vk_buffer, &requirements));
|
VK_CALL(vkGetBufferMemoryRequirements(device->vk_device, resource->u.vk_buffer, &requirements));
|
||||||
if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES)
|
if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES)
|
||||||
FIXME("Vulkan device tile size is greater than the standard D3D12 tile size.\n");
|
FIXME("Vulkan device tile size is greater than the standard D3D12 tile size.\n");
|
||||||
@ -1156,6 +1178,76 @@ static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3
|
|||||||
resource->tiles.total_count = tile_info->extent.width;
|
resource->tiles.total_count = tile_info->extent.width;
|
||||||
resource->tiles.subresource_count = 1;
|
resource->tiles.subresource_count = 1;
|
||||||
resource->tiles.standard_mip_count = 1;
|
resource->tiles.standard_mip_count = 1;
|
||||||
|
resource->tiles.packed_mip_tile_count = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VK_CALL(vkGetImageMemoryRequirements(device->vk_device, resource->u.vk_image, &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");
|
||||||
|
|
||||||
|
requirement_count = 0;
|
||||||
|
VK_CALL(vkGetImageSparseMemoryRequirements(device->vk_device, resource->u.vk_image, &requirement_count, NULL));
|
||||||
|
if (!(sparse_requirements_array = vkd3d_calloc(requirement_count, sizeof(*sparse_requirements_array))))
|
||||||
|
{
|
||||||
|
ERR("Failed to allocate sparse requirements array.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
VK_CALL(vkGetImageSparseMemoryRequirements(device->vk_device, resource->u.vk_image,
|
||||||
|
&requirement_count, sparse_requirements_array));
|
||||||
|
|
||||||
|
for (i = 0; i < requirement_count; ++i)
|
||||||
|
{
|
||||||
|
if (sparse_requirements_array[i].formatProperties.aspectMask & resource->format->vk_aspect_mask)
|
||||||
|
{
|
||||||
|
if (sparse_requirements.formatProperties.aspectMask)
|
||||||
|
{
|
||||||
|
WARN("Ignoring properties for aspect mask %#x.\n",
|
||||||
|
sparse_requirements_array[i].formatProperties.aspectMask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sparse_requirements = sparse_requirements_array[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vkd3d_free(sparse_requirements_array);
|
||||||
|
if (!sparse_requirements.formatProperties.aspectMask)
|
||||||
|
{
|
||||||
|
WARN("Failed to get sparse requirements.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
resource->tiles.tile_extent = sparse_requirements.formatProperties.imageGranularity;
|
||||||
|
resource->tiles.subresource_count = subresource_count;
|
||||||
|
resource->tiles.standard_mip_count = sparse_requirements.imageMipTailSize
|
||||||
|
? sparse_requirements.imageMipTailFirstLod : resource->desc.MipLevels;
|
||||||
|
resource->tiles.packed_mip_tile_count = (resource->tiles.standard_mip_count < resource->desc.MipLevels)
|
||||||
|
? sparse_requirements.imageMipTailSize / requirements.alignment : 0;
|
||||||
|
|
||||||
|
for (i = 0, start_idx = 0; i < subresource_count; ++i)
|
||||||
|
{
|
||||||
|
miplevel_idx = i % resource->desc.MipLevels;
|
||||||
|
|
||||||
|
tile_extent = &sparse_requirements.formatProperties.imageGranularity;
|
||||||
|
tile_info = &resource->tiles.subresources[i];
|
||||||
|
compute_image_subresource_size_in_tiles(tile_extent, &resource->desc, miplevel_idx, &tile_info->extent);
|
||||||
|
tile_info->offset = start_idx;
|
||||||
|
tile_info->count = 0;
|
||||||
|
|
||||||
|
if (miplevel_idx < resource->tiles.standard_mip_count)
|
||||||
|
{
|
||||||
|
tile_count = tile_info->extent.width * tile_info->extent.height * tile_info->extent.depth;
|
||||||
|
start_idx += tile_count;
|
||||||
|
tile_info->count = tile_count;
|
||||||
|
}
|
||||||
|
else if (miplevel_idx == resource->tiles.standard_mip_count)
|
||||||
|
{
|
||||||
|
tile_info->count = 1; /* Non-zero dummy value */
|
||||||
|
start_idx += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resource->tiles.total_count = start_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -706,6 +706,7 @@ struct d3d12_resource_tile_info
|
|||||||
VkExtent3D tile_extent;
|
VkExtent3D tile_extent;
|
||||||
unsigned int total_count;
|
unsigned int total_count;
|
||||||
unsigned int standard_mip_count;
|
unsigned int standard_mip_count;
|
||||||
|
unsigned int packed_mip_tile_count;
|
||||||
unsigned int subresource_count;
|
unsigned int subresource_count;
|
||||||
struct vkd3d_subresource_tile_info *subresources;
|
struct vkd3d_subresource_tile_info *subresources;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user