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>
This commit is contained in:
Karmjit Mahil 2022-11-17 17:17:42 +00:00 committed by Marge Bot
parent 42e9cc010d
commit e30b6563ca
3 changed files with 105 additions and 6 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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)