v3dv/pipeline: add basic ref counting support for variants
As soon as we start to cache variants on pipeline caches, the same variant could be used by different pipelines and pipeline caches. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
parent
2326d5bc04
commit
63b6b633e9
|
@ -2740,6 +2740,9 @@ update_fs_variant(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
assert(variant);
|
assert(variant);
|
||||||
assert(vk_result == VK_SUCCESS);
|
assert(vk_result == VK_SUCCESS);
|
||||||
|
|
||||||
|
if (p_stage->current_variant != variant) {
|
||||||
|
v3dv_shader_variant_unref(cmd_buffer->device, p_stage->current_variant);
|
||||||
|
}
|
||||||
p_stage->current_variant = variant;
|
p_stage->current_variant = variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2768,6 +2771,9 @@ update_vs_variant(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
assert(variant);
|
assert(variant);
|
||||||
assert(vk_result == VK_SUCCESS);
|
assert(vk_result == VK_SUCCESS);
|
||||||
|
|
||||||
|
if (p_stage->current_variant != variant) {
|
||||||
|
v3dv_shader_variant_unref(cmd_buffer->device, p_stage->current_variant);
|
||||||
|
}
|
||||||
p_stage->current_variant = variant;
|
p_stage->current_variant = variant;
|
||||||
|
|
||||||
/* Now the vs_bin */
|
/* Now the vs_bin */
|
||||||
|
@ -2787,6 +2793,9 @@ update_vs_variant(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
assert(variant);
|
assert(variant);
|
||||||
assert(vk_result == VK_SUCCESS);
|
assert(vk_result == VK_SUCCESS);
|
||||||
|
|
||||||
|
if (p_stage->current_variant != variant) {
|
||||||
|
v3dv_shader_variant_unref(cmd_buffer->device, p_stage->current_variant);
|
||||||
|
}
|
||||||
p_stage->current_variant = variant;
|
p_stage->current_variant = variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2814,6 +2823,9 @@ update_cs_variant(struct v3dv_cmd_buffer *cmd_buffer)
|
||||||
assert(variant);
|
assert(variant);
|
||||||
assert(result == VK_SUCCESS);
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
|
if (p_stage->current_variant != variant) {
|
||||||
|
v3dv_shader_variant_unref(cmd_buffer->device, p_stage->current_variant);
|
||||||
|
}
|
||||||
p_stage->current_variant = variant;
|
p_stage->current_variant = variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
|
|
||||||
#include "drm-uapi/v3d_drm.h"
|
#include "drm-uapi/v3d_drm.h"
|
||||||
#include "format/u_format.h"
|
#include "format/u_format.h"
|
||||||
#include "u_atomic.h"
|
|
||||||
#include "vk_util.h"
|
#include "vk_util.h"
|
||||||
|
|
||||||
#include "util/build_id.h"
|
#include "util/build_id.h"
|
||||||
|
|
|
@ -89,6 +89,16 @@ v3dv_DestroyShaderModule(VkDevice _device,
|
||||||
vk_free2(&device->alloc, pAllocator, module);
|
vk_free2(&device->alloc, pAllocator, module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
v3dv_shader_variant_destroy(struct v3dv_device *device,
|
||||||
|
struct v3dv_shader_variant *variant)
|
||||||
|
{
|
||||||
|
if (variant->assembly_bo)
|
||||||
|
v3dv_bo_free(device, variant->assembly_bo);
|
||||||
|
ralloc_free(variant->prog_data.base);
|
||||||
|
vk_free(&device->alloc, variant);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
destroy_pipeline_stage(struct v3dv_device *device,
|
destroy_pipeline_stage(struct v3dv_device *device,
|
||||||
struct v3dv_pipeline_stage *p_stage,
|
struct v3dv_pipeline_stage *p_stage,
|
||||||
|
@ -99,18 +109,13 @@ destroy_pipeline_stage(struct v3dv_device *device,
|
||||||
|
|
||||||
hash_table_foreach(p_stage->cache, entry) {
|
hash_table_foreach(p_stage->cache, entry) {
|
||||||
struct v3dv_shader_variant *variant = entry->data;
|
struct v3dv_shader_variant *variant = entry->data;
|
||||||
|
if (variant)
|
||||||
if (variant->assembly_bo) {
|
v3dv_shader_variant_unref(device, variant);
|
||||||
v3dv_bo_free(device, variant->assembly_bo);
|
|
||||||
ralloc_free(variant->prog_data.base);
|
|
||||||
vk_free2(&device->alloc, pAllocator, variant);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ralloc_free(p_stage->nir);
|
ralloc_free(p_stage->nir);
|
||||||
|
v3dv_shader_variant_unref(device, p_stage->current_variant);
|
||||||
_mesa_hash_table_destroy(p_stage->cache, NULL);
|
_mesa_hash_table_destroy(p_stage->cache, NULL);
|
||||||
|
|
||||||
vk_free2(&device->alloc, pAllocator, p_stage);
|
vk_free2(&device->alloc, pAllocator, p_stage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1348,6 +1353,8 @@ upload_assembly(struct v3dv_pipeline_stage *p_stage,
|
||||||
*
|
*
|
||||||
* If the method returns NULL it means that it was not able to allocate the
|
* If the method returns NULL it means that it was not able to allocate the
|
||||||
* resources for the variant. out_vk_result would return which OOM applies.
|
* resources for the variant. out_vk_result would return which OOM applies.
|
||||||
|
*
|
||||||
|
* Returns a new reference of the shader_variant to the caller.
|
||||||
*/
|
*/
|
||||||
struct v3dv_shader_variant*
|
struct v3dv_shader_variant*
|
||||||
v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage,
|
v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage,
|
||||||
|
@ -1361,6 +1368,7 @@ v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage,
|
||||||
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
*out_vk_result = VK_SUCCESS;
|
*out_vk_result = VK_SUCCESS;
|
||||||
|
v3dv_shader_variant_ref(entry->data);
|
||||||
return entry->data;
|
return entry->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1374,6 +1382,7 @@ v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage,
|
||||||
*out_vk_result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
*out_vk_result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
variant->ref_cnt = 1;
|
||||||
|
|
||||||
struct v3dv_physical_device *physical_device =
|
struct v3dv_physical_device *physical_device =
|
||||||
&pipeline->device->instance->physicalDevice;
|
&pipeline->device->instance->physicalDevice;
|
||||||
|
@ -1409,7 +1418,7 @@ v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage,
|
||||||
} else {
|
} else {
|
||||||
if (!upload_assembly(p_stage, variant, qpu_insts, qpu_insts_size)) {
|
if (!upload_assembly(p_stage, variant, qpu_insts, qpu_insts_size)) {
|
||||||
free(qpu_insts);
|
free(qpu_insts);
|
||||||
vk_free2(&device->alloc, pAllocator, variant);
|
v3dv_shader_variant_unref(device, variant);
|
||||||
|
|
||||||
*out_vk_result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
*out_vk_result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#include "util/set.h"
|
#include "util/set.h"
|
||||||
#include "util/hash_table.h"
|
#include "util/hash_table.h"
|
||||||
#include "util/xmlconfig.h"
|
#include "util/xmlconfig.h"
|
||||||
|
#include "u_atomic.h"
|
||||||
|
|
||||||
#include "v3dv_entrypoints.h"
|
#include "v3dv_entrypoints.h"
|
||||||
#include "v3dv_extensions.h"
|
#include "v3dv_extensions.h"
|
||||||
|
@ -1218,6 +1219,8 @@ vk_to_mesa_shader_stage(VkShaderStageFlagBits vk_stage)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct v3dv_shader_variant {
|
struct v3dv_shader_variant {
|
||||||
|
uint32_t ref_cnt;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct v3d_prog_data *base;
|
struct v3d_prog_data *base;
|
||||||
struct v3d_vs_prog_data *vs;
|
struct v3d_vs_prog_data *vs;
|
||||||
|
@ -1714,6 +1717,26 @@ v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage,
|
||||||
const VkAllocationCallbacks *pAllocator,
|
const VkAllocationCallbacks *pAllocator,
|
||||||
VkResult *out_vk_result);
|
VkResult *out_vk_result);
|
||||||
|
|
||||||
|
void
|
||||||
|
v3dv_shader_variant_destroy(struct v3dv_device *device,
|
||||||
|
struct v3dv_shader_variant *variant);
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
v3dv_shader_variant_ref(struct v3dv_shader_variant *variant)
|
||||||
|
{
|
||||||
|
assert(variant && variant->ref_cnt >= 1);
|
||||||
|
p_atomic_inc(&variant->ref_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
v3dv_shader_variant_unref(struct v3dv_device *device,
|
||||||
|
struct v3dv_shader_variant *variant)
|
||||||
|
{
|
||||||
|
assert(variant && variant->ref_cnt >= 1);
|
||||||
|
if (p_atomic_dec_zero(&variant->ref_cnt))
|
||||||
|
v3dv_shader_variant_destroy(device, variant);
|
||||||
|
}
|
||||||
|
|
||||||
struct v3dv_descriptor *
|
struct v3dv_descriptor *
|
||||||
v3dv_descriptor_map_get_descriptor(struct v3dv_descriptor_state *descriptor_state,
|
v3dv_descriptor_map_get_descriptor(struct v3dv_descriptor_state *descriptor_state,
|
||||||
struct v3dv_descriptor_map *map,
|
struct v3dv_descriptor_map *map,
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
|
|
||||||
#include "broadcom/clif/clif_dump.h"
|
#include "broadcom/clif/clif_dump.h"
|
||||||
|
|
||||||
#include "u_atomic.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue