vulkan/runtime: enable parametrization of ASTC software decode

Enable the driver to select :
  - LUT allocation alignment
  - LUT memory flags selection

Signed-off-by: Prakhar Vishwakarma <prakhar.vishwakarma@intel.com>
Signed-off-by: Jaishankar Rajendran <jaishankar.rajendran@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41205>
This commit is contained in:
Jaishankar Rajendran 2026-02-02 14:21:42 +05:30 committed by Marge Bot
parent 0f2a42afcf
commit cd941d3970
4 changed files with 58 additions and 22 deletions

View file

@ -355,7 +355,8 @@ radv_device_init_meta(struct radv_device *device)
if (pdev->emulate_astc) {
result = vk_texcompress_astc_init(&device->vk, &device->meta_state.alloc, device->meta_state.cache,
&device->meta_state.astc_decode);
&device->meta_state.astc_decode,
vk_texcompress_astc_default_params(&device->vk));
if (result != VK_SUCCESS)
return result;
}

View file

@ -493,9 +493,10 @@ anv_device_init_astc_emu(struct anv_device *device)
simple_mtx_init(&astc_emu->mutex, mtx_plain);
if (device->physical->emu_astc_ldr) {
result = vk_texcompress_astc_init(&device->vk, &device->vk.alloc,
VK_NULL_HANDLE,
&astc_emu->texcompress);
result = vk_texcompress_astc_init(
&device->vk, &device->vk.alloc, VK_NULL_HANDLE,
&astc_emu->texcompress,
vk_texcompress_astc_default_params(&device->vk));
}
return result;

View file

@ -181,7 +181,7 @@ static VkResult
astc_prepare_buffer(struct vk_device *device,
struct vk_texcompress_astc_state *astc,
VkAllocationCallbacks *allocator,
VkDeviceSize minTexelBufferOffsetAlignment,
VkDeviceSize alignment,
uint8_t *single_buf_ptr,
VkDeviceSize *single_buf_size)
{
@ -200,7 +200,7 @@ astc_prepare_buffer(struct vk_device *device,
};
for (unsigned i = 0; i < ARRAY_SIZE(luts); i++) {
offset = align(offset, minTexelBufferOffsetAlignment);
offset = align(offset, alignment);
if (single_buf_ptr) {
memcpy(single_buf_ptr + offset, luts[i]->data, luts[i]->size_B);
result = create_buffer_view(device, allocator, &astc->luts_buf_view[i], astc->luts_buf,
@ -237,8 +237,7 @@ astc_prepare_buffer(struct vk_device *device,
vk_format_get_blockheight(formats[i]),
&lut_width, &lut_height);
const unsigned lut_size = lut_width * lut_height;
offset = align(offset, minTexelBufferOffsetAlignment);
offset = align(offset, alignment);
if (single_buf_ptr) {
memcpy(single_buf_ptr + offset, lut_data, lut_width * lut_height);
@ -263,26 +262,19 @@ create_fill_all_luts_vulkan(struct vk_device *device,
VkResult result;
VkDevice _device = vk_device_to_handle(device);
const struct vk_device_dispatch_table *disp = &device->dispatch_table;
VkPhysicalDevice _phy_device = vk_physical_device_to_handle(device->physical);
const struct vk_physical_device_dispatch_table *phy_disp = &device->physical->dispatch_table;
VkDeviceSize single_buf_size;
uint8_t *single_buf_ptr;
VkPhysicalDeviceProperties2 phy_dev_prop = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
.pNext = NULL,
};
phy_disp->GetPhysicalDeviceProperties2(_phy_device, &phy_dev_prop);
/* get the single_buf_size */
result = astc_prepare_buffer(device, astc, allocator,
phy_dev_prop.properties.limits.minTexelBufferOffsetAlignment,
astc->params.luts_alignment,
NULL, &single_buf_size);
VkMemoryPropertyFlags memory_property = astc->params.luts_memory_flags;
/* create gpu buffer for all the luts */
result = vk_create_buffer(device, allocator, single_buf_size,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
memory_property,
VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
&astc->luts_buf, &astc->luts_mem);
if (unlikely(result != VK_SUCCESS))
@ -292,9 +284,18 @@ create_fill_all_luts_vulkan(struct vk_device *device,
/* fill all the luts and create views */
result = astc_prepare_buffer(device, astc, allocator,
phy_dev_prop.properties.limits.minTexelBufferOffsetAlignment,
astc->params.luts_alignment,
single_buf_ptr, &single_buf_size);
if ((astc->params.luts_memory_flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == 0) {
disp->FlushMappedMemoryRanges(_device, 1,
&(VkMappedMemoryRange) {
.memory = astc->luts_mem,
.offset = 0,
.size = VK_WHOLE_SIZE,
});
}
disp->UnmapMemory(_device, astc->luts_mem);
return result;
}
@ -671,10 +672,30 @@ vk_texcompress_astc_fill_write_descriptor_buffer(struct vk_device *device, struc
assert(desc_i == ARRAY_SIZE(buffer->descriptors));
}
struct vk_texcompress_astc_params
vk_texcompress_astc_default_params(struct vk_device *device)
{
VkPhysicalDevice _phy_device = vk_physical_device_to_handle(device->physical);
const struct vk_physical_device_dispatch_table *phy_disp = &device->physical->dispatch_table;
VkPhysicalDeviceProperties2 phy_dev_prop = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
.pNext = NULL,
};
phy_disp->GetPhysicalDeviceProperties2(_phy_device, &phy_dev_prop);
return (struct vk_texcompress_astc_params) {
.luts_alignment = phy_dev_prop.properties.limits.minTexelBufferOffsetAlignment,
.luts_memory_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
};
}
VkResult
vk_texcompress_astc_init(struct vk_device *device, VkAllocationCallbacks *allocator,
VkPipelineCache pipeline_cache,
struct vk_texcompress_astc_state **astc)
struct vk_texcompress_astc_state **astc,
struct vk_texcompress_astc_params params)
{
VkResult result;
@ -686,6 +707,8 @@ vk_texcompress_astc_init(struct vk_device *device, VkAllocationCallbacks *alloca
simple_mtx_init(&(*astc)->mutex, mtx_plain);
(*astc)->params = params;
result = create_fill_all_luts_vulkan(device, allocator, *astc);
if (result != VK_SUCCESS)
goto fail;

View file

@ -35,7 +35,14 @@
#define VK_TEXCOMPRESS_ASTC_NUM_PARTITION_TABLES 14
#define VK_TEXCOMPRESS_ASTC_WRITE_DESC_SET_COUNT 8
struct vk_texcompress_astc_params {
VkMemoryPropertyFlags luts_memory_flags;
uint32_t luts_alignment;
};
struct vk_texcompress_astc_state {
struct vk_texcompress_astc_params params;
/* single buffer is allocated for all luts */
VkDeviceMemory luts_mem;
VkBuffer luts_buf;
@ -86,11 +93,15 @@ VkPipeline vk_texcompress_astc_get_decode_pipeline(struct vk_device *device,
VkResult vk_texcompress_astc_init(struct vk_device *device,
VkAllocationCallbacks *allocator,
VkPipelineCache pipeline_cache,
struct vk_texcompress_astc_state **astc);
struct vk_texcompress_astc_state **astc,
struct vk_texcompress_astc_params params);
void vk_texcompress_astc_finish(struct vk_device *device,
VkAllocationCallbacks *allocator,
struct vk_texcompress_astc_state *astc);
struct vk_texcompress_astc_params
vk_texcompress_astc_default_params(struct vk_device *device);
static inline VkFormat
vk_texcompress_astc_emulation_format(VkFormat format)
{