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