panvk: Move VkPipelineLayout logic to its own file

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com>
Reviewed-by: Rebecca Mckeever <rebecca.mckeever@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28170>
This commit is contained in:
Boris Brezillon 2023-12-18 16:57:57 +01:00 committed by Marge Bot
parent 2da06e6628
commit 80947ae1d2
12 changed files with 228 additions and 179 deletions

View file

@ -74,6 +74,7 @@ foreach arch : ['6', '7']
'panvk_vX_meta_clear.c',
'panvk_vX_nir_lower_descriptors.c',
'panvk_vX_pipeline.c',
'panvk_vX_pipeline_layout.c',
'panvk_vX_sampler.c',
'panvk_vX_shader.c',
],

View file

@ -28,6 +28,7 @@
#include "panvk_buffer.h"
#include "panvk_pipeline.h"
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"
#include "pan_encoder.h"

View file

@ -27,7 +27,6 @@
#include "panvk_descriptor_set.h"
#include "panvk_private.h"
#include "panvk_sampler.h"
#include <assert.h>
#include <fcntl.h>
@ -39,98 +38,6 @@
#include "vk_descriptors.h"
#include "vk_util.h"
/*
* Pipeline layouts. These have nothing to do with the pipeline. They are
* just multiple descriptor set layouts pasted together.
*/
VKAPI_ATTR VkResult VKAPI_CALL
panvk_CreatePipelineLayout(VkDevice _device,
const VkPipelineLayoutCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkPipelineLayout *pPipelineLayout)
{
VK_FROM_HANDLE(panvk_device, device, _device);
struct panvk_pipeline_layout *layout;
struct mesa_sha1 ctx;
layout =
vk_pipeline_layout_zalloc(&device->vk, sizeof(*layout), pCreateInfo);
if (layout == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
_mesa_sha1_init(&ctx);
unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0;
unsigned dyn_ubo_idx = 0, dyn_ssbo_idx = 0, img_idx = 0;
for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++) {
const struct panvk_descriptor_set_layout *set_layout =
vk_to_panvk_descriptor_set_layout(layout->vk.set_layouts[set]);
layout->sets[set].sampler_offset = sampler_idx;
layout->sets[set].tex_offset = tex_idx;
layout->sets[set].ubo_offset = ubo_idx;
layout->sets[set].dyn_ubo_offset = dyn_ubo_idx;
layout->sets[set].dyn_ssbo_offset = dyn_ssbo_idx;
layout->sets[set].img_offset = img_idx;
sampler_idx += set_layout->num_samplers;
tex_idx += set_layout->num_textures;
ubo_idx += set_layout->num_ubos;
dyn_ubo_idx += set_layout->num_dyn_ubos;
dyn_ssbo_idx += set_layout->num_dyn_ssbos;
img_idx += set_layout->num_imgs;
for (unsigned b = 0; b < set_layout->binding_count; b++) {
const struct panvk_descriptor_set_binding_layout *binding_layout =
&set_layout->bindings[b];
if (binding_layout->immutable_samplers) {
for (unsigned s = 0; s < binding_layout->array_size; s++) {
struct panvk_sampler *sampler =
binding_layout->immutable_samplers[s];
_mesa_sha1_update(&ctx, &sampler->desc, sizeof(sampler->desc));
}
}
_mesa_sha1_update(&ctx, &binding_layout->type,
sizeof(binding_layout->type));
_mesa_sha1_update(&ctx, &binding_layout->array_size,
sizeof(binding_layout->array_size));
_mesa_sha1_update(&ctx, &binding_layout->shader_stages,
sizeof(binding_layout->shader_stages));
}
}
for (unsigned range = 0; range < pCreateInfo->pushConstantRangeCount;
range++) {
layout->push_constants.size =
MAX2(pCreateInfo->pPushConstantRanges[range].offset +
pCreateInfo->pPushConstantRanges[range].size,
layout->push_constants.size);
}
layout->num_samplers = sampler_idx;
layout->num_textures = tex_idx;
layout->num_ubos = ubo_idx;
layout->num_dyn_ubos = dyn_ubo_idx;
layout->num_dyn_ssbos = dyn_ssbo_idx;
layout->num_imgs = img_idx;
/* Some NIR texture operations don't require a sampler, but Bifrost/Midgard
* ones always expect one. Add a dummy sampler to deal with this limitation.
*/
if (layout->num_textures) {
layout->num_samplers++;
for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++)
layout->sets[set].sampler_offset++;
}
_mesa_sha1_final(&ctx, layout->sha1);
*pPipelineLayout = panvk_pipeline_layout_to_handle(layout);
return VK_SUCCESS;
}
VKAPI_ATTR VkResult VKAPI_CALL
panvk_CreateDescriptorPool(VkDevice _device,
const VkDescriptorPoolCreateInfo *pCreateInfo,

View file

@ -0,0 +1,60 @@
/*
* Copyright © 2021 Collabora Ltd.
* SPDX-License-Identifier: MIT
*/
#ifndef PANVK_PIPELINE_LAYOUT_H
#define PANVK_PIPELINE_LAYOUT_H
#include <stdint.h>
#include "vulkan/runtime/vk_pipeline_layout.h"
#include "panvk_descriptor_set_layout.h"
#include "panvk_macros.h"
#define MAX_SETS 4
#define MAX_DYNAMIC_UNIFORM_BUFFERS 16
#define MAX_DYNAMIC_STORAGE_BUFFERS 8
#define MAX_DYNAMIC_BUFFERS \
(MAX_DYNAMIC_UNIFORM_BUFFERS + MAX_DYNAMIC_STORAGE_BUFFERS)
struct panvk_pipeline_layout {
struct vk_pipeline_layout vk;
unsigned char sha1[20];
unsigned num_samplers;
unsigned num_textures;
unsigned num_ubos;
unsigned num_dyn_ubos;
unsigned num_dyn_ssbos;
uint32_t num_imgs;
struct {
uint32_t size;
} push_constants;
struct {
unsigned sampler_offset;
unsigned tex_offset;
unsigned ubo_offset;
unsigned dyn_ubo_offset;
unsigned dyn_ssbo_offset;
unsigned img_offset;
} sets[MAX_SETS];
};
VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline_layout, vk.base, VkPipelineLayout,
VK_OBJECT_TYPE_PIPELINE_LAYOUT)
#ifdef PAN_ARCH
unsigned panvk_per_arch(pipeline_layout_ubo_start)(
const struct panvk_pipeline_layout *layout, unsigned set, bool is_dynamic);
unsigned panvk_per_arch(pipeline_layout_ubo_index)(
const struct panvk_pipeline_layout *layout, unsigned set, unsigned binding,
unsigned array_index);
#endif
#endif

View file

@ -72,6 +72,7 @@
#include "panvk_macros.h"
#include "panvk_mempool.h"
#include "panvk_pipeline.h"
#include "panvk_pipeline_layout.h"
#include "panvk_varyings.h"
#include "vk_extensions.h"
@ -90,20 +91,16 @@ typedef uint32_t xcb_window_t;
#include "panvk_entrypoints.h"
#define MAX_BIND_POINTS 2 /* compute + graphics */
#define MAX_VBS 16
#define MAX_VERTEX_ATTRIBS 16
#define MAX_VSC_PIPES 32
#define MAX_SCISSORS 16
#define MAX_DISCARD_RECTANGLES 4
#define MAX_PUSH_CONSTANTS_SIZE 128
#define MAX_DYNAMIC_UNIFORM_BUFFERS 16
#define MAX_DYNAMIC_STORAGE_BUFFERS 8
#define MAX_DYNAMIC_BUFFERS \
(MAX_DYNAMIC_UNIFORM_BUFFERS + MAX_DYNAMIC_STORAGE_BUFFERS)
#define MAX_SAMPLES_LOG2 4
#define NUM_META_FS_KEYS 13
#define MAX_VIEWS 8
#define MAX_BIND_POINTS 2 /* compute + graphics */
#define MAX_VBS 16
#define MAX_VERTEX_ATTRIBS 16
#define MAX_VSC_PIPES 32
#define MAX_SCISSORS 16
#define MAX_DISCARD_RECTANGLES 4
#define MAX_PUSH_CONSTANTS_SIZE 128
#define MAX_SAMPLES_LOG2 4
#define NUM_META_FS_KEYS 13
#define MAX_VIEWS 8
#define NUM_DEPTH_CLEAR_PIPELINES 3
@ -112,6 +109,7 @@ typedef uint32_t xcb_window_t;
#define PANVK_NUM_BUILTIN_UBOS 2
struct panvk_device;
struct panvk_pipeline_layout;
/* Used for internal object allocation. */
struct panvk_priv_bo {
@ -338,69 +336,6 @@ struct panvk_cmd_event_op {
struct panvk_event *event;
};
#define MAX_SETS 4
struct panvk_pipeline_layout {
struct vk_pipeline_layout vk;
unsigned char sha1[20];
unsigned num_samplers;
unsigned num_textures;
unsigned num_ubos;
unsigned num_dyn_ubos;
unsigned num_dyn_ssbos;
uint32_t num_imgs;
struct {
uint32_t size;
} push_constants;
struct {
unsigned sampler_offset;
unsigned tex_offset;
unsigned ubo_offset;
unsigned dyn_ubo_offset;
unsigned dyn_ssbo_offset;
unsigned img_offset;
} sets[MAX_SETS];
};
static unsigned
panvk_pipeline_layout_ubo_start(const struct panvk_pipeline_layout *layout,
unsigned set, bool is_dynamic)
{
const struct panvk_descriptor_set_layout *set_layout =
vk_to_panvk_descriptor_set_layout(layout->vk.set_layouts[set]);
unsigned offset = PANVK_NUM_BUILTIN_UBOS + layout->sets[set].ubo_offset +
layout->sets[set].dyn_ubo_offset;
if (is_dynamic)
offset += set_layout->num_ubos;
return offset;
}
static unsigned
panvk_pipeline_layout_ubo_index(const struct panvk_pipeline_layout *layout,
unsigned set, unsigned binding,
unsigned array_index)
{
const struct panvk_descriptor_set_layout *set_layout =
vk_to_panvk_descriptor_set_layout(layout->vk.set_layouts[set]);
const struct panvk_descriptor_set_binding_layout *binding_layout =
&set_layout->bindings[binding];
const bool is_dynamic =
binding_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
const uint32_t ubo_idx =
is_dynamic ? binding_layout->dyn_ubo_idx : binding_layout->ubo_idx;
return panvk_pipeline_layout_ubo_start(layout, set, is_dynamic) + ubo_idx +
array_index;
}
enum panvk_dynamic_state_bits {
PANVK_DYNAMIC_VIEWPORT = 1 << 0,
PANVK_DYNAMIC_SCISSOR = 1 << 1,
@ -648,8 +583,6 @@ VK_DEFINE_HANDLE_CASTS(panvk_queue, vk.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_cmd_pool, vk.base, VkCommandPool,
VK_OBJECT_TYPE_COMMAND_POOL)
VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_pipeline_layout, vk.base, VkPipelineLayout,
VK_OBJECT_TYPE_PIPELINE_LAYOUT)
#ifdef PAN_ARCH
#include "panvk_vX_cmd_buffer.h"

View file

@ -34,6 +34,7 @@
#include "panvk_image.h"
#include "panvk_image_view.h"
#include "panvk_pipeline.h"
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"
#include "pan_blitter.h"

View file

@ -37,6 +37,7 @@
#include "panvk_buffer.h"
#include "panvk_cs.h"
#include "panvk_pipeline.h"
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"
#include "panvk_varyings.h"
@ -284,7 +285,7 @@ panvk_per_arch(emit_ubos)(const struct panvk_pipeline *pipeline,
const struct panvk_descriptor_set *set = state->sets[s];
unsigned ubo_start =
panvk_pipeline_layout_ubo_start(pipeline->layout, s, false);
panvk_per_arch(pipeline_layout_ubo_start)(pipeline->layout, s, false);
if (!set) {
unsigned all_ubos = set_layout->num_ubos + set_layout->num_dyn_ubos;
@ -293,8 +294,8 @@ panvk_per_arch(emit_ubos)(const struct panvk_pipeline *pipeline,
memcpy(&ubos[ubo_start], set->ubos,
set_layout->num_ubos * sizeof(*ubos));
unsigned dyn_ubo_start =
panvk_pipeline_layout_ubo_start(pipeline->layout, s, true);
unsigned dyn_ubo_start = panvk_per_arch(pipeline_layout_ubo_start)(
pipeline->layout, s, true);
for (unsigned i = 0; i < set_layout->num_dyn_ubos; i++) {
const struct panvk_buffer_desc *bdesc =

View file

@ -7,6 +7,7 @@
#include "panvk_descriptor_set.h"
#include "panvk_descriptor_set_layout.h"
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"
#include "panvk_sampler.h"

View file

@ -27,6 +27,7 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"
#include "nir.h"
@ -109,8 +110,8 @@ build_res_index(nir_builder *b, uint32_t set, uint32_t binding,
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: {
assert(addr_format == nir_address_format_32bit_index_offset);
const unsigned ubo_idx =
panvk_pipeline_layout_ubo_index(ctx->layout, set, binding, 0);
const unsigned ubo_idx = panvk_per_arch(pipeline_layout_ubo_index)(
ctx->layout, set, binding, 0);
const uint32_t packed = (array_size - 1) << 16 | ubo_idx;
@ -122,7 +123,7 @@ build_res_index(nir_builder *b, uint32_t set, uint32_t binding,
addr_format == nir_address_format_64bit_global_32bit_offset);
const unsigned set_ubo_idx =
panvk_pipeline_layout_ubo_start(ctx->layout, set, false) +
panvk_per_arch(pipeline_layout_ubo_start)(ctx->layout, set, false) +
set_layout->desc_ubo_index;
const uint32_t packed =
@ -325,7 +326,7 @@ load_resource_deref_desc(nir_builder *b, nir_deref_instr *deref,
index_ssa = nir_imm_int(b, index_imm);
const unsigned set_ubo_idx =
panvk_pipeline_layout_ubo_start(ctx->layout, set, false) +
panvk_per_arch(pipeline_layout_ubo_start)(ctx->layout, set, false) +
set_layout->desc_ubo_index;
nir_def *desc_ubo_offset =

View file

@ -28,6 +28,7 @@
#include "panvk_cs.h"
#include "panvk_pipeline.h"
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"
#include "nir/nir.h"

View file

@ -0,0 +1,141 @@
/*
* Copyright © 2021 Collabora Ltd.
*
* SPDX-License-Identifier: MIT
*/
#include "genxml/gen_macros.h"
#include "panvk_entrypoints.h"
#include "panvk_macros.h"
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"
#include "panvk_sampler.h"
#include "util/mesa-sha1.h"
/*
* Pipeline layouts. These have nothing to do with the pipeline. They are
* just multiple descriptor set layouts pasted together.
*/
VKAPI_ATTR VkResult VKAPI_CALL
panvk_per_arch(CreatePipelineLayout)(
VkDevice _device, const VkPipelineLayoutCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout)
{
VK_FROM_HANDLE(panvk_device, device, _device);
struct panvk_pipeline_layout *layout;
struct mesa_sha1 ctx;
layout =
vk_pipeline_layout_zalloc(&device->vk, sizeof(*layout), pCreateInfo);
if (layout == NULL)
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
_mesa_sha1_init(&ctx);
unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0;
unsigned dyn_ubo_idx = 0, dyn_ssbo_idx = 0, img_idx = 0;
for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++) {
const struct panvk_descriptor_set_layout *set_layout =
vk_to_panvk_descriptor_set_layout(layout->vk.set_layouts[set]);
layout->sets[set].sampler_offset = sampler_idx;
layout->sets[set].tex_offset = tex_idx;
layout->sets[set].ubo_offset = ubo_idx;
layout->sets[set].dyn_ubo_offset = dyn_ubo_idx;
layout->sets[set].dyn_ssbo_offset = dyn_ssbo_idx;
layout->sets[set].img_offset = img_idx;
sampler_idx += set_layout->num_samplers;
tex_idx += set_layout->num_textures;
ubo_idx += set_layout->num_ubos;
dyn_ubo_idx += set_layout->num_dyn_ubos;
dyn_ssbo_idx += set_layout->num_dyn_ssbos;
img_idx += set_layout->num_imgs;
for (unsigned b = 0; b < set_layout->binding_count; b++) {
const struct panvk_descriptor_set_binding_layout *binding_layout =
&set_layout->bindings[b];
if (binding_layout->immutable_samplers) {
for (unsigned s = 0; s < binding_layout->array_size; s++) {
struct panvk_sampler *sampler =
binding_layout->immutable_samplers[s];
_mesa_sha1_update(&ctx, &sampler->desc, sizeof(sampler->desc));
}
}
_mesa_sha1_update(&ctx, &binding_layout->type,
sizeof(binding_layout->type));
_mesa_sha1_update(&ctx, &binding_layout->array_size,
sizeof(binding_layout->array_size));
_mesa_sha1_update(&ctx, &binding_layout->shader_stages,
sizeof(binding_layout->shader_stages));
}
}
for (unsigned range = 0; range < pCreateInfo->pushConstantRangeCount;
range++) {
layout->push_constants.size =
MAX2(pCreateInfo->pPushConstantRanges[range].offset +
pCreateInfo->pPushConstantRanges[range].size,
layout->push_constants.size);
}
layout->num_samplers = sampler_idx;
layout->num_textures = tex_idx;
layout->num_ubos = ubo_idx;
layout->num_dyn_ubos = dyn_ubo_idx;
layout->num_dyn_ssbos = dyn_ssbo_idx;
layout->num_imgs = img_idx;
/* Some NIR texture operations don't require a sampler, but Bifrost/Midgard
* ones always expect one. Add a dummy sampler to deal with this limitation.
*/
if (layout->num_textures) {
layout->num_samplers++;
for (unsigned set = 0; set < pCreateInfo->setLayoutCount; set++)
layout->sets[set].sampler_offset++;
}
_mesa_sha1_final(&ctx, layout->sha1);
*pPipelineLayout = panvk_pipeline_layout_to_handle(layout);
return VK_SUCCESS;
}
unsigned
panvk_per_arch(pipeline_layout_ubo_start)(
const struct panvk_pipeline_layout *layout, unsigned set, bool is_dynamic)
{
const struct panvk_descriptor_set_layout *set_layout =
vk_to_panvk_descriptor_set_layout(layout->vk.set_layouts[set]);
unsigned offset = PANVK_NUM_BUILTIN_UBOS + layout->sets[set].ubo_offset +
layout->sets[set].dyn_ubo_offset;
if (is_dynamic)
offset += set_layout->num_ubos;
return offset;
}
unsigned
panvk_per_arch(pipeline_layout_ubo_index)(
const struct panvk_pipeline_layout *layout, unsigned set, unsigned binding,
unsigned array_index)
{
const struct panvk_descriptor_set_layout *set_layout =
vk_to_panvk_descriptor_set_layout(layout->vk.set_layouts[set]);
const struct panvk_descriptor_set_binding_layout *binding_layout =
&set_layout->bindings[binding];
const bool is_dynamic =
binding_layout->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
const uint32_t ubo_idx =
is_dynamic ? binding_layout->dyn_ubo_idx : binding_layout->ubo_idx;
return panvk_per_arch(pipeline_layout_ubo_start)(layout, set, is_dynamic) +
ubo_idx + array_index;
}

View file

@ -29,6 +29,7 @@
#include "genxml/gen_macros.h"
#include "panvk_pipeline_layout.h"
#include "panvk_private.h"
#include "spirv/nir_spirv.h"