summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarmjit Mahil <Karmjit.Mahil@imgtec.com>2022-11-17 17:17:42 +0000
committerMarge Bot <emma+marge@anholt.net>2022-11-28 11:38:38 +0000
commite30b6563ca2eb8287585251a82e3265945732e6b (patch)
tree7b6ae249cfb1c096baabed5f02ca4db2b966a06f
parent42e9cc010d537210249d8e03e7505b4576f48f37 (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.c84
-rw-r--r--src/imagination/vulkan/pvr_pass.c14
-rw-r--r--src/imagination/vulkan/pvr_private.h13
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)