panvk: Move panvk_descriptor_state to bifrost subdir

Signed-off-by: Rebecca Mckeever <rebecca.mckeever@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29369>
This commit is contained in:
Rebecca Mckeever
2024-05-31 22:58:47 -07:00
committed by Marge Bot
parent d858c42a9d
commit b9f194a6ed
6 changed files with 561 additions and 421 deletions
@@ -0,0 +1,91 @@
/*
* Copyright © 2024 Collabora Ltd.
* SPDX-License-Identifier: MIT
*/
#ifndef PANVK_CMD_DESC_STATE_H
#define PANVK_CMD_DESC_STATE_H
#ifndef PAN_ARCH
#error "PAN_ARCH must be defined"
#endif
#include <stdint.h>
#include "genxml/gen_macros.h"
#include "panvk_descriptor_set.h"
#include "panvk_macros.h"
#include "panvk_pipeline.h"
#include "vk_command_buffer.h"
#include "pan_pool.h"
struct panvk_descriptor_state {
const struct panvk_descriptor_set *sets[MAX_SETS];
struct panvk_push_descriptor_set *push_sets[MAX_SETS];
struct {
struct mali_uniform_buffer_packed ubos[MAX_DYNAMIC_UNIFORM_BUFFERS];
struct panvk_ssbo_addr ssbos[MAX_DYNAMIC_STORAGE_BUFFERS];
} dyn;
mali_ptr ubos;
mali_ptr textures;
mali_ptr samplers;
mali_ptr dyn_desc_ubo;
struct {
mali_ptr attribs;
mali_ptr attrib_bufs;
} img;
};
void panvk_per_arch(cmd_prepare_push_sets)(
struct pan_pool *desc_pool_base, struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline);
void panvk_per_arch(cmd_unprepare_push_sets)(
struct panvk_descriptor_state *desc_state);
void panvk_per_arch(cmd_prepare_ubos)(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline);
void panvk_per_arch(cmd_prepare_textures)(
struct pan_pool *desc_pool_base, struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline);
void panvk_per_arch(cmd_prepare_samplers)(
struct pan_pool *desc_pool_base, struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline);
void panvk_per_arch(fill_img_attribs)(struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline,
void *attrib_bufs, void *attribs,
unsigned first_buf);
void panvk_per_arch(prepare_img_attribs)(
struct pan_pool *desc_pool_base, struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline);
void panvk_per_arch(cmd_desc_state_reset)(
struct panvk_descriptor_state *gfx_desc_state,
struct panvk_descriptor_state *compute_desc_state);
void panvk_per_arch(cmd_desc_state_cleanup)(
struct vk_command_buffer *cmdbuf,
struct panvk_descriptor_state *gfx_desc_state,
struct panvk_descriptor_state *compute_desc_state);
void panvk_per_arch(cmd_desc_state_bind_sets)(
struct panvk_descriptor_state *desc_state, VkPipelineLayout layout,
uint32_t first_set, uint32_t desc_set_count,
const VkDescriptorSet *desc_sets, uint32_t dyn_offset_count,
const uint32_t *dyn_offsets);
struct panvk_push_descriptor_set *panvk_per_arch(cmd_push_descriptors)(
struct vk_command_buffer *cmdbuf, struct panvk_descriptor_state *desc_state,
uint32_t set);
#endif
@@ -21,6 +21,7 @@
#include "pan_blend.h"
#include "pan_desc.h"
#include "panvk_mempool.h"
#include "panvk_shader.h"
#define MAX_RTS 8
@@ -0,0 +1,427 @@
/*
* Copyright © 2024 Collabora Ltd.
*
* Derived from tu_cmd_buffer.c which is:
* Copyright © 2016 Red Hat.
* Copyright © 2016 Bas Nieuwenhuizen
* Copyright © 2015 Intel Corporation
*
* SPDX-License-Identifier: MIT
*/
#include "genxml/gen_macros.h"
#include "panvk_buffer.h"
#include "panvk_cmd_desc_state.h"
#include "panvk_entrypoints.h"
#include "panvk_pipeline.h"
#include "panvk_pipeline_layout.h"
#include "pan_pool.h"
#include "util/rounding.h"
#include "vk_alloc.h"
#include "vk_command_buffer.h"
#include "vk_command_pool.h"
void
panvk_per_arch(cmd_prepare_push_sets)(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
const struct panvk_pipeline_layout *playout = pipeline->layout;
for (unsigned i = 0; i < playout->vk.set_count; i++) {
const struct panvk_descriptor_set_layout *slayout =
vk_to_panvk_descriptor_set_layout(playout->vk.set_layouts[i]);
bool is_push_set =
slayout->flags &
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
if (desc_state->sets[i] || !is_push_set || !desc_state->push_sets[i])
continue;
struct panvk_descriptor_set *set = &desc_state->push_sets[i]->set;
panvk_per_arch(push_descriptor_set_assign_layout)(
desc_state->push_sets[i], slayout);
if (slayout->desc_ubo_size) {
struct panfrost_ptr desc_ubo =
pan_pool_alloc_aligned(desc_pool_base, slayout->desc_ubo_size, 16);
struct mali_uniform_buffer_packed *ubos = set->ubos;
memcpy(desc_ubo.cpu, set->desc_ubo.addr.host, slayout->desc_ubo_size);
set->desc_ubo.addr.dev = desc_ubo.gpu;
set->desc_ubo.addr.host = desc_ubo.cpu;
pan_pack(&ubos[slayout->desc_ubo_index], UNIFORM_BUFFER, cfg) {
cfg.pointer = set->desc_ubo.addr.dev;
cfg.entries = DIV_ROUND_UP(slayout->desc_ubo_size, 16);
}
}
desc_state->sets[i] = &desc_state->push_sets[i]->set;
}
}
void
panvk_per_arch(cmd_unprepare_push_sets)(
struct panvk_descriptor_state *desc_state)
{
for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sets); i++) {
if (desc_state->push_sets[i] &&
&desc_state->push_sets[i]->set == desc_state->sets[i])
desc_state->sets[i] = NULL;
}
}
static void
panvk_cmd_prepare_dyn_ssbos(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
if (!pipeline->layout->num_dyn_ssbos || desc_state->dyn_desc_ubo)
return;
struct panfrost_ptr ssbo_descs =
pan_pool_alloc_aligned(desc_pool_base, sizeof(desc_state->dyn.ssbos), 16);
memcpy(ssbo_descs.cpu, desc_state->dyn.ssbos, sizeof(desc_state->dyn.ssbos));
desc_state->dyn_desc_ubo = ssbo_descs.gpu;
}
void
panvk_per_arch(cmd_prepare_ubos)(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
unsigned ubo_count =
panvk_per_arch(pipeline_layout_total_ubo_count)(pipeline->layout);
if (!ubo_count || desc_state->ubos)
return;
panvk_cmd_prepare_dyn_ssbos(desc_pool_base, desc_state, pipeline);
struct panfrost_ptr ubos =
pan_pool_alloc_desc_array(desc_pool_base, ubo_count, UNIFORM_BUFFER);
struct mali_uniform_buffer_packed *ubo_descs = ubos.cpu;
for (unsigned s = 0; s < pipeline->layout->vk.set_count; s++) {
const struct panvk_descriptor_set_layout *set_layout =
vk_to_panvk_descriptor_set_layout(pipeline->layout->vk.set_layouts[s]);
const struct panvk_descriptor_set *set = desc_state->sets[s];
unsigned ubo_start =
panvk_per_arch(pipeline_layout_ubo_start)(pipeline->layout, s, false);
if (!set) {
memset(&ubo_descs[ubo_start], 0,
set_layout->num_ubos * sizeof(*ubo_descs));
} else {
memcpy(&ubo_descs[ubo_start], set->ubos,
set_layout->num_ubos * sizeof(*ubo_descs));
}
}
unsigned dyn_ubos_offset =
panvk_per_arch(pipeline_layout_dyn_ubos_offset)(pipeline->layout);
memcpy(&ubo_descs[dyn_ubos_offset], desc_state->dyn.ubos,
pipeline->layout->num_dyn_ubos * sizeof(*ubo_descs));
if (pipeline->layout->num_dyn_ssbos) {
unsigned dyn_desc_ubo =
panvk_per_arch(pipeline_layout_dyn_desc_ubo_index)(pipeline->layout);
pan_pack(&ubo_descs[dyn_desc_ubo], UNIFORM_BUFFER, cfg) {
cfg.pointer = desc_state->dyn_desc_ubo;
cfg.entries =
pipeline->layout->num_dyn_ssbos * sizeof(struct panvk_ssbo_addr);
}
}
desc_state->ubos = ubos.gpu;
}
void
panvk_per_arch(cmd_prepare_textures)(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
unsigned num_textures = pipeline->layout->num_textures;
if (!num_textures || desc_state->textures)
return;
struct panfrost_ptr textures = pan_pool_alloc_aligned(
desc_pool_base, num_textures * pan_size(TEXTURE), pan_size(TEXTURE));
void *texture = textures.cpu;
for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sets); i++) {
if (!desc_state->sets[i])
continue;
memcpy(texture, desc_state->sets[i]->textures,
desc_state->sets[i]->layout->num_textures * pan_size(TEXTURE));
texture += desc_state->sets[i]->layout->num_textures * pan_size(TEXTURE);
}
desc_state->textures = textures.gpu;
}
void
panvk_per_arch(cmd_prepare_samplers)(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
unsigned num_samplers = pipeline->layout->num_samplers;
if (!num_samplers || desc_state->samplers)
return;
struct panfrost_ptr samplers =
pan_pool_alloc_desc_array(desc_pool_base, num_samplers, SAMPLER);
void *sampler = samplers.cpu;
/* Prepare the dummy sampler */
pan_pack(sampler, SAMPLER, cfg) {
cfg.seamless_cube_map = false;
cfg.magnify_nearest = true;
cfg.minify_nearest = true;
cfg.normalized_coordinates = false;
}
sampler += pan_size(SAMPLER);
for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sets); i++) {
if (!desc_state->sets[i])
continue;
memcpy(sampler, desc_state->sets[i]->samplers,
desc_state->sets[i]->layout->num_samplers * pan_size(SAMPLER));
sampler += desc_state->sets[i]->layout->num_samplers * pan_size(SAMPLER);
}
desc_state->samplers = samplers.gpu;
}
void
panvk_per_arch(fill_img_attribs)(struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline,
void *attrib_bufs, void *attribs,
unsigned first_buf)
{
for (unsigned s = 0; s < pipeline->layout->vk.set_count; s++) {
const struct panvk_descriptor_set *set = desc_state->sets[s];
if (!set)
continue;
const struct panvk_descriptor_set_layout *layout = set->layout;
unsigned img_idx = pipeline->layout->sets[s].img_offset;
unsigned offset = img_idx * pan_size(ATTRIBUTE_BUFFER) * 2;
unsigned size = layout->num_imgs * pan_size(ATTRIBUTE_BUFFER) * 2;
memcpy(attrib_bufs + offset, desc_state->sets[s]->img_attrib_bufs, size);
offset = img_idx * pan_size(ATTRIBUTE);
for (unsigned i = 0; i < layout->num_imgs; i++) {
pan_pack(attribs + offset, ATTRIBUTE, cfg) {
cfg.buffer_index = first_buf + (img_idx + i) * 2;
cfg.format = desc_state->sets[s]->img_fmts[i];
cfg.offset_enable = false;
}
offset += pan_size(ATTRIBUTE);
}
}
}
void
panvk_per_arch(prepare_img_attribs)(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
if (desc_state->img.attribs)
return;
unsigned attrib_count = pipeline->layout->num_imgs;
unsigned attrib_buf_count = (pipeline->layout->num_imgs * 2);
struct panfrost_ptr bufs = pan_pool_alloc_desc_array(
desc_pool_base, attrib_buf_count + 1, ATTRIBUTE_BUFFER);
struct panfrost_ptr attribs =
pan_pool_alloc_desc_array(desc_pool_base, attrib_count, ATTRIBUTE);
panvk_per_arch(fill_img_attribs)(desc_state, pipeline, bufs.cpu, attribs.cpu,
0);
desc_state->img.attrib_bufs = bufs.gpu;
desc_state->img.attribs = attribs.gpu;
}
void
panvk_per_arch(cmd_desc_state_reset)(
struct panvk_descriptor_state *gfx_desc_state,
struct panvk_descriptor_state *compute_desc_state)
{
memset(&gfx_desc_state->sets, 0, sizeof(gfx_desc_state->sets));
memset(&compute_desc_state->sets, 0, sizeof(compute_desc_state->sets));
}
void
panvk_per_arch(cmd_desc_state_cleanup)(
struct vk_command_buffer *cmdbuf,
struct panvk_descriptor_state *gfx_desc_state,
struct panvk_descriptor_state *compute_desc_state)
{
for (unsigned i = 0; i < MAX_SETS; i++) {
if (gfx_desc_state->push_sets[i])
vk_free(&cmdbuf->pool->alloc, gfx_desc_state->push_sets[i]);
if (compute_desc_state->push_sets[i])
vk_free(&cmdbuf->pool->alloc, compute_desc_state->push_sets[i]);
}
}
static void
panvk_emit_dyn_ubo(struct panvk_descriptor_state *desc_state,
const struct panvk_descriptor_set *desc_set,
unsigned binding, unsigned array_idx, uint32_t dyn_offset,
unsigned dyn_ubo_slot)
{
struct mali_uniform_buffer_packed *ubo = &desc_state->dyn.ubos[dyn_ubo_slot];
const struct panvk_descriptor_set_layout *slayout = desc_set->layout;
VkDescriptorType type = slayout->bindings[binding].type;
assert(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
assert(dyn_ubo_slot < ARRAY_SIZE(desc_state->dyn.ubos));
const unsigned dyn_ubo_idx = slayout->bindings[binding].dyn_ubo_idx;
const struct panvk_buffer_desc *bdesc =
&desc_set->dyn_ubos[dyn_ubo_idx + array_idx];
mali_ptr address =
panvk_buffer_gpu_ptr(bdesc->buffer, bdesc->offset + dyn_offset);
size_t size = panvk_buffer_range(bdesc->buffer, bdesc->offset + dyn_offset,
bdesc->size);
if (size) {
pan_pack(ubo, UNIFORM_BUFFER, cfg) {
cfg.pointer = address;
cfg.entries = DIV_ROUND_UP(size, 16);
}
} else {
memset(ubo, 0, sizeof(*ubo));
}
}
static void
panvk_emit_dyn_ssbo(struct panvk_descriptor_state *desc_state,
const struct panvk_descriptor_set *desc_set,
unsigned binding, unsigned array_idx, uint32_t dyn_offset,
unsigned dyn_ssbo_slot)
{
struct panvk_ssbo_addr *ssbo = &desc_state->dyn.ssbos[dyn_ssbo_slot];
const struct panvk_descriptor_set_layout *slayout = desc_set->layout;
VkDescriptorType type = slayout->bindings[binding].type;
assert(type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
assert(dyn_ssbo_slot < ARRAY_SIZE(desc_state->dyn.ssbos));
const unsigned dyn_ssbo_idx = slayout->bindings[binding].dyn_ssbo_idx;
const struct panvk_buffer_desc *bdesc =
&desc_set->dyn_ssbos[dyn_ssbo_idx + array_idx];
*ssbo = (struct panvk_ssbo_addr){
.base_addr =
panvk_buffer_gpu_ptr(bdesc->buffer, bdesc->offset + dyn_offset),
.size = panvk_buffer_range(bdesc->buffer, bdesc->offset + dyn_offset,
bdesc->size),
};
}
void
panvk_per_arch(cmd_desc_state_bind_sets)(
struct panvk_descriptor_state *desc_state, VkPipelineLayout layout,
uint32_t first_set, uint32_t desc_set_count,
const VkDescriptorSet *desc_sets, uint32_t dyn_offset_count,
const uint32_t *dyn_offsets)
{
VK_FROM_HANDLE(panvk_pipeline_layout, playout, layout);
unsigned dynoffset_idx = 0;
for (unsigned i = 0; i < desc_set_count; ++i) {
unsigned idx = i + first_set;
VK_FROM_HANDLE(panvk_descriptor_set, set, desc_sets[i]);
desc_state->sets[idx] = set;
if (set->layout->num_dyn_ssbos || set->layout->num_dyn_ubos) {
unsigned dyn_ubo_slot = playout->sets[idx].dyn_ubo_offset;
unsigned dyn_ssbo_slot = playout->sets[idx].dyn_ssbo_offset;
for (unsigned b = 0; b < set->layout->binding_count; b++) {
for (unsigned e = 0; e < set->layout->bindings[b].array_size; e++) {
VkDescriptorType type = set->layout->bindings[b].type;
if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
panvk_emit_dyn_ubo(desc_state, set, b, e,
dyn_offsets[dynoffset_idx++],
dyn_ubo_slot++);
} else if (type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
panvk_emit_dyn_ssbo(desc_state, set, b, e,
dyn_offsets[dynoffset_idx++],
dyn_ssbo_slot++);
}
}
}
}
}
/* Unconditionally reset all previously emitted descriptors tables.
* TODO: we could be smarter by checking which part of the pipeline layout
* are compatible with the previouly bound descriptor sets.
*/
desc_state->ubos = 0;
desc_state->textures = 0;
desc_state->samplers = 0;
desc_state->dyn_desc_ubo = 0;
desc_state->img.attrib_bufs = 0;
desc_state->img.attribs = 0;
assert(dynoffset_idx == dyn_offset_count);
}
struct panvk_push_descriptor_set *
panvk_per_arch(cmd_push_descriptors)(struct vk_command_buffer *cmdbuf,
struct panvk_descriptor_state *desc_state,
uint32_t set)
{
assert(set < MAX_SETS);
if (unlikely(desc_state->push_sets[set] == NULL)) {
desc_state->push_sets[set] =
vk_zalloc(&cmdbuf->pool->alloc, sizeof(*desc_state->push_sets[0]), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (unlikely(desc_state->push_sets[set] == NULL)) {
vk_command_buffer_set_error(cmdbuf, VK_ERROR_OUT_OF_HOST_MEMORY);
return NULL;
}
}
/* Pushing descriptors replaces whatever sets are bound */
desc_state->sets[set] = NULL;
/* Reset all descs to force emission of new tables on the next draw/dispatch.
* TODO: Be smarter and only reset those when required.
*/
desc_state->ubos = 0;
desc_state->textures = 0;
desc_state->samplers = 0;
desc_state->img.attrib_bufs = 0;
desc_state->img.attribs = 0;
return desc_state->push_sets[set];
}
+4 -22
View File
@@ -14,6 +14,7 @@
#include "vulkan/runtime/vk_command_buffer.h"
#include "panvk_cmd_desc_state.h"
#include "panvk_cmd_push_constant.h"
#include "panvk_descriptor_set.h"
#include "panvk_descriptor_set_layout.h"
@@ -29,8 +30,8 @@
#include "genxml/gen_macros.h"
#define MAX_BIND_POINTS 2 /* compute + graphics */
#define MAX_VBS 16
#define MAX_BIND_POINTS 2 /* compute + graphics */
#define MAX_VBS 16
struct panvk_batch {
struct list_head node;
@@ -72,25 +73,6 @@ struct panvk_cmd_event_op {
struct panvk_event *event;
};
struct panvk_descriptor_state {
const struct panvk_descriptor_set *sets[MAX_SETS];
struct panvk_push_descriptor_set *push_sets[MAX_SETS];
struct {
struct mali_uniform_buffer_packed ubos[MAX_DYNAMIC_UNIFORM_BUFFERS];
struct panvk_ssbo_addr ssbos[MAX_DYNAMIC_STORAGE_BUFFERS];
} dyn;
mali_ptr ubos;
mali_ptr textures;
mali_ptr samplers;
mali_ptr dyn_desc_ubo;
struct {
mali_ptr attribs;
mali_ptr attrib_bufs;
} img;
};
struct panvk_attrib_buf {
mali_ptr address;
unsigned size;
@@ -217,7 +199,7 @@ panvk_cmd_get_desc_state(struct panvk_cmd_buffer *cmdbuf,
extern const struct vk_command_buffer_ops panvk_per_arch(cmd_buffer_ops);
struct panvk_batch *
panvk_per_arch(cmd_open_batch)(struct panvk_cmd_buffer *cmdbuf);
panvk_per_arch(cmd_open_batch)(struct panvk_cmd_buffer *cmdbuf);
void panvk_per_arch(cmd_close_batch)(struct panvk_cmd_buffer *cmdbuf);
+37 -399
View File
@@ -30,6 +30,7 @@
#include "panvk_buffer.h"
#include "panvk_cmd_buffer.h"
#include "panvk_cmd_desc_state.h"
#include "panvk_cmd_pool.h"
#include "panvk_cmd_push_constant.h"
#include "panvk_device.h"
@@ -51,9 +52,6 @@
#include "pan_samples.h"
#include "pan_shader.h"
#include "util/rounding.h"
#include "util/u_pack_color.h"
#include "vk_descriptor_update_template.h"
#include "vk_format.h"
@@ -321,193 +319,6 @@ panvk_cmd_prepare_draw_sysvals(struct panvk_cmd_buffer *cmdbuf,
}
}
static void
panvk_cmd_prepare_push_sets(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
const struct panvk_pipeline_layout *playout = pipeline->layout;
for (unsigned i = 0; i < playout->vk.set_count; i++) {
const struct panvk_descriptor_set_layout *slayout =
vk_to_panvk_descriptor_set_layout(playout->vk.set_layouts[i]);
bool is_push_set =
slayout->flags &
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
if (desc_state->sets[i] || !is_push_set || !desc_state->push_sets[i])
continue;
struct panvk_descriptor_set *set = &desc_state->push_sets[i]->set;
panvk_per_arch(push_descriptor_set_assign_layout)(
desc_state->push_sets[i], slayout);
if (slayout->desc_ubo_size) {
struct panfrost_ptr desc_ubo = pan_pool_alloc_aligned(
desc_pool_base, slayout->desc_ubo_size, 16);
struct mali_uniform_buffer_packed *ubos = set->ubos;
memcpy(desc_ubo.cpu, set->desc_ubo.addr.host, slayout->desc_ubo_size);
set->desc_ubo.addr.dev = desc_ubo.gpu;
set->desc_ubo.addr.host = desc_ubo.cpu;
pan_pack(&ubos[slayout->desc_ubo_index], UNIFORM_BUFFER, cfg) {
cfg.pointer = set->desc_ubo.addr.dev;
cfg.entries = DIV_ROUND_UP(slayout->desc_ubo_size, 16);
}
}
desc_state->sets[i] = &desc_state->push_sets[i]->set;
}
}
static void
panvk_cmd_unprepare_push_sets(struct panvk_descriptor_state *desc_state)
{
for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sets); i++) {
if (desc_state->push_sets[i] &&
&desc_state->push_sets[i]->set == desc_state->sets[i])
desc_state->sets[i] = NULL;
}
}
static void
panvk_cmd_prepare_dyn_ssbos(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
if (!pipeline->layout->num_dyn_ssbos || desc_state->dyn_desc_ubo)
return;
struct panfrost_ptr ssbo_descs = pan_pool_alloc_aligned(
desc_pool_base, sizeof(desc_state->dyn.ssbos), 16);
memcpy(ssbo_descs.cpu, desc_state->dyn.ssbos, sizeof(desc_state->dyn.ssbos));
desc_state->dyn_desc_ubo = ssbo_descs.gpu;
}
static void
panvk_cmd_prepare_ubos(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
unsigned ubo_count =
panvk_per_arch(pipeline_layout_total_ubo_count)(pipeline->layout);
if (!ubo_count || desc_state->ubos)
return;
panvk_cmd_prepare_dyn_ssbos(desc_pool_base, desc_state, pipeline);
struct panfrost_ptr ubos = pan_pool_alloc_desc_array(
desc_pool_base, ubo_count, UNIFORM_BUFFER);
struct mali_uniform_buffer_packed *ubo_descs = ubos.cpu;
for (unsigned s = 0; s < pipeline->layout->vk.set_count; s++) {
const struct panvk_descriptor_set_layout *set_layout =
vk_to_panvk_descriptor_set_layout(pipeline->layout->vk.set_layouts[s]);
const struct panvk_descriptor_set *set = desc_state->sets[s];
unsigned ubo_start =
panvk_per_arch(pipeline_layout_ubo_start)(pipeline->layout, s, false);
if (!set) {
memset(&ubo_descs[ubo_start], 0,
set_layout->num_ubos * sizeof(*ubo_descs));
} else {
memcpy(&ubo_descs[ubo_start], set->ubos,
set_layout->num_ubos * sizeof(*ubo_descs));
}
}
unsigned dyn_ubos_offset =
panvk_per_arch(pipeline_layout_dyn_ubos_offset)(pipeline->layout);
memcpy(&ubo_descs[dyn_ubos_offset], desc_state->dyn.ubos,
pipeline->layout->num_dyn_ubos * sizeof(*ubo_descs));
if (pipeline->layout->num_dyn_ssbos) {
unsigned dyn_desc_ubo =
panvk_per_arch(pipeline_layout_dyn_desc_ubo_index)(pipeline->layout);
pan_pack(&ubo_descs[dyn_desc_ubo], UNIFORM_BUFFER, cfg) {
cfg.pointer = desc_state->dyn_desc_ubo;
cfg.entries =
pipeline->layout->num_dyn_ssbos * sizeof(struct panvk_ssbo_addr);
}
}
desc_state->ubos = ubos.gpu;
}
static void
panvk_cmd_prepare_textures(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
unsigned num_textures = pipeline->layout->num_textures;
if (!num_textures || desc_state->textures)
return;
struct panfrost_ptr textures = pan_pool_alloc_aligned(
desc_pool_base, num_textures * pan_size(TEXTURE),
pan_size(TEXTURE));
void *texture = textures.cpu;
for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sets); i++) {
if (!desc_state->sets[i])
continue;
memcpy(texture, desc_state->sets[i]->textures,
desc_state->sets[i]->layout->num_textures * pan_size(TEXTURE));
texture += desc_state->sets[i]->layout->num_textures * pan_size(TEXTURE);
}
desc_state->textures = textures.gpu;
}
static void
panvk_cmd_prepare_samplers(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
unsigned num_samplers = pipeline->layout->num_samplers;
if (!num_samplers || desc_state->samplers)
return;
struct panfrost_ptr samplers =
pan_pool_alloc_desc_array(desc_pool_base, num_samplers, SAMPLER);
void *sampler = samplers.cpu;
/* Prepare the dummy sampler */
pan_pack(sampler, SAMPLER, cfg) {
cfg.seamless_cube_map = false;
cfg.magnify_nearest = true;
cfg.minify_nearest = true;
cfg.normalized_coordinates = false;
}
sampler += pan_size(SAMPLER);
for (unsigned i = 0; i < ARRAY_SIZE(desc_state->sets); i++) {
if (!desc_state->sets[i])
continue;
memcpy(sampler, desc_state->sets[i]->samplers,
desc_state->sets[i]->layout->num_samplers * pan_size(SAMPLER));
sampler += desc_state->sets[i]->layout->num_samplers * pan_size(SAMPLER);
}
desc_state->samplers = samplers.gpu;
}
static bool
has_depth_att(struct panvk_cmd_buffer *cmdbuf)
{
@@ -934,57 +745,6 @@ panvk_draw_prepare_varyings(struct panvk_cmd_buffer *cmdbuf,
draw->fs.varyings = pipeline->fs.varyings.attribs;
}
static void
panvk_fill_img_attribs(struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline, void *attrib_bufs,
void *attribs, unsigned first_buf)
{
for (unsigned s = 0; s < pipeline->layout->vk.set_count; s++) {
const struct panvk_descriptor_set *set = desc_state->sets[s];
if (!set)
continue;
const struct panvk_descriptor_set_layout *layout = set->layout;
unsigned img_idx = pipeline->layout->sets[s].img_offset;
unsigned offset = img_idx * pan_size(ATTRIBUTE_BUFFER) * 2;
unsigned size = layout->num_imgs * pan_size(ATTRIBUTE_BUFFER) * 2;
memcpy(attrib_bufs + offset, desc_state->sets[s]->img_attrib_bufs, size);
offset = img_idx * pan_size(ATTRIBUTE);
for (unsigned i = 0; i < layout->num_imgs; i++) {
pan_pack(attribs + offset, ATTRIBUTE, cfg) {
cfg.buffer_index = first_buf + (img_idx + i) * 2;
cfg.format = desc_state->sets[s]->img_fmts[i];
cfg.offset_enable = false;
}
offset += pan_size(ATTRIBUTE);
}
}
}
static void
panvk_prepare_img_attribs(struct pan_pool *desc_pool_base,
struct panvk_descriptor_state *desc_state,
const struct panvk_pipeline *pipeline)
{
if (desc_state->img.attribs)
return;
unsigned attrib_count = pipeline->layout->num_imgs;
unsigned attrib_buf_count = (pipeline->layout->num_imgs * 2);
struct panfrost_ptr bufs = pan_pool_alloc_desc_array(
desc_pool_base, attrib_buf_count + 1, ATTRIBUTE_BUFFER);
struct panfrost_ptr attribs = pan_pool_alloc_desc_array(
desc_pool_base, attrib_count, ATTRIBUTE);
panvk_fill_img_attribs(desc_state, pipeline, bufs.cpu, attribs.cpu, 0);
desc_state->img.attrib_bufs = bufs.gpu;
desc_state->img.attribs = attribs.gpu;
}
static void
panvk_draw_emit_attrib_buf(const struct panvk_draw_info *draw,
const struct vk_vertex_binding_state *buf_info,
@@ -1142,9 +902,9 @@ panvk_draw_prepare_vs_attribs(struct panvk_cmd_buffer *cmdbuf,
memset(attribs.cpu + num_vs_attribs * pan_size(ATTRIBUTE), 0,
(MAX_VS_ATTRIBS - num_vs_attribs) * pan_size(ATTRIBUTE));
panvk_fill_img_attribs(desc_state, &pipeline->base,
bufs.cpu + bufs_offset,
attribs.cpu + attribs_offset, num_vbs * 2);
panvk_per_arch(fill_img_attribs)(
desc_state, &pipeline->base, bufs.cpu + bufs_offset,
attribs.cpu + attribs_offset, num_vbs * 2);
desc_state->img.attrib_bufs = bufs.gpu + bufs_offset;
desc_state->img.attribs = attribs.gpu + attribs_offset;
}
@@ -1170,7 +930,8 @@ panvk_draw_prepare_attributes(struct panvk_cmd_buffer *cmdbuf,
if (pipeline->fs.has_img_access) {
struct pan_pool *desc_pool_base = &cmdbuf->desc_pool.base;
panvk_prepare_img_attribs(desc_pool_base, desc_state, &pipeline->base);
panvk_per_arch(prepare_img_attribs)(desc_pool_base, desc_state,
&pipeline->base);
draw->fs.attributes = desc_state->img.attribs;
draw->fs.attribute_bufs = desc_state->img.attrib_bufs;
}
@@ -1500,7 +1261,8 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw)
panvk_cmd_prepare_draw_sysvals(cmdbuf, draw);
struct pan_pool *desc_pool_base = &cmdbuf->desc_pool.base;
panvk_cmd_prepare_push_sets(desc_pool_base, desc_state, &pipeline->base);
panvk_per_arch(cmd_prepare_push_sets)(desc_pool_base, desc_state,
&pipeline->base);
if (!cmdbuf->state.gfx.push_uniforms) {
cmdbuf->state.gfx.push_uniforms = panvk_cmd_prepare_push_uniforms(
@@ -1508,9 +1270,12 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw)
&cmdbuf->state.gfx.sysvals, sizeof(cmdbuf->state.gfx.sysvals));
}
panvk_cmd_prepare_ubos(desc_pool_base, desc_state, &pipeline->base);
panvk_cmd_prepare_textures(desc_pool_base, desc_state, &pipeline->base);
panvk_cmd_prepare_samplers(desc_pool_base, desc_state, &pipeline->base);
panvk_per_arch(cmd_prepare_ubos)(desc_pool_base, desc_state,
&pipeline->base);
panvk_per_arch(cmd_prepare_textures)(desc_pool_base, desc_state,
&pipeline->base);
panvk_per_arch(cmd_prepare_samplers)(desc_pool_base, desc_state,
&pipeline->base);
/* TODO: indexed draws */
draw->tls = batch->tls.gpu;
@@ -1545,7 +1310,7 @@ panvk_cmd_draw(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw)
/* Clear the dirty flags all at once */
cmdbuf->state.gfx.dirty = 0;
panvk_cmd_unprepare_push_sets(desc_state);
panvk_per_arch(cmd_unprepare_push_sets)(desc_state);
}
VKAPI_ATTR void VKAPI_CALL
@@ -1812,10 +1577,8 @@ panvk_reset_cmdbuf(struct vk_command_buffer *vk_cmdbuf,
panvk_pool_reset(&cmdbuf->tls_pool);
panvk_pool_reset(&cmdbuf->varying_pool);
memset(&cmdbuf->state.gfx.desc_state.sets, 0,
sizeof(cmdbuf->state.gfx.desc_state.sets));
memset(&cmdbuf->state.compute.desc_state.sets, 0,
sizeof(cmdbuf->state.compute.desc_state.sets));
panvk_per_arch(cmd_desc_state_reset)(&cmdbuf->state.gfx.desc_state,
&cmdbuf->state.compute.desc_state);
}
static void
@@ -1825,14 +1588,9 @@ panvk_destroy_cmdbuf(struct vk_command_buffer *vk_cmdbuf)
container_of(vk_cmdbuf, struct panvk_cmd_buffer, vk);
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
for (unsigned i = 0; i < MAX_SETS; i++) {
if (cmdbuf->state.gfx.desc_state.push_sets[i])
vk_free(&cmdbuf->vk.pool->alloc,
cmdbuf->state.gfx.desc_state.push_sets[i]);
if (cmdbuf->state.compute.desc_state.push_sets[i])
vk_free(&cmdbuf->vk.pool->alloc,
cmdbuf->state.compute.desc_state.push_sets[i]);
}
panvk_per_arch(cmd_desc_state_cleanup)(&cmdbuf->vk,
&cmdbuf->state.gfx.desc_state,
&cmdbuf->state.compute.desc_state);
list_for_each_entry_safe(struct panvk_batch, batch, &cmdbuf->batches, node) {
list_del(&batch->node);
@@ -1945,15 +1703,18 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x,
panvk_per_arch(cmd_alloc_tls_desc)(cmdbuf, false);
dispatch.tsd = batch->tls.gpu;
panvk_cmd_prepare_push_sets(desc_pool_base, desc_state, &pipeline->base);
panvk_per_arch(cmd_prepare_push_sets)(desc_pool_base, desc_state,
&pipeline->base);
if (pipeline->cs.has_img_access)
panvk_prepare_img_attribs(desc_pool_base, desc_state, &pipeline->base);
panvk_per_arch(prepare_img_attribs)(desc_pool_base, desc_state,
&pipeline->base);
dispatch.attributes = desc_state->img.attribs;
dispatch.attribute_bufs = desc_state->img.attrib_bufs;
panvk_cmd_prepare_ubos(desc_pool_base, desc_state, &pipeline->base);
panvk_per_arch(cmd_prepare_ubos)(desc_pool_base, desc_state,
&pipeline->base);
dispatch.ubos = desc_state->ubos;
if (!cmdbuf->state.compute.push_uniforms) {
@@ -1963,10 +1724,12 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x,
}
dispatch.push_uniforms = cmdbuf->state.compute.push_uniforms;
panvk_cmd_prepare_textures(desc_pool_base, desc_state, &pipeline->base);
panvk_per_arch(cmd_prepare_textures)(desc_pool_base, desc_state,
&pipeline->base);
dispatch.textures = desc_state->textures;
panvk_cmd_prepare_samplers(desc_pool_base, desc_state, &pipeline->base);
panvk_per_arch(cmd_prepare_samplers)(desc_pool_base, desc_state,
&pipeline->base);
dispatch.samplers = desc_state->samplers;
panfrost_pack_work_groups_compute(
@@ -2006,7 +1769,7 @@ panvk_per_arch(CmdDispatch)(VkCommandBuffer commandBuffer, uint32_t x,
}
panvk_per_arch(cmd_close_batch)(cmdbuf);
panvk_cmd_unprepare_push_sets(desc_state);
panvk_per_arch(cmd_unprepare_push_sets)(desc_state);
}
static void
@@ -2381,62 +2144,6 @@ panvk_per_arch(CmdBindIndexBuffer)(VkCommandBuffer commandBuffer,
}
}
static void
panvk_emit_dyn_ubo(struct panvk_descriptor_state *desc_state,
const struct panvk_descriptor_set *desc_set,
unsigned binding, unsigned array_idx, uint32_t dyn_offset,
unsigned dyn_ubo_slot)
{
struct mali_uniform_buffer_packed *ubo = &desc_state->dyn.ubos[dyn_ubo_slot];
const struct panvk_descriptor_set_layout *slayout = desc_set->layout;
VkDescriptorType type = slayout->bindings[binding].type;
assert(type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
assert(dyn_ubo_slot < ARRAY_SIZE(desc_state->dyn.ubos));
const unsigned dyn_ubo_idx = slayout->bindings[binding].dyn_ubo_idx;
const struct panvk_buffer_desc *bdesc =
&desc_set->dyn_ubos[dyn_ubo_idx + array_idx];
mali_ptr address =
panvk_buffer_gpu_ptr(bdesc->buffer, bdesc->offset + dyn_offset);
size_t size = panvk_buffer_range(bdesc->buffer, bdesc->offset + dyn_offset,
bdesc->size);
if (size) {
pan_pack(ubo, UNIFORM_BUFFER, cfg) {
cfg.pointer = address;
cfg.entries = DIV_ROUND_UP(size, 16);
}
} else {
memset(ubo, 0, sizeof(*ubo));
}
}
static void
panvk_emit_dyn_ssbo(struct panvk_descriptor_state *desc_state,
const struct panvk_descriptor_set *desc_set,
unsigned binding, unsigned array_idx, uint32_t dyn_offset,
unsigned dyn_ssbo_slot)
{
struct panvk_ssbo_addr *ssbo = &desc_state->dyn.ssbos[dyn_ssbo_slot];
const struct panvk_descriptor_set_layout *slayout = desc_set->layout;
VkDescriptorType type = slayout->bindings[binding].type;
assert(type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC);
assert(dyn_ssbo_slot < ARRAY_SIZE(desc_state->dyn.ssbos));
const unsigned dyn_ssbo_idx = slayout->bindings[binding].dyn_ssbo_idx;
const struct panvk_buffer_desc *bdesc =
&desc_set->dyn_ssbos[dyn_ssbo_idx + array_idx];
*ssbo = (struct panvk_ssbo_addr){
.base_addr =
panvk_buffer_gpu_ptr(bdesc->buffer, bdesc->offset + dyn_offset),
.size = panvk_buffer_range(bdesc->buffer, bdesc->offset + dyn_offset,
bdesc->size),
};
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdBindDescriptorSets)(
VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
@@ -2445,52 +2152,13 @@ panvk_per_arch(CmdBindDescriptorSets)(
const uint32_t *pDynamicOffsets)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
VK_FROM_HANDLE(panvk_pipeline_layout, playout, layout);
struct panvk_descriptor_state *descriptors_state =
struct panvk_descriptor_state *desc_state =
panvk_cmd_get_desc_state(cmdbuf, pipelineBindPoint);
unsigned dynoffset_idx = 0;
for (unsigned i = 0; i < descriptorSetCount; ++i) {
unsigned idx = i + firstSet;
VK_FROM_HANDLE(panvk_descriptor_set, set, pDescriptorSets[i]);
descriptors_state->sets[idx] = set;
if (set->layout->num_dyn_ssbos || set->layout->num_dyn_ubos) {
unsigned dyn_ubo_slot = playout->sets[idx].dyn_ubo_offset;
unsigned dyn_ssbo_slot = playout->sets[idx].dyn_ssbo_offset;
for (unsigned b = 0; b < set->layout->binding_count; b++) {
for (unsigned e = 0; e < set->layout->bindings[b].array_size; e++) {
VkDescriptorType type = set->layout->bindings[b].type;
if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
panvk_emit_dyn_ubo(descriptors_state, set, b, e,
pDynamicOffsets[dynoffset_idx++],
dyn_ubo_slot++);
} else if (type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) {
panvk_emit_dyn_ssbo(descriptors_state, set, b, e,
pDynamicOffsets[dynoffset_idx++],
dyn_ssbo_slot++);
}
}
}
}
}
/* Unconditionally reset all previously emitted descriptors tables.
* TODO: we could be smarter by checking which part of the pipeline layout
* are compatible with the previouly bound descriptor sets.
*/
descriptors_state->ubos = 0;
descriptors_state->textures = 0;
descriptors_state->samplers = 0;
descriptors_state->dyn_desc_ubo = 0;
descriptors_state->img.attrib_bufs = 0;
descriptors_state->img.attribs = 0;
assert(dynoffset_idx == dynamicOffsetCount);
panvk_per_arch(cmd_desc_state_bind_sets)(
desc_state, layout, firstSet, descriptorSetCount, pDescriptorSets,
dynamicOffsetCount, pDynamicOffsets);
}
VKAPI_ATTR void VKAPI_CALL
@@ -2574,36 +2242,6 @@ panvk_per_arch(CmdDispatchIndirect)(VkCommandBuffer commandBuffer,
panvk_stub();
}
static struct panvk_push_descriptor_set *
panvk_cmd_push_descriptors(struct vk_command_buffer *vk_cmdbuf,
struct panvk_descriptor_state *desc_state,
uint32_t set)
{
assert(set < MAX_SETS);
if (unlikely(desc_state->push_sets[set] == NULL)) {
desc_state->push_sets[set] =
vk_zalloc(&vk_cmdbuf->pool->alloc, sizeof(*desc_state->push_sets[0]),
8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (unlikely(desc_state->push_sets[set] == NULL)) {
vk_command_buffer_set_error(vk_cmdbuf, VK_ERROR_OUT_OF_HOST_MEMORY);
return NULL;
}
}
/* Pushing descriptors replaces whatever sets are bound */
desc_state->sets[set] = NULL;
/* Reset all descs to force emission of new tables on the next draw/dispatch.
* TODO: Be smarter and only reset those when required.
*/
desc_state->ubos = 0;
desc_state->textures = 0;
desc_state->samplers = 0;
desc_state->img.attrib_bufs = 0;
desc_state->img.attribs = 0;
return desc_state->push_sets[set];
}
VKAPI_ATTR void VKAPI_CALL
panvk_per_arch(CmdPushDescriptorSetKHR)(
VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint,
@@ -2617,7 +2255,7 @@ panvk_per_arch(CmdPushDescriptorSetKHR)(
struct panvk_descriptor_state *desc_state =
panvk_cmd_get_desc_state(cmdbuf, pipelineBindPoint);
struct panvk_push_descriptor_set *push_set =
panvk_cmd_push_descriptors(&cmdbuf->vk, desc_state, set);
panvk_per_arch(cmd_push_descriptors)(&cmdbuf->vk, desc_state, set);
if (!push_set)
return;
@@ -2640,7 +2278,7 @@ panvk_per_arch(CmdPushDescriptorSetWithTemplateKHR)(
struct panvk_descriptor_state *desc_state =
panvk_cmd_get_desc_state(cmdbuf, template->bind_point);
struct panvk_push_descriptor_set *push_set =
panvk_cmd_push_descriptors(&cmdbuf->vk, desc_state, set);
panvk_per_arch(cmd_push_descriptors)(&cmdbuf->vk, desc_state, set);
if (!push_set)
return;
+1
View File
@@ -55,6 +55,7 @@ panvk_per_arch_libs = []
bifrost_archs = [6, 7]
bifrost_inc_dir = ['bifrost']
bifrost_files = [
'bifrost/panvk_vX_cmd_desc_state.c',
'bifrost/panvk_vX_descriptor_set.c',
'bifrost/panvk_vX_descriptor_set_layout.c',
'bifrost/panvk_vX_nir_lower_descriptors.c',