19f464c52Smaya/*
29f464c52Smaya * © Copyright 2018 Alyssa Rosenzweig
39f464c52Smaya *
49f464c52Smaya * Permission is hereby granted, free of charge, to any person obtaining a
59f464c52Smaya * copy of this software and associated documentation files (the "Software"),
69f464c52Smaya * to deal in the Software without restriction, including without limitation
79f464c52Smaya * the rights to use, copy, modify, merge, publish, distribute, sublicense,
89f464c52Smaya * and/or sell copies of the Software, and to permit persons to whom the
99f464c52Smaya * Software is furnished to do so, subject to the following conditions:
109f464c52Smaya *
119f464c52Smaya * The above copyright notice and this permission notice (including the next
129f464c52Smaya * paragraph) shall be included in all copies or substantial portions of the
139f464c52Smaya * Software.
149f464c52Smaya *
159f464c52Smaya * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
169f464c52Smaya * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
179f464c52Smaya * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
189f464c52Smaya * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
199f464c52Smaya * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
209f464c52Smaya * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
219f464c52Smaya * SOFTWARE.
229f464c52Smaya *
239f464c52Smaya */
249f464c52Smaya
259f464c52Smaya#ifndef __BUILDER_H__
269f464c52Smaya#define __BUILDER_H__
279f464c52Smaya
289f464c52Smaya#define _LARGEFILE64_SOURCE 1
299f464c52Smaya#include <sys/mman.h>
309f464c52Smaya#include <assert.h>
319f464c52Smaya#include "pan_resource.h"
329f464c52Smaya#include "pan_job.h"
337ec681f3Smrg#include "pan_blend_cso.h"
347ec681f3Smrg#include "pan_encoder.h"
357ec681f3Smrg#include "pan_texture.h"
369f464c52Smaya
379f464c52Smaya#include "pipe/p_compiler.h"
389f464c52Smaya#include "pipe/p_config.h"
399f464c52Smaya#include "pipe/p_context.h"
409f464c52Smaya#include "pipe/p_defines.h"
419f464c52Smaya#include "pipe/p_format.h"
429f464c52Smaya#include "pipe/p_screen.h"
439f464c52Smaya#include "pipe/p_state.h"
449f464c52Smaya#include "util/u_blitter.h"
459f464c52Smaya#include "util/hash_table.h"
467ec681f3Smrg#include "util/simple_mtx.h"
479f464c52Smaya
489f464c52Smaya#include "midgard/midgard_compile.h"
497ec681f3Smrg#include "compiler/shader_enums.h"
509f464c52Smaya
519f464c52Smaya/* Forward declare to avoid extra header dep */
529f464c52Smayastruct prim_convert_context;
539f464c52Smaya
549f464c52Smaya#define SET_BIT(lval, bit, cond) \
559f464c52Smaya	if (cond) \
569f464c52Smaya		lval |= (bit); \
579f464c52Smaya	else \
589f464c52Smaya		lval &= ~(bit);
599f464c52Smaya
607ec681f3Smrg/* Dirty tracking flags. 3D is for general 3D state. Shader flags are
617ec681f3Smrg * per-stage. Renderer refers to Renderer State Descriptors. Vertex refers to
627ec681f3Smrg * vertex attributes/elements. */
637ec681f3Smrg
647ec681f3Smrgenum pan_dirty_3d {
657ec681f3Smrg        PAN_DIRTY_VIEWPORT       = BITFIELD_BIT(0),
667ec681f3Smrg        PAN_DIRTY_SCISSOR        = BITFIELD_BIT(1),
677ec681f3Smrg        PAN_DIRTY_VERTEX         = BITFIELD_BIT(2),
687ec681f3Smrg        PAN_DIRTY_PARAMS         = BITFIELD_BIT(3),
697ec681f3Smrg        PAN_DIRTY_DRAWID         = BITFIELD_BIT(4),
707ec681f3Smrg        PAN_DIRTY_TLS_SIZE       = BITFIELD_BIT(5),
717ec681f3Smrg};
727ec681f3Smrg
737ec681f3Smrgenum pan_dirty_shader {
747ec681f3Smrg        PAN_DIRTY_STAGE_RENDERER = BITFIELD_BIT(0),
757ec681f3Smrg        PAN_DIRTY_STAGE_TEXTURE  = BITFIELD_BIT(1),
767ec681f3Smrg        PAN_DIRTY_STAGE_SAMPLER  = BITFIELD_BIT(2),
777ec681f3Smrg        PAN_DIRTY_STAGE_IMAGE    = BITFIELD_BIT(3),
787ec681f3Smrg        PAN_DIRTY_STAGE_CONST    = BITFIELD_BIT(4),
797ec681f3Smrg        PAN_DIRTY_STAGE_SSBO     = BITFIELD_BIT(5),
807ec681f3Smrg};
817ec681f3Smrg
829f464c52Smayastruct panfrost_constant_buffer {
837ec681f3Smrg        struct pipe_constant_buffer cb[PIPE_MAX_CONSTANT_BUFFERS];
847ec681f3Smrg        uint32_t enabled_mask;
859f464c52Smaya};
869f464c52Smaya
879f464c52Smayastruct panfrost_query {
889f464c52Smaya        /* Passthrough from Gallium */
899f464c52Smaya        unsigned type;
909f464c52Smaya        unsigned index;
919f464c52Smaya
927ec681f3Smrg        /* For computed queries. 64-bit to prevent overflow */
937ec681f3Smrg        struct {
947ec681f3Smrg                uint64_t start;
957ec681f3Smrg                uint64_t end;
967ec681f3Smrg        };
977ec681f3Smrg
989f464c52Smaya        /* Memory for the GPU to writeback the value of the query */
997ec681f3Smrg        struct pipe_resource *rsrc;
1007ec681f3Smrg
1017ec681f3Smrg        /* Whether an occlusion query is for a MSAA framebuffer */
1027ec681f3Smrg        bool msaa;
1039f464c52Smaya};
1049f464c52Smaya
1057ec681f3Smrgstruct pipe_fence_handle {
1069f464c52Smaya        struct pipe_reference reference;
1077ec681f3Smrg        uint32_t syncobj;
1087ec681f3Smrg        bool signaled;
1099f464c52Smaya};
1109f464c52Smaya
1117ec681f3Smrgstruct panfrost_streamout_target {
1127ec681f3Smrg        struct pipe_stream_output_target base;
1137ec681f3Smrg        uint32_t offset;
1147ec681f3Smrg};
1159f464c52Smaya
1167ec681f3Smrgstruct panfrost_streamout {
1177ec681f3Smrg        struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
1187ec681f3Smrg        unsigned num_targets;
1199f464c52Smaya};
1209f464c52Smaya
1219f464c52Smayastruct panfrost_context {
1229f464c52Smaya        /* Gallium context */
1239f464c52Smaya        struct pipe_context base;
1249f464c52Smaya
1257ec681f3Smrg        /* Dirty global state */
1267ec681f3Smrg        enum pan_dirty_3d dirty;
1279f464c52Smaya
1287ec681f3Smrg        /* Per shader stage dirty state */
1297ec681f3Smrg        enum pan_dirty_shader dirty_shader[PIPE_SHADER_TYPES];
1309f464c52Smaya
1317ec681f3Smrg        /* Unowned pools, so manage yourself. */
1327ec681f3Smrg        struct panfrost_pool descs, shaders;
1339f464c52Smaya
1347ec681f3Smrg        /* Sync obj used to keep track of in-flight jobs. */
1357ec681f3Smrg        uint32_t syncobj;
1369f464c52Smaya
1377ec681f3Smrg        /* Set of 32 batches. When the set is full, the LRU entry (the batch
1387ec681f3Smrg         * with the smallest seqnum) is flushed to free a slot.
1397ec681f3Smrg         */
1407ec681f3Smrg        struct {
1417ec681f3Smrg                uint64_t seqnum;
1427ec681f3Smrg                struct panfrost_batch slots[PAN_MAX_BATCHES];
1439f464c52Smaya
1447ec681f3Smrg                /** Set of active batches for faster traversal */
1457ec681f3Smrg                BITSET_DECLARE(active, PAN_MAX_BATCHES);
1467ec681f3Smrg        } batches;
1479f464c52Smaya
1487ec681f3Smrg        /* Map from resources to panfrost_batches */
1497ec681f3Smrg        struct hash_table *writers;
1509f464c52Smaya
1517ec681f3Smrg        /* Bound job batch */
1527ec681f3Smrg        struct panfrost_batch *batch;
1539f464c52Smaya
1547ec681f3Smrg        /* Within a launch_grid call.. */
1557ec681f3Smrg        const struct pipe_grid_info *compute_grid;
1569f464c52Smaya
1577ec681f3Smrg        struct pipe_framebuffer_state pipe_framebuffer;
1587ec681f3Smrg        struct panfrost_streamout streamout;
1599f464c52Smaya
1607ec681f3Smrg        bool active_queries;
1617ec681f3Smrg        uint64_t prims_generated;
1627ec681f3Smrg        uint64_t tf_prims_generated;
1637ec681f3Smrg        struct panfrost_query *occlusion_query;
1649f464c52Smaya
1657ec681f3Smrg        bool indirect_draw;
1667ec681f3Smrg        unsigned drawid;
1679f464c52Smaya        unsigned vertex_count;
1687ec681f3Smrg        unsigned instance_count;
1697ec681f3Smrg        unsigned offset_start;
1707ec681f3Smrg        unsigned base_vertex;
1717ec681f3Smrg        unsigned base_instance;
1727ec681f3Smrg        mali_ptr first_vertex_sysval_ptr;
1737ec681f3Smrg        mali_ptr base_vertex_sysval_ptr;
1747ec681f3Smrg        mali_ptr base_instance_sysval_ptr;
1757ec681f3Smrg        enum pipe_prim_type active_prim;
1767ec681f3Smrg
1777ec681f3Smrg        /* If instancing is enabled, vertex count padded for instance; if
1787ec681f3Smrg         * it is disabled, just equal to plain vertex count */
1797ec681f3Smrg        unsigned padded_count;
1809f464c52Smaya
1819f464c52Smaya        struct panfrost_constant_buffer constant_buffer[PIPE_SHADER_TYPES];
1829f464c52Smaya        struct panfrost_rasterizer *rasterizer;
1837ec681f3Smrg        struct panfrost_shader_variants *shader[PIPE_SHADER_TYPES];
1849f464c52Smaya        struct panfrost_vertex_state *vertex;
1859f464c52Smaya
1869f464c52Smaya        struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
1879f464c52Smaya        uint32_t vb_mask;
1889f464c52Smaya
1897ec681f3Smrg        struct pipe_shader_buffer ssbo[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
1907ec681f3Smrg        uint32_t ssbo_mask[PIPE_SHADER_TYPES];
1917ec681f3Smrg
1927ec681f3Smrg        struct pipe_image_view images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
1937ec681f3Smrg        uint32_t image_mask[PIPE_SHADER_TYPES];
1947ec681f3Smrg
1959f464c52Smaya        struct panfrost_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
1969f464c52Smaya        unsigned sampler_count[PIPE_SHADER_TYPES];
1979f464c52Smaya
1989f464c52Smaya        struct panfrost_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
1999f464c52Smaya        unsigned sampler_view_count[PIPE_SHADER_TYPES];
2009f464c52Smaya
2019f464c52Smaya        struct blitter_context *blitter;
2029f464c52Smaya
2039f464c52Smaya        struct panfrost_blend_state *blend;
2049f464c52Smaya
2059f464c52Smaya        struct pipe_viewport_state pipe_viewport;
2069f464c52Smaya        struct pipe_scissor_state scissor;
2079f464c52Smaya        struct pipe_blend_color blend_color;
2087ec681f3Smrg        struct panfrost_zsa_state *depth_stencil;
2099f464c52Smaya        struct pipe_stencil_ref stencil_ref;
2107ec681f3Smrg        uint16_t sample_mask;
2117ec681f3Smrg        unsigned min_samples;
2129f464c52Smaya
2137ec681f3Smrg        struct panfrost_query *cond_query;
2147ec681f3Smrg        bool cond_cond;
2157ec681f3Smrg        enum pipe_render_cond_flag cond_mode;
2169f464c52Smaya
2177ec681f3Smrg        bool is_noop;
2189f464c52Smaya
2197ec681f3Smrg        /* Mask of active render targets */
2207ec681f3Smrg        uint8_t fb_rt_mask;
2219f464c52Smaya};
2229f464c52Smaya
2239f464c52Smaya/* Corresponds to the CSO */
2249f464c52Smaya
2257ec681f3Smrgstruct panfrost_rasterizer;
2269f464c52Smaya
2277ec681f3Smrg/* Linked varyings */
2287ec681f3Smrgstruct pan_linkage {
2297ec681f3Smrg        /* If the upload is owned by the CSO instead
2307ec681f3Smrg         * of the pool, the referenced BO. Else,
2317ec681f3Smrg         * NULL. */
2327ec681f3Smrg        struct panfrost_bo *bo;
2339f464c52Smaya
2347ec681f3Smrg        /* Uploaded attribute descriptors */
2357ec681f3Smrg        mali_ptr producer, consumer;
2369f464c52Smaya
2377ec681f3Smrg        /* Varyings buffers required */
2387ec681f3Smrg        uint32_t present;
2399f464c52Smaya
2407ec681f3Smrg        /* Per-vertex stride for general varying buffer */
2417ec681f3Smrg        uint32_t stride;
2429f464c52Smaya};
2439f464c52Smaya
2447ec681f3Smrg#define RSD_WORDS 16
2457ec681f3Smrg
2469f464c52Smaya/* Variants bundle together to form the backing CSO, bundling multiple
2477ec681f3Smrg * shaders with varying emulated features baked in */
2489f464c52Smaya
2499f464c52Smaya/* A shader state corresponds to the actual, current variant of the shader */
2509f464c52Smayastruct panfrost_shader_state {
2519f464c52Smaya        /* Compiled, mapped descriptor, ready for the hardware */
2529f464c52Smaya        bool compiled;
2539f464c52Smaya
2547ec681f3Smrg        /* Respectively, shader binary and Renderer State Descriptor */
2557ec681f3Smrg        struct panfrost_pool_ref bin, state;
2569f464c52Smaya
2577ec681f3Smrg        /* For fragment shaders, a prepared (but not uploaded RSD) */
2587ec681f3Smrg        uint32_t partial_rsd[RSD_WORDS];
2599f464c52Smaya
2607ec681f3Smrg        struct pan_shader_info info;
2619f464c52Smaya
2627ec681f3Smrg        /* Linked varyings, for non-separable programs */
2637ec681f3Smrg        struct pan_linkage linkage;
2647ec681f3Smrg
2657ec681f3Smrg        struct pipe_stream_output_info stream_output;
2667ec681f3Smrg        uint64_t so_mask;
2677ec681f3Smrg
2687ec681f3Smrg        /* Variants */
2697ec681f3Smrg        enum pipe_format rt_formats[8];
2707ec681f3Smrg        unsigned nr_cbufs;
2717ec681f3Smrg
2727ec681f3Smrg        /* Mask of state that dirties the sysvals */
2737ec681f3Smrg        unsigned dirty_3d, dirty_shader;
2749f464c52Smaya};
2759f464c52Smaya
2769f464c52Smaya/* A collection of varyings (the CSO) */
2779f464c52Smayastruct panfrost_shader_variants {
2787ec681f3Smrg        /* A panfrost_shader_variants can represent a shader for
2797ec681f3Smrg         * either graphics or compute */
2807ec681f3Smrg
2817ec681f3Smrg        bool is_compute;
2827ec681f3Smrg
2837ec681f3Smrg        union {
2847ec681f3Smrg                struct pipe_shader_state base;
2857ec681f3Smrg                struct pipe_compute_state cbase;
2867ec681f3Smrg        };
2877ec681f3Smrg
2887ec681f3Smrg        /** Lock for the variants array */
2897ec681f3Smrg        simple_mtx_t lock;
2907ec681f3Smrg
2917ec681f3Smrg        struct panfrost_shader_state *variants;
2927ec681f3Smrg        unsigned variant_space;
2939f464c52Smaya
2949f464c52Smaya        unsigned variant_count;
2959f464c52Smaya
2969f464c52Smaya        /* The current active variant */
2979f464c52Smaya        unsigned active_variant;
2989f464c52Smaya};
2999f464c52Smaya
3007ec681f3Smrgstruct pan_vertex_buffer {
3017ec681f3Smrg        unsigned vbi;
3027ec681f3Smrg        unsigned divisor;
3037ec681f3Smrg};
3047ec681f3Smrg
3059f464c52Smayastruct panfrost_vertex_state {
3069f464c52Smaya        unsigned num_elements;
3079f464c52Smaya
3087ec681f3Smrg        /* buffers corresponds to attribute buffer, element_buffers corresponds
3097ec681f3Smrg         * to an index in buffers for each vertex element */
3107ec681f3Smrg        struct pan_vertex_buffer buffers[PIPE_MAX_ATTRIBS];
3117ec681f3Smrg        unsigned element_buffer[PIPE_MAX_ATTRIBS];
3127ec681f3Smrg        unsigned nr_bufs;
3139f464c52Smaya
3147ec681f3Smrg        struct pipe_vertex_element pipe[PIPE_MAX_ATTRIBS];
3157ec681f3Smrg        unsigned formats[PIPE_MAX_ATTRIBS];
3169f464c52Smaya};
3179f464c52Smaya
3187ec681f3Smrgstruct panfrost_zsa_state;
3197ec681f3Smrgstruct panfrost_sampler_state;
3207ec681f3Smrgstruct panfrost_sampler_view;
3219f464c52Smaya
3229f464c52Smayastatic inline struct panfrost_context *
3239f464c52Smayapan_context(struct pipe_context *pcontext)
3249f464c52Smaya{
3259f464c52Smaya        return (struct panfrost_context *) pcontext;
3269f464c52Smaya}
3279f464c52Smaya
3287ec681f3Smrgstatic inline struct panfrost_streamout_target *
3297ec681f3Smrgpan_so_target(struct pipe_stream_output_target *target)
3309f464c52Smaya{
3317ec681f3Smrg        return (struct panfrost_streamout_target *)target;
3327ec681f3Smrg}
3337ec681f3Smrg
3347ec681f3Smrgstatic inline struct panfrost_shader_state *
3357ec681f3Smrgpanfrost_get_shader_state(struct panfrost_context *ctx,
3367ec681f3Smrg                          enum pipe_shader_type st)
3377ec681f3Smrg{
3387ec681f3Smrg        struct panfrost_shader_variants *all = ctx->shader[st];
3397ec681f3Smrg
3407ec681f3Smrg        if (!all)
3417ec681f3Smrg                return NULL;
3427ec681f3Smrg
3437ec681f3Smrg        return &all->variants[all->active_variant];
3449f464c52Smaya}
3459f464c52Smaya
3469f464c52Smayastruct pipe_context *
3479f464c52Smayapanfrost_create_context(struct pipe_screen *screen, void *priv, unsigned flags);
3489f464c52Smaya
3497ec681f3Smrgbool
3507ec681f3Smrgpanfrost_writes_point_size(struct panfrost_context *ctx);
3519f464c52Smaya
3527ec681f3Smrgstruct panfrost_ptr
3537ec681f3Smrgpanfrost_vertex_tiler_job(struct panfrost_context *ctx, bool is_tiler);
3549f464c52Smaya
3559f464c52Smayavoid
3569f464c52Smayapanfrost_flush(
3579f464c52Smaya        struct pipe_context *pipe,
3589f464c52Smaya        struct pipe_fence_handle **fence,
3599f464c52Smaya        unsigned flags);
3609f464c52Smaya
3619f464c52Smayabool
3627ec681f3Smrgpanfrost_render_condition_check(struct panfrost_context *ctx);
3639f464c52Smaya
3647ec681f3Smrgvoid
3657ec681f3Smrgpanfrost_shader_compile(struct pipe_screen *pscreen,
3667ec681f3Smrg                        struct panfrost_pool *shader_pool,
3677ec681f3Smrg                        struct panfrost_pool *desc_pool,
3687ec681f3Smrg                        enum pipe_shader_ir ir_type,
3697ec681f3Smrg                        const void *ir,
3707ec681f3Smrg                        gl_shader_stage stage,
3717ec681f3Smrg                        struct panfrost_shader_state *state);
3729f464c52Smaya
3737ec681f3Smrgvoid
3747ec681f3Smrgpanfrost_analyze_sysvals(struct panfrost_shader_state *ss);
3759f464c52Smaya
3767ec681f3Smrgmali_ptr
3777ec681f3Smrgpanfrost_get_index_buffer_bounded(struct panfrost_batch *batch,
3787ec681f3Smrg                                  const struct pipe_draw_info *info,
3797ec681f3Smrg                                  const struct pipe_draw_start_count_bias *draw,
3807ec681f3Smrg                                  unsigned *min_index, unsigned *max_index);
3819f464c52Smaya
3827ec681f3Smrg/* Instancing */
3839f464c52Smaya
3849f464c52Smayamali_ptr
3857ec681f3Smrgpanfrost_vertex_buffer_address(struct panfrost_context *ctx, unsigned i);
3867ec681f3Smrg
3877ec681f3Smrg/* Compute */
3889f464c52Smaya
3899f464c52Smayavoid
3907ec681f3Smrgpanfrost_compute_context_init(struct pipe_context *pctx);
3917ec681f3Smrg
3927ec681f3Smrgstatic inline void
3937ec681f3Smrgpanfrost_dirty_state_all(struct panfrost_context *ctx)
3947ec681f3Smrg{
3957ec681f3Smrg        ctx->dirty = ~0;
3967ec681f3Smrg
3977ec681f3Smrg        for (unsigned i = 0; i < PIPE_SHADER_TYPES; ++i)
3987ec681f3Smrg                ctx->dirty_shader[i] = ~0;
3997ec681f3Smrg}
4007ec681f3Smrg
4017ec681f3Smrgstatic inline void
4027ec681f3Smrgpanfrost_clean_state_3d(struct panfrost_context *ctx)
4037ec681f3Smrg{
4047ec681f3Smrg        ctx->dirty = 0;
4057ec681f3Smrg
4067ec681f3Smrg        for (unsigned i = 0; i < PIPE_SHADER_TYPES; ++i) {
4077ec681f3Smrg                if (i != PIPE_SHADER_COMPUTE)
4087ec681f3Smrg                        ctx->dirty_shader[i] = 0;
4097ec681f3Smrg        }
4107ec681f3Smrg}
4119f464c52Smaya
4129f464c52Smaya#endif
413