1/*
2 * Copyright (C) 2019 Alyssa Rosenzweig
3 * Copyright (C) 2014-2017 Broadcom
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 */
25
26#ifndef __PAN_JOB_H__
27#define __PAN_JOB_H__
28
29#include "util/u_dynarray.h"
30#include "pipe/p_state.h"
31#include "pan_cs.h"
32#include "pan_mempool.h"
33#include "pan_resource.h"
34#include "pan_scoreboard.h"
35
36/* Simple tri-state data structure. In the default "don't care" state, the value
37 * may be set to true or false. However, once the value is set, it must not be
38 * changed. Declared inside of a struct to prevent casting to bool, which is an
39 * error. The getter needs to be used instead.
40 */
41struct pan_tristate {
42        enum {
43                PAN_TRISTATE_DONTCARE,
44                PAN_TRISTATE_FALSE,
45                PAN_TRISTATE_TRUE,
46        } v;
47};
48
49/*
50 * Try to set a tristate value to a desired boolean value. Returns whether the
51 * operation is successful.
52 */
53static bool
54pan_tristate_set(struct pan_tristate *state, bool value)
55{
56        switch (state->v) {
57        case PAN_TRISTATE_DONTCARE:
58                state->v = value ? PAN_TRISTATE_TRUE : PAN_TRISTATE_FALSE;
59                return true;
60
61        case PAN_TRISTATE_FALSE:
62                return (value == false);
63
64        case PAN_TRISTATE_TRUE:
65                return (value == true);
66
67        default:
68                unreachable("Invalid tristate value");
69        }
70}
71
72/*
73 * Read the boolean value of a tristate. Return value undefined in the don't
74 * care state.
75 */
76static bool
77pan_tristate_get(struct pan_tristate state)
78{
79        return (state.v == PAN_TRISTATE_TRUE);
80}
81
82/* A panfrost_batch corresponds to a bound FBO we're rendering to,
83 * collecting over multiple draws. */
84
85struct panfrost_batch {
86        struct panfrost_context *ctx;
87        struct pipe_framebuffer_state key;
88
89        /* Sequence number used to implement LRU eviction when all batch slots are used */
90        uint64_t seqnum;
91
92        /* Buffers cleared (PIPE_CLEAR_* bitmask) */
93        unsigned clear;
94
95        /* Buffers drawn */
96        unsigned draws;
97
98        /* Buffers read */
99        unsigned read;
100
101        /* Buffers needing resolve to memory */
102        unsigned resolve;
103
104        /* Packed clear values, indexed by both render target as well as word.
105         * Essentially, a single pixel is packed, with some padding to bring it
106         * up to a 32-bit interval; that pixel is then duplicated over to fill
107         * all 16-bytes */
108
109        uint32_t clear_color[PIPE_MAX_COLOR_BUFS][4];
110        float clear_depth;
111        unsigned clear_stencil;
112
113        /* Amount of thread local storage required per thread */
114        unsigned stack_size;
115
116        /* Amount of shared memory needed per workgroup (for compute) */
117        unsigned shared_size;
118
119        /* The bounding box covered by this job, taking scissors into account.
120         * Basically, the bounding box we have to run fragment shaders for */
121
122        unsigned minx, miny;
123        unsigned maxx, maxy;
124
125        /* Acts as a rasterizer discard */
126        bool scissor_culls_everything;
127
128        /* BOs referenced not in the pool */
129        unsigned num_bos;
130        struct util_dynarray bos;
131
132        /* Pool owned by this batch (released when the batch is released) used for temporary descriptors */
133        struct panfrost_pool pool;
134
135        /* Pool also owned by this batch that is not CPU mapped (created as
136         * INVISIBLE) used for private GPU-internal structures, particularly
137         * varyings */
138        struct panfrost_pool invisible_pool;
139
140        /* Job scoreboarding state */
141        struct pan_scoreboard scoreboard;
142
143        /* Polygon list bound to the batch, or NULL if none bound yet */
144        struct panfrost_bo *polygon_list;
145
146        /* Scratchpad BO bound to the batch, or NULL if none bound yet */
147        struct panfrost_bo *scratchpad;
148
149        /* Shared memory BO bound to the batch, or NULL if none bound yet */
150        struct panfrost_bo *shared_memory;
151
152        /* Framebuffer descriptor. */
153        struct panfrost_ptr framebuffer;
154
155        /* Thread local storage descriptor. */
156        struct panfrost_ptr tls;
157
158        /* Tiler context */
159        struct pan_tiler_context tiler_ctx;
160
161        /* Indirect draw data */
162        struct panfrost_ptr indirect_draw_ctx;
163        unsigned indirect_draw_job_id;
164
165        /* Keep the num_work_groups sysval around for indirect dispatch */
166        mali_ptr num_wg_sysval[3];
167
168        /* Cached descriptors */
169        mali_ptr viewport;
170        mali_ptr rsd[PIPE_SHADER_TYPES];
171        mali_ptr textures[PIPE_SHADER_TYPES];
172        mali_ptr samplers[PIPE_SHADER_TYPES];
173        mali_ptr attribs[PIPE_SHADER_TYPES];
174        mali_ptr attrib_bufs[PIPE_SHADER_TYPES];
175        mali_ptr uniform_buffers[PIPE_SHADER_TYPES];
176        mali_ptr push_uniforms[PIPE_SHADER_TYPES];
177        mali_ptr depth_stencil;
178        mali_ptr blend;
179
180        /* Valhall: struct mali_scissor_packed */
181        unsigned scissor[2];
182        float minimum_z, maximum_z;
183
184        /* Used on Valhall only. Midgard includes attributes in-band with
185         * attributes, wildly enough.
186         */
187        mali_ptr images[PIPE_SHADER_TYPES];
188
189        /* On Valhall, these are properties of the batch. On Bifrost, they are
190         * per draw.
191         */
192        struct pan_tristate sprite_coord_origin;
193        struct pan_tristate first_provoking_vertex;
194
195        /* Referenced resources */
196        struct set *resources;
197};
198
199/* Functions for managing the above */
200
201struct panfrost_batch *
202panfrost_get_batch_for_fbo(struct panfrost_context *ctx);
203
204struct panfrost_batch *
205panfrost_get_fresh_batch_for_fbo(struct panfrost_context *ctx, const char *reason);
206
207void
208panfrost_batch_add_bo(struct panfrost_batch *batch,
209                      struct panfrost_bo *bo,
210                      enum pipe_shader_type stage);
211
212void
213panfrost_batch_read_rsrc(struct panfrost_batch *batch,
214                         struct panfrost_resource *rsrc,
215                         enum pipe_shader_type stage);
216
217void
218panfrost_batch_write_rsrc(struct panfrost_batch *batch,
219                          struct panfrost_resource *rsrc,
220                          enum pipe_shader_type stage);
221
222void
223panfrost_resource_swap_bo(struct panfrost_context *ctx,
224                          struct panfrost_resource *rsrc,
225                          struct panfrost_bo *newbo);
226
227struct panfrost_bo *
228panfrost_batch_create_bo(struct panfrost_batch *batch, size_t size,
229                         uint32_t create_flags, uint32_t access_flags,
230                         const char *label);
231
232void
233panfrost_flush_all_batches(struct panfrost_context *ctx, const char *reason);
234
235void
236panfrost_flush_batches_accessing_rsrc(struct panfrost_context *ctx,
237                                      struct panfrost_resource *rsrc,
238                                      const char *reason);
239
240void
241panfrost_flush_writer(struct panfrost_context *ctx,
242                      struct panfrost_resource *rsrc,
243                      const char *reason);
244
245void
246panfrost_batch_adjust_stack_size(struct panfrost_batch *batch);
247
248struct panfrost_bo *
249panfrost_batch_get_scratchpad(struct panfrost_batch *batch, unsigned size, unsigned thread_tls_alloc, unsigned core_id_range);
250
251struct panfrost_bo *
252panfrost_batch_get_shared_memory(struct panfrost_batch *batch, unsigned size, unsigned workgroup_count);
253
254void
255panfrost_batch_clear(struct panfrost_batch *batch,
256                     unsigned buffers,
257                     const union pipe_color_union *color,
258                     double depth, unsigned stencil);
259
260void
261panfrost_batch_union_scissor(struct panfrost_batch *batch,
262                             unsigned minx, unsigned miny,
263                             unsigned maxx, unsigned maxy);
264
265bool
266panfrost_batch_skip_rasterization(struct panfrost_batch *batch);
267
268#endif
269