diff options
author | Karmjit Mahil <Karmjit.Mahil@imgtec.com> | 2022-11-17 17:17:42 +0000 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-11-28 11:38:38 +0000 |
commit | e30b6563ca2eb8287585251a82e3265945732e6b (patch) | |
tree | 7b6ae249cfb1c096baabed5f02ca4db2b966a06f | |
parent | 42e9cc010d537210249d8e03e7505b4576f48f37 (diff) |
pvr: Setup tile buffers.
Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com>
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20007>
-rw-r--r-- | src/imagination/vulkan/pvr_device.c | 84 | ||||
-rw-r--r-- | src/imagination/vulkan/pvr_pass.c | 14 | ||||
-rw-r--r-- | src/imagination/vulkan/pvr_private.h | 13 |
3 files changed, 105 insertions, 6 deletions
diff --git a/src/imagination/vulkan/pvr_device.c b/src/imagination/vulkan/pvr_device.c index 7fd96ac5e16..061cac44af1 100644 --- a/src/imagination/vulkan/pvr_device.c +++ b/src/imagination/vulkan/pvr_device.c @@ -1990,6 +1990,82 @@ err_free_nop_usc_bo: return result; } +static void pvr_device_init_tile_buffer_state(struct pvr_device *device) +{ + simple_mtx_init(&device->tile_buffer_state.mtx, mtx_plain); + + for (uint32_t i = 0; i < ARRAY_SIZE(device->tile_buffer_state.buffers); i++) + device->tile_buffer_state.buffers[i] = NULL; + + device->tile_buffer_state.buffer_count = 0; +} + +static void pvr_device_finish_tile_buffer_state(struct pvr_device *device) +{ + /* Destroy the mutex first to trigger asserts in case it's still locked so + * that we don't put things in an inconsistent state by freeing buffers that + * might be in use or attempt to free buffers while new buffers are being + * allocated. + */ + simple_mtx_destroy(&device->tile_buffer_state.mtx); + + for (uint32_t i = 0; i < device->tile_buffer_state.buffer_count; i++) + pvr_bo_free(device, device->tile_buffer_state.buffers[i]); +} + +/** + * \brief Ensures that a certain amount of tile buffers are allocated. + * + * Make sure that \p capacity amount of tile buffers are allocated. If less were + * present, append new tile buffers of \p size_in_bytes each to reach the quota. + */ +VkResult pvr_device_tile_buffer_ensure_cap(struct pvr_device *device, + uint32_t capacity, + uint32_t size_in_bytes) +{ + const uint32_t cache_line_size = + rogue_get_slc_cache_line_size(&device->pdevice->dev_info); + uint32_t offset; + VkResult result; + + simple_mtx_lock(&device->tile_buffer_state.mtx); + + offset = device->tile_buffer_state.buffer_count; + + /* Clamping in release and asserting in debug. */ + assert(capacity <= ARRAY_SIZE(device->tile_buffer_state.buffers)); + capacity = MIN2(capacity, ARRAY_SIZE(device->tile_buffer_state.buffers)); + + /* TODO: Implement bo multialloc? To reduce the amount of syscalls and + * allocations. + */ + for (uint32_t i = 0; i < (capacity - offset); i++) { + result = pvr_bo_alloc(device, + device->heaps.general_heap, + size_in_bytes, + cache_line_size, + 0, + &device->tile_buffer_state.buffers[offset + i]); + if (result != VK_SUCCESS) { + for (uint32_t j = 0; j < i; j++) + pvr_bo_free(device, device->tile_buffer_state.buffers[offset + j]); + + goto err_release_lock; + } + } + + device->tile_buffer_state.buffer_count = capacity; + + simple_mtx_unlock(&device->tile_buffer_state.mtx); + + return VK_SUCCESS; + +err_release_lock: + simple_mtx_unlock(&device->tile_buffer_state.mtx); + + return result; +} + static void pvr_device_init_default_sampler_state(struct pvr_device *device) { pvr_csb_pack (&device->input_attachment_sampler, TEXSTATE_SAMPLER, sampler) { @@ -2100,9 +2176,11 @@ VkResult pvr_CreateDevice(VkPhysicalDevice physicalDevice, if (result != VK_SUCCESS) goto err_pvr_finish_compute_idfwdf; + pvr_device_init_tile_buffer_state(device); + result = pvr_queues_create(device, pCreateInfo); if (result != VK_SUCCESS) - goto err_pvr_finish_graphics_static_clear; + goto err_pvr_finish_tile_buffer_state; pvr_device_init_default_sampler_state(device); @@ -2126,7 +2204,8 @@ VkResult pvr_CreateDevice(VkPhysicalDevice physicalDevice, return VK_SUCCESS; -err_pvr_finish_graphics_static_clear: +err_pvr_finish_tile_buffer_state: + pvr_device_finish_tile_buffer_state(device); pvr_device_finish_graphics_static_clear_state(device); err_pvr_finish_compute_idfwdf: @@ -2169,6 +2248,7 @@ void pvr_DestroyDevice(VkDevice _device, PVR_FROM_HANDLE(pvr_device, device, _device); pvr_queues_destroy(device); + pvr_device_finish_tile_buffer_state(device); pvr_device_finish_graphics_static_clear_state(device); pvr_device_finish_compute_idfwdf_state(device); pvr_bo_free(device, device->pds_compute_fence_program.pvr_bo); diff --git a/src/imagination/vulkan/pvr_pass.c b/src/imagination/vulkan/pvr_pass.c index f3dda723005..f9702df5ecf 100644 --- a/src/imagination/vulkan/pvr_pass.c +++ b/src/imagination/vulkan/pvr_pass.c @@ -348,9 +348,9 @@ static void pvr_load_op_destroy(struct pvr_device *device, #define PVR_SPM_LOAD_IN_BUFFERS_COUNT(dev_info) \ ({ \ - int __ret = 7U; \ + int __ret = PVR_MAX_TILE_BUFFER_COUNT; \ if (PVR_HAS_FEATURE(dev_info, eight_output_registers)) \ - __ret = 3U; \ + __ret -= 4U; \ __ret; \ }) @@ -590,8 +590,14 @@ VkResult pvr_CreateRenderPass2(VkDevice _device, &pass->hw_setup->renders[i]; struct pvr_load_op *load_op = NULL; - if (hw_render->tile_buffers_count) - pvr_finishme("Set up tile buffer table"); + if (hw_render->tile_buffers_count) { + result = pvr_device_tile_buffer_ensure_cap( + device, + hw_render->tile_buffers_count, + hw_render->eot_setup.tile_buffer_size); + if (result != VK_SUCCESS) + goto err_free_pass; + } assert(!hw_render->load_op); diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h index 7cd98a9a458..7b217313866 100644 --- a/src/imagination/vulkan/pvr_private.h +++ b/src/imagination/vulkan/pvr_private.h @@ -52,6 +52,7 @@ #include "util/format/u_format.h" #include "util/log.h" #include "util/macros.h" +#include "util/simple_mtx.h" #include "util/u_dynarray.h" #include "vk_buffer.h" #include "vk_command_buffer.h" @@ -398,6 +399,14 @@ struct pvr_device { uint32_t large_clear_vdm_words[PVR_CLEAR_VDM_STATE_DWORD_COUNT]; } static_clear_state; + struct { + simple_mtx_t mtx; + +#define PVR_MAX_TILE_BUFFER_COUNT 7U + struct pvr_bo *buffers[PVR_MAX_TILE_BUFFER_COUNT]; + uint32_t buffer_count; + } tile_buffer_state; + VkPhysicalDeviceFeatures features; struct pvr_bo_store *bo_store; @@ -1521,6 +1530,10 @@ VkResult pvr_pds_unitex_state_program_create_and_upload( uint32_t uniform_kicks, struct pvr_pds_upload *const pds_upload_out); +VkResult pvr_device_tile_buffer_ensure_cap(struct pvr_device *device, + uint32_t capacity, + uint32_t size_in_bytes); + #define PVR_FROM_HANDLE(__pvr_type, __name, __handle) \ VK_FROM_HANDLE(__pvr_type, __name, __handle) |