Mesa (main): panfrost: Add helpers to emit Valhall data structures
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Apr 7 18:02:37 UTC 2022
Module: Mesa
Branch: main
Commit: 8689a88d10e4998ce2eb86491353cb0c1d69d927
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=8689a88d10e4998ce2eb86491353cb0c1d69d927
Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date: Thu Apr 7 11:26:10 2022 -0400
panfrost: Add helpers to emit Valhall data structures
Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15797>
---
src/gallium/drivers/panfrost/pan_cmdstream.c | 222 +++++++++++++++++++++++++++
1 file changed, 222 insertions(+)
diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c
index 8b8bed36bdf..bcab9165284 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -758,6 +758,228 @@ panfrost_emit_viewport(struct panfrost_batch *batch)
#endif
}
+#if PAN_ARCH >= 9
+/**
+ * Emit a Valhall depth/stencil descriptor at draw-time. The bulk of the
+ * descriptor corresponds to a pipe_depth_stencil_alpha CSO and is packed at
+ * CSO create time. However, the stencil reference values and shader
+ * interactions are dynamic state. Pack only the dynamic state here and OR
+ * together.
+ */
+static mali_ptr
+panfrost_emit_depth_stencil(struct panfrost_batch *batch)
+{
+ struct panfrost_context *ctx = batch->ctx;
+ const struct panfrost_zsa_state *zsa = ctx->depth_stencil;
+ struct panfrost_rasterizer *rast = ctx->rasterizer;
+ struct panfrost_shader_state *fs = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
+ bool back_enab = zsa->base.stencil[1].enabled;
+
+ struct panfrost_ptr T = pan_pool_alloc_desc(&batch->pool.base, DEPTH_STENCIL);
+ struct mali_depth_stencil_packed dynamic;
+
+ pan_pack(&dynamic, DEPTH_STENCIL, cfg) {
+ cfg.front_reference_value = ctx->stencil_ref.ref_value[0];
+ cfg.back_reference_value = ctx->stencil_ref.ref_value[back_enab ? 1 : 0];
+
+ cfg.stencil_from_shader = fs->info.fs.writes_stencil;
+ cfg.depth_source = pan_depth_source(&fs->info);
+
+ cfg.depth_bias_enable = rast->base.offset_tri;
+ cfg.depth_units = rast->base.offset_units * 2.0f;
+ cfg.depth_factor = rast->base.offset_scale;
+ cfg.depth_bias_clamp = rast->base.offset_clamp;
+ }
+
+ pan_merge(dynamic, zsa->desc, DEPTH_STENCIL);
+ memcpy(T.cpu, &dynamic, pan_size(DEPTH_STENCIL));
+
+ return T.gpu;
+}
+
+/**
+ * Emit Valhall blend descriptor at draw-time. The descriptor itself is shared
+ * with Bifrost, but the container data structure is simplified.
+ */
+static mali_ptr
+panfrost_emit_blend_valhall(struct panfrost_batch *batch)
+{
+ unsigned rt_count = MAX2(batch->key.nr_cbufs, 1);
+
+ struct panfrost_ptr T = pan_pool_alloc_desc_array(&batch->pool.base, rt_count, BLEND);
+
+ mali_ptr blend_shaders[PIPE_MAX_COLOR_BUFS] = { 0 };
+ panfrost_get_blend_shaders(batch, blend_shaders);
+
+ panfrost_emit_blend(batch, T.cpu, blend_shaders);
+
+ /* Precalculate for the per-draw path */
+ bool has_blend_shader = false;
+
+ for (unsigned i = 0; i < rt_count; ++i)
+ has_blend_shader |= !!blend_shaders[i];
+
+ batch->ctx->valhall_has_blend_shader = has_blend_shader;
+
+ return T.gpu;
+}
+
+/**
+ * Emit Valhall buffer descriptors for bound vertex buffers at draw-time.
+ */
+static mali_ptr
+panfrost_emit_vertex_buffers(struct panfrost_batch *batch)
+{
+ struct panfrost_context *ctx = batch->ctx;
+ unsigned buffer_count = util_last_bit(ctx->vb_mask);
+ struct panfrost_ptr T = pan_pool_alloc_desc_array(&batch->pool.base,
+ buffer_count, BUFFER);
+ struct mali_buffer_packed *buffers = T.cpu;
+
+ u_foreach_bit(i, ctx->vb_mask) {
+ struct pipe_vertex_buffer vb = ctx->vertex_buffers[i];
+ struct pipe_resource *prsrc = vb.buffer.resource;
+ struct panfrost_resource *rsrc = pan_resource(prsrc);
+ assert(!vb.is_user_buffer);
+
+ panfrost_batch_read_rsrc(batch, rsrc, PIPE_SHADER_VERTEX);
+
+ pan_pack(buffers + i, BUFFER, cfg) {
+ cfg.address = rsrc->image.data.bo->ptr.gpu +
+ vb.buffer_offset;
+
+ cfg.size = prsrc->width0 - vb.buffer_offset;
+ }
+ }
+
+ return T.gpu;
+}
+
+/**
+ * Emit Valhall attribute descriptors and associated (vertex) buffer
+ * descriptors at draw-time. The attribute descriptors are packed at draw time
+ * except for the stride field. The buffer descriptors are packed here, though
+ * that could be moved into panfrost_set_vertex_buffers if needed.
+ */
+static mali_ptr
+panfrost_emit_vertex_data(struct panfrost_batch *batch)
+{
+ struct panfrost_context *ctx = batch->ctx;
+ struct panfrost_vertex_state *vtx = ctx->vertex;
+ struct panfrost_ptr T = pan_pool_alloc_desc_array(&batch->pool.base,
+ vtx->num_elements,
+ ATTRIBUTE);
+ struct mali_attribute_packed *attributes = T.cpu;
+
+ for (unsigned i = 0; i < vtx->num_elements; ++i) {
+ struct mali_attribute_packed packed;
+ unsigned vbi = vtx->pipe[i].vertex_buffer_index;
+
+ pan_pack(&packed, ATTRIBUTE, cfg) {
+ cfg.stride = ctx->vertex_buffers[vbi].stride;
+ }
+
+ pan_merge(packed, vtx->attributes[i], ATTRIBUTE);
+ attributes[i] = packed;
+ }
+
+ return T.gpu;
+}
+
+/*
+ * Emit Valhall descriptors for shader images. Unlike previous generations,
+ * Valhall does not have a special descriptor for images. Standard texture
+ * descriptors are used. The binding is different in Gallium, however, so we
+ * translate.
+ */
+static struct pipe_sampler_view
+panfrost_pipe_image_to_sampler_view(struct pipe_image_view *v)
+{
+ struct pipe_sampler_view out = {
+ .format = v->format,
+ .texture = v->resource,
+ .target = v->resource->target,
+ .swizzle_r = PIPE_SWIZZLE_X,
+ .swizzle_g = PIPE_SWIZZLE_Y,
+ .swizzle_b = PIPE_SWIZZLE_Z,
+ .swizzle_a = PIPE_SWIZZLE_W
+ };
+
+ if (out.target == PIPE_BUFFER) {
+ out.u.buf.offset = v->u.buf.offset;
+ out.u.buf.size = v->u.buf.size;
+ } else {
+ out.u.tex.first_layer = v->u.tex.first_layer;
+ out.u.tex.last_layer = v->u.tex.last_layer;
+
+ /* Single level only */
+ out.u.tex.first_level = v->u.tex.level;
+ out.u.tex.last_level = v->u.tex.level;
+ }
+
+ return out;
+}
+
+static void
+panfrost_update_sampler_view(struct panfrost_sampler_view *view,
+ struct pipe_context *pctx);
+
+static mali_ptr
+panfrost_emit_images(struct panfrost_batch *batch, enum pipe_shader_type stage)
+{
+ struct panfrost_context *ctx = batch->ctx;
+ unsigned last_bit = util_last_bit(ctx->image_mask[stage]);
+
+ struct panfrost_ptr T =
+ pan_pool_alloc_desc_array(&batch->pool.base, last_bit, TEXTURE);
+
+ struct mali_texture_packed *out = (struct mali_texture_packed *) T.cpu;
+
+ for (int i = 0; i < last_bit; ++i) {
+ struct pipe_image_view *image = &ctx->images[stage][i];
+
+ if (!(ctx->image_mask[stage] & BITFIELD_BIT(i))) {
+ memset(&out[i], 0, sizeof(out[i]));
+ continue;
+ }
+
+ /* Construct a synthetic sampler view so we can use our usual
+ * sampler view code for the actual descriptor packing.
+ *
+ * Use the batch pool for a transient allocation, rather than
+ * allocating a long-lived descriptor.
+ */
+ struct panfrost_sampler_view view = {
+ .base = panfrost_pipe_image_to_sampler_view(image),
+ .pool = &batch->pool
+ };
+
+ /* If we specify a cube map, the hardware internally treat it as
+ * a 2D array. Since cube maps as images can confuse our common
+ * texturing code, explicitly use a 2D array.
+ *
+ * Similar concerns apply to 3D textures.
+ */
+ if (view.base.target == PIPE_BUFFER) {
+ view.base.target = PIPE_BUFFER;
+ } else {
+ view.base.target = PIPE_TEXTURE_2D_ARRAY;
+
+ /* Hardware limitation */
+ if (view.base.u.tex.first_level != 0)
+ unreachable("TODO: mipmaps special handling");
+ }
+
+ panfrost_update_sampler_view(&view, &ctx->base);
+ out[i] = view.bifrost_descriptor;
+
+ panfrost_track_image_access(batch, stage, image);
+ }
+
+ return T.gpu;
+}
+#endif
+
static mali_ptr
panfrost_map_constant_buffer_gpu(struct panfrost_batch *batch,
enum pipe_shader_type st,
More information about the mesa-commit
mailing list