1/**************************************************************************
2 *
3 * Copyright 2009 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28/**
29 * The rast code is concerned with rasterization of command bins.
30 * Each screen tile has a bin associated with it.  To render the
31 * scene we iterate over the tile bins and execute the commands
32 * in each bin.
33 * We'll do that with multiple threads...
34 */
35
36
37#ifndef LP_RAST_H
38#define LP_RAST_H
39
40#include "pipe/p_compiler.h"
41#include "util/u_pack_color.h"
42#include "util/u_rect.h"
43#include "lp_jit.h"
44
45
46struct lp_rasterizer;
47struct lp_scene;
48struct lp_fence;
49struct cmd_bin;
50
51#define FIXED_TYPE_WIDTH 64
52/** For sub-pixel positioning */
53#define FIXED_ORDER 8
54#define FIXED_ONE (1<<FIXED_ORDER)
55#define FIXED_SHIFT (FIXED_TYPE_WIDTH - 1)
56/** Maximum length of an edge in a primitive in pixels.
57 *  If the framebuffer is large we have to think about fixed-point
58 *  integer overflow. Coordinates need ((FIXED_TYPE_WIDTH/2) - 1) bits
59 *  to be able to fit product of two such coordinates inside
60 *  FIXED_TYPE_WIDTH, any larger and we could overflow a
61 *  FIXED_TYPE_WIDTH_-bit int.
62 */
63#define MAX_FIXED_LENGTH (1 << (((FIXED_TYPE_WIDTH/2) - 1) - FIXED_ORDER))
64
65#define MAX_FIXED_LENGTH32 (1 << (((32/2) - 1) - FIXED_ORDER))
66
67/* Rasterizer output size going to jit fs, width/height */
68#define LP_RASTER_BLOCK_SIZE 4
69
70#define LP_MAX_ACTIVE_BINNED_QUERIES 64
71
72#define IMUL64(a, b) (((int64_t)(a)) * ((int64_t)(b)))
73
74struct lp_rasterizer_task;
75
76extern const float lp_sample_pos_4x[4][2];
77
78/**
79 * Rasterization state.
80 * Objects of this type are put into the shared data bin and pointed
81 * to by commands in the per-tile bins.
82 */
83struct lp_rast_state {
84   /* State for the shader.  This also contains state which feeds into
85    * the fragment shader, such as blend color and alpha ref value.
86    */
87   struct lp_jit_context jit_context;
88
89   /* The shader itself.  Probably we also need to pass a pointer to
90    * the tile color/z/stencil data somehow
91     */
92   struct lp_fragment_shader_variant *variant;
93};
94
95
96/**
97 * Texture blit offsets.
98 */
99struct lp_rast_blit {
100   int16_t x0;
101   int16_t y0;
102};
103
104
105/**
106 * Coefficients necessary to run the shader at a given location.
107 * First coefficient is position.
108 * These pointers point into the bin data buffer.
109 */
110struct lp_rast_shader_inputs {
111   unsigned frontfacing:1;      /** True for front-facing */
112   unsigned disable:1;          /** Partially binned, disable this command */
113   unsigned opaque:1;           /** Is opaque */
114   unsigned is_blit:1;          /* blit */
115   unsigned pad0:12;            /* wasted space */
116   unsigned view_index:16;
117   unsigned stride;             /* how much to advance data between a0, dadx, dady */
118   unsigned layer;              /* the layer to render to (from gs, already clamped) */
119   unsigned viewport_index;     /* the active viewport index (from gs, already clamped) */
120
121   /* followed by a0, dadx, dady and planes[] */
122};
123
124struct lp_rast_plane {
125   /* edge function values at minx,miny ?? */
126   int64_t c;
127
128   int32_t dcdx;
129   int32_t dcdy;
130
131   /* one-pixel sized trivial reject offsets for each plane */
132   uint32_t eo;
133   /*
134    * We rely on this struct being 64bit aligned (ideally it would be 128bit
135    * but that's quite the waste) and therefore on 32bit we need padding
136    * since otherwise (even with the 64bit number in there) it wouldn't be.
137    */
138   uint32_t pad;
139};
140
141/**
142 * Rasterization information for a triangle known to be in this bin,
143 * plus inputs to run the shader:
144 * These fields are tile- and bin-independent.
145 * Objects of this type are put into the lp_setup_context::data buffer.
146 */
147struct lp_rast_triangle {
148#ifdef DEBUG
149   float v[3][2];
150   float pad0;
151   float pad1;
152#endif
153
154   /* inputs for the shader */
155   struct lp_rast_shader_inputs inputs;
156   /* planes are also allocated here */
157};
158
159
160#define RECT_PLANE_LEFT   0x1
161#define RECT_PLANE_RIGHT  0x2
162#define RECT_PLANE_TOP    0x4
163#define RECT_PLANE_BOTTOM 0x8
164
165/**
166 * Rasterization information for a screen-aligned rectangle known to
167 * be in this bin, plus inputs to run the shader:
168 * These fields are tile- and bin-independent.
169 * Objects of this type are put into the lp_setup_context::data buffer.
170 */
171struct lp_rast_rectangle {
172#ifdef DEBUG
173   float v[2][2]; /**< diagonal corners */
174#endif
175
176   /* Rectangle boundaries in integer pixels:
177    */
178   struct u_rect box;
179
180   /* inputs for the shader */
181   struct lp_rast_shader_inputs inputs;
182};
183
184
185struct lp_rast_clear_rb {
186   union util_color color_val;
187   unsigned cbuf;
188};
189
190
191#define GET_A0(inputs) ((float (*)[4])((inputs)+1))
192#define GET_DADX(inputs) ((float (*)[4])((char *)((inputs) + 1) + (inputs)->stride))
193#define GET_DADY(inputs) ((float (*)[4])((char *)((inputs) + 1) + 2 * (inputs)->stride))
194#define GET_PLANES(tri) ((struct lp_rast_plane *)((char *)(&(tri)->inputs + 1) + 3 * (tri)->inputs.stride))
195
196
197
198struct lp_rasterizer *
199lp_rast_create( unsigned num_threads );
200
201void
202lp_rast_destroy( struct lp_rasterizer * );
203
204void
205lp_rast_queue_scene( struct lp_rasterizer *rast,
206                     struct lp_scene *scene );
207
208void
209lp_rast_finish( struct lp_rasterizer *rast );
210
211
212union lp_rast_cmd_arg {
213   const struct lp_rast_shader_inputs *shade_tile;
214   struct {
215      const struct lp_rast_triangle *tri;
216      unsigned plane_mask;
217   } triangle;
218   const struct lp_rast_rectangle *rectangle;
219   const struct lp_rast_state *set_state;
220   const struct lp_rast_clear_rb *clear_rb;
221   struct {
222      uint64_t value;
223      uint64_t mask;
224   } clear_zstencil;
225   const struct lp_rast_state *state;
226   struct lp_fence *fence;
227   struct llvmpipe_query *query_obj;
228};
229
230
231/* Cast wrappers.  Hopefully these compile to noops!
232 */
233static inline union lp_rast_cmd_arg
234lp_rast_arg_inputs( const struct lp_rast_shader_inputs *shade_tile )
235{
236   union lp_rast_cmd_arg arg;
237   arg.shade_tile = shade_tile;
238   return arg;
239}
240
241static inline union lp_rast_cmd_arg
242lp_rast_arg_triangle( const struct lp_rast_triangle *triangle,
243                      unsigned plane_mask)
244{
245   union lp_rast_cmd_arg arg;
246   arg.triangle.tri = triangle;
247   arg.triangle.plane_mask = plane_mask;
248   return arg;
249}
250
251/**
252 * Build argument for a contained triangle.
253 *
254 * All planes are enabled, so instead of the plane mask we pass the upper
255 * left coordinates of the a block that fully encloses the triangle.
256 */
257static inline union lp_rast_cmd_arg
258lp_rast_arg_triangle_contained( const struct lp_rast_triangle *triangle,
259                                unsigned x, unsigned y)
260{
261   union lp_rast_cmd_arg arg;
262   arg.triangle.tri = triangle;
263   arg.triangle.plane_mask = x | (y << 8);
264   return arg;
265}
266
267static inline union lp_rast_cmd_arg
268lp_rast_arg_rectangle( const struct lp_rast_rectangle *rectangle )
269{
270   union lp_rast_cmd_arg arg;
271   arg.rectangle = rectangle;
272   return arg;
273}
274
275static inline union lp_rast_cmd_arg
276lp_rast_arg_state( const struct lp_rast_state *state )
277{
278   union lp_rast_cmd_arg arg;
279   arg.set_state = state;
280   return arg;
281}
282
283static inline union lp_rast_cmd_arg
284lp_rast_arg_fence( struct lp_fence *fence )
285{
286   union lp_rast_cmd_arg arg;
287   arg.fence = fence;
288   return arg;
289}
290
291
292static inline union lp_rast_cmd_arg
293lp_rast_arg_clearzs( uint64_t value, uint64_t mask )
294{
295   union lp_rast_cmd_arg arg;
296   arg.clear_zstencil.value = value;
297   arg.clear_zstencil.mask = mask;
298   return arg;
299}
300
301
302static inline union lp_rast_cmd_arg
303lp_rast_arg_query( struct llvmpipe_query *pq )
304{
305   union lp_rast_cmd_arg arg;
306   arg.query_obj = pq;
307   return arg;
308}
309
310static inline union lp_rast_cmd_arg
311lp_rast_arg_null( void )
312{
313   union lp_rast_cmd_arg arg;
314   arg.set_state = NULL;
315   return arg;
316}
317
318
319/**
320 * Binnable Commands.
321 * These get put into bins by the setup code and are called when
322 * the bins are executed.
323 */
324#define LP_RAST_OP_CLEAR_COLOR       0x0
325#define LP_RAST_OP_CLEAR_ZSTENCIL    0x1
326#define LP_RAST_OP_TRIANGLE_1        0x2
327#define LP_RAST_OP_TRIANGLE_2        0x3
328#define LP_RAST_OP_TRIANGLE_3        0x4
329#define LP_RAST_OP_TRIANGLE_4        0x5
330#define LP_RAST_OP_TRIANGLE_5        0x6
331#define LP_RAST_OP_TRIANGLE_6        0x7
332#define LP_RAST_OP_TRIANGLE_7        0x8
333#define LP_RAST_OP_TRIANGLE_8        0x9
334#define LP_RAST_OP_TRIANGLE_3_4      0xa
335#define LP_RAST_OP_TRIANGLE_3_16     0xb
336#define LP_RAST_OP_TRIANGLE_4_16     0xc
337#define LP_RAST_OP_SHADE_TILE        0xd
338#define LP_RAST_OP_SHADE_TILE_OPAQUE 0xe
339#define LP_RAST_OP_BEGIN_QUERY       0xf
340#define LP_RAST_OP_END_QUERY         0x10
341#define LP_RAST_OP_SET_STATE         0x11
342#define LP_RAST_OP_TRIANGLE_32_1     0x12
343#define LP_RAST_OP_TRIANGLE_32_2     0x13
344#define LP_RAST_OP_TRIANGLE_32_3     0x14
345#define LP_RAST_OP_TRIANGLE_32_4     0x15
346#define LP_RAST_OP_TRIANGLE_32_5     0x16
347#define LP_RAST_OP_TRIANGLE_32_6     0x17
348#define LP_RAST_OP_TRIANGLE_32_7     0x18
349#define LP_RAST_OP_TRIANGLE_32_8     0x19
350#define LP_RAST_OP_TRIANGLE_32_3_4   0x1a
351#define LP_RAST_OP_TRIANGLE_32_3_16  0x1b
352#define LP_RAST_OP_TRIANGLE_32_4_16  0x1c
353
354#define LP_RAST_OP_MS_TRIANGLE_1     0x1d
355#define LP_RAST_OP_MS_TRIANGLE_2     0x1e
356#define LP_RAST_OP_MS_TRIANGLE_3     0x1f
357#define LP_RAST_OP_MS_TRIANGLE_4     0x20
358#define LP_RAST_OP_MS_TRIANGLE_5     0x21
359#define LP_RAST_OP_MS_TRIANGLE_6     0x22
360#define LP_RAST_OP_MS_TRIANGLE_7     0x23
361#define LP_RAST_OP_MS_TRIANGLE_8     0x24
362#define LP_RAST_OP_MS_TRIANGLE_3_4   0x25
363#define LP_RAST_OP_MS_TRIANGLE_3_16  0x26
364#define LP_RAST_OP_MS_TRIANGLE_4_16  0x27
365#define LP_RAST_OP_RECTANGLE         0x28  /* Keep at end */
366#define LP_RAST_OP_BLIT              0x29  /* Keep at end */
367
368#define LP_RAST_OP_MAX               0x2a
369#define LP_RAST_OP_MASK              0xff
370
371/* Returned by characterize_bin:
372 */
373#define LP_RAST_FLAGS_TRI            (0x1)
374#define LP_RAST_FLAGS_RECT           (0x2)
375#define LP_RAST_FLAGS_TILE           (0x4)
376#define LP_RAST_FLAGS_BLIT           (0x8)
377
378struct lp_bin_info {
379   unsigned type:8;
380   unsigned count:24;
381};
382
383struct lp_bin_info
384lp_characterize_bin(const struct cmd_bin *bin);
385
386void
387lp_debug_bins( struct lp_scene *scene );
388void
389lp_debug_draw_bins_by_cmd_length( struct lp_scene *scene );
390void
391lp_debug_draw_bins_by_coverage( struct lp_scene *scene );
392
393
394#endif
395