1cdc920a0Smrg/**************************************************************************
2cdc920a0Smrg *
3cdc920a0Smrg * Copyright 2009 VMware, Inc.
4cdc920a0Smrg * All Rights Reserved.
5cdc920a0Smrg *
6cdc920a0Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7cdc920a0Smrg * copy of this software and associated documentation files (the
8cdc920a0Smrg * "Software"), to deal in the Software without restriction, including
9cdc920a0Smrg * without limitation the rights to use, copy, modify, merge, publish,
10cdc920a0Smrg * distribute, sub license, and/or sell copies of the Software, and to
11cdc920a0Smrg * permit persons to whom the Software is furnished to do so, subject to
12cdc920a0Smrg * the following conditions:
13cdc920a0Smrg *
14cdc920a0Smrg * The above copyright notice and this permission notice (including the
15cdc920a0Smrg * next paragraph) shall be included in all copies or substantial portions
16cdc920a0Smrg * of the Software.
17cdc920a0Smrg *
18cdc920a0Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19cdc920a0Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20cdc920a0Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21cdc920a0Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22cdc920a0Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23cdc920a0Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24cdc920a0Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25cdc920a0Smrg *
26cdc920a0Smrg **************************************************************************/
27cdc920a0Smrg
28cdc920a0Smrg/**
29cdc920a0Smrg * The rast code is concerned with rasterization of command bins.
30cdc920a0Smrg * Each screen tile has a bin associated with it.  To render the
31cdc920a0Smrg * scene we iterate over the tile bins and execute the commands
32cdc920a0Smrg * in each bin.
33cdc920a0Smrg * We'll do that with multiple threads...
34cdc920a0Smrg */
35cdc920a0Smrg
36cdc920a0Smrg
37cdc920a0Smrg#ifndef LP_RAST_H
38cdc920a0Smrg#define LP_RAST_H
39cdc920a0Smrg
40cdc920a0Smrg#include "pipe/p_compiler.h"
41af69d88dSmrg#include "util/u_pack_color.h"
427ec681f3Smrg#include "util/u_rect.h"
43cdc920a0Smrg#include "lp_jit.h"
44cdc920a0Smrg
45cdc920a0Smrg
46cdc920a0Smrgstruct lp_rasterizer;
47cdc920a0Smrgstruct lp_scene;
48cdc920a0Smrgstruct lp_fence;
49cdc920a0Smrgstruct cmd_bin;
50cdc920a0Smrg
51af69d88dSmrg#define FIXED_TYPE_WIDTH 64
52cdc920a0Smrg/** For sub-pixel positioning */
53af69d88dSmrg#define FIXED_ORDER 8
54cdc920a0Smrg#define FIXED_ONE (1<<FIXED_ORDER)
55af69d88dSmrg#define FIXED_SHIFT (FIXED_TYPE_WIDTH - 1)
56af69d88dSmrg/** Maximum length of an edge in a primitive in pixels.
57af69d88dSmrg *  If the framebuffer is large we have to think about fixed-point
58af69d88dSmrg *  integer overflow. Coordinates need ((FIXED_TYPE_WIDTH/2) - 1) bits
59af69d88dSmrg *  to be able to fit product of two such coordinates inside
60af69d88dSmrg *  FIXED_TYPE_WIDTH, any larger and we could overflow a
61af69d88dSmrg *  FIXED_TYPE_WIDTH_-bit int.
62af69d88dSmrg */
63af69d88dSmrg#define MAX_FIXED_LENGTH (1 << (((FIXED_TYPE_WIDTH/2) - 1) - FIXED_ORDER))
64af69d88dSmrg
65af69d88dSmrg#define MAX_FIXED_LENGTH32 (1 << (((32/2) - 1) - FIXED_ORDER))
66af69d88dSmrg
67af69d88dSmrg/* Rasterizer output size going to jit fs, width/height */
68af69d88dSmrg#define LP_RASTER_BLOCK_SIZE 4
69af69d88dSmrg
70af69d88dSmrg#define LP_MAX_ACTIVE_BINNED_QUERIES 64
71cdc920a0Smrg
72af69d88dSmrg#define IMUL64(a, b) (((int64_t)(a)) * ((int64_t)(b)))
73cdc920a0Smrg
74cdc920a0Smrgstruct lp_rasterizer_task;
75cdc920a0Smrg
767ec681f3Smrgextern const float lp_sample_pos_4x[4][2];
77cdc920a0Smrg
78cdc920a0Smrg/**
79cdc920a0Smrg * Rasterization state.
80cdc920a0Smrg * Objects of this type are put into the shared data bin and pointed
81cdc920a0Smrg * to by commands in the per-tile bins.
82cdc920a0Smrg */
83cdc920a0Smrgstruct lp_rast_state {
84cdc920a0Smrg   /* State for the shader.  This also contains state which feeds into
85cdc920a0Smrg    * the fragment shader, such as blend color and alpha ref value.
86cdc920a0Smrg    */
87cdc920a0Smrg   struct lp_jit_context jit_context;
88cdc920a0Smrg
89cdc920a0Smrg   /* The shader itself.  Probably we also need to pass a pointer to
903464ebd5Sriastradh    * the tile color/z/stencil data somehow
91cdc920a0Smrg     */
923464ebd5Sriastradh   struct lp_fragment_shader_variant *variant;
93cdc920a0Smrg};
94cdc920a0Smrg
95cdc920a0Smrg
967ec681f3Smrg/**
977ec681f3Smrg * Texture blit offsets.
987ec681f3Smrg */
997ec681f3Smrgstruct lp_rast_blit {
1007ec681f3Smrg   int16_t x0;
1017ec681f3Smrg   int16_t y0;
1027ec681f3Smrg};
1037ec681f3Smrg
1047ec681f3Smrg
105cdc920a0Smrg/**
106cdc920a0Smrg * Coefficients necessary to run the shader at a given location.
107cdc920a0Smrg * First coefficient is position.
108cdc920a0Smrg * These pointers point into the bin data buffer.
109cdc920a0Smrg */
110cdc920a0Smrgstruct lp_rast_shader_inputs {
1113464ebd5Sriastradh   unsigned frontfacing:1;      /** True for front-facing */
1123464ebd5Sriastradh   unsigned disable:1;          /** Partially binned, disable this command */
1133464ebd5Sriastradh   unsigned opaque:1;           /** Is opaque */
1147ec681f3Smrg   unsigned is_blit:1;          /* blit */
1157ec681f3Smrg   unsigned pad0:12;            /* wasted space */
1167ec681f3Smrg   unsigned view_index:16;
1173464ebd5Sriastradh   unsigned stride;             /* how much to advance data between a0, dadx, dady */
118af69d88dSmrg   unsigned layer;              /* the layer to render to (from gs, already clamped) */
119af69d88dSmrg   unsigned viewport_index;     /* the active viewport index (from gs, already clamped) */
1207ec681f3Smrg
1213464ebd5Sriastradh   /* followed by a0, dadx, dady and planes[] */
122cdc920a0Smrg};
123cdc920a0Smrg
1243464ebd5Sriastradhstruct lp_rast_plane {
1253464ebd5Sriastradh   /* edge function values at minx,miny ?? */
126af69d88dSmrg   int64_t c;
1273464ebd5Sriastradh
128af69d88dSmrg   int32_t dcdx;
129af69d88dSmrg   int32_t dcdy;
1303464ebd5Sriastradh
1313464ebd5Sriastradh   /* one-pixel sized trivial reject offsets for each plane */
13201e04c3fSmrg   uint32_t eo;
13301e04c3fSmrg   /*
13401e04c3fSmrg    * We rely on this struct being 64bit aligned (ideally it would be 128bit
13501e04c3fSmrg    * but that's quite the waste) and therefore on 32bit we need padding
13601e04c3fSmrg    * since otherwise (even with the 64bit number in there) it wouldn't be.
13701e04c3fSmrg    */
13801e04c3fSmrg   uint32_t pad;
1393464ebd5Sriastradh};
140cdc920a0Smrg
141cdc920a0Smrg/**
142cdc920a0Smrg * Rasterization information for a triangle known to be in this bin,
143cdc920a0Smrg * plus inputs to run the shader:
144cdc920a0Smrg * These fields are tile- and bin-independent.
1453464ebd5Sriastradh * Objects of this type are put into the lp_setup_context::data buffer.
146cdc920a0Smrg */
147cdc920a0Smrgstruct lp_rast_triangle {
148cdc920a0Smrg#ifdef DEBUG
149cdc920a0Smrg   float v[3][2];
1503464ebd5Sriastradh   float pad0;
1513464ebd5Sriastradh   float pad1;
152cdc920a0Smrg#endif
153cdc920a0Smrg
154cdc920a0Smrg   /* inputs for the shader */
1553464ebd5Sriastradh   struct lp_rast_shader_inputs inputs;
1563464ebd5Sriastradh   /* planes are also allocated here */
157cdc920a0Smrg};
158cdc920a0Smrg
159cdc920a0Smrg
1607ec681f3Smrg#define RECT_PLANE_LEFT   0x1
1617ec681f3Smrg#define RECT_PLANE_RIGHT  0x2
1627ec681f3Smrg#define RECT_PLANE_TOP    0x4
1637ec681f3Smrg#define RECT_PLANE_BOTTOM 0x8
1647ec681f3Smrg
1657ec681f3Smrg/**
1667ec681f3Smrg * Rasterization information for a screen-aligned rectangle known to
1677ec681f3Smrg * be in this bin, plus inputs to run the shader:
1687ec681f3Smrg * These fields are tile- and bin-independent.
1697ec681f3Smrg * Objects of this type are put into the lp_setup_context::data buffer.
1707ec681f3Smrg */
1717ec681f3Smrgstruct lp_rast_rectangle {
1727ec681f3Smrg#ifdef DEBUG
1737ec681f3Smrg   float v[2][2]; /**< diagonal corners */
1747ec681f3Smrg#endif
1757ec681f3Smrg
1767ec681f3Smrg   /* Rectangle boundaries in integer pixels:
1777ec681f3Smrg    */
1787ec681f3Smrg   struct u_rect box;
1797ec681f3Smrg
1807ec681f3Smrg   /* inputs for the shader */
1817ec681f3Smrg   struct lp_rast_shader_inputs inputs;
1827ec681f3Smrg};
1837ec681f3Smrg
1847ec681f3Smrg
185af69d88dSmrgstruct lp_rast_clear_rb {
186af69d88dSmrg   union util_color color_val;
187af69d88dSmrg   unsigned cbuf;
188af69d88dSmrg};
189af69d88dSmrg
190af69d88dSmrg
1913464ebd5Sriastradh#define GET_A0(inputs) ((float (*)[4])((inputs)+1))
1923464ebd5Sriastradh#define GET_DADX(inputs) ((float (*)[4])((char *)((inputs) + 1) + (inputs)->stride))
1933464ebd5Sriastradh#define GET_DADY(inputs) ((float (*)[4])((char *)((inputs) + 1) + 2 * (inputs)->stride))
1943464ebd5Sriastradh#define GET_PLANES(tri) ((struct lp_rast_plane *)((char *)(&(tri)->inputs + 1) + 3 * (tri)->inputs.stride))
1953464ebd5Sriastradh
1963464ebd5Sriastradh
197cdc920a0Smrg
198cdc920a0Smrgstruct lp_rasterizer *
1993464ebd5Sriastradhlp_rast_create( unsigned num_threads );
200cdc920a0Smrg
201cdc920a0Smrgvoid
202cdc920a0Smrglp_rast_destroy( struct lp_rasterizer * );
203cdc920a0Smrg
204cdc920a0Smrgvoid
205cdc920a0Smrglp_rast_queue_scene( struct lp_rasterizer *rast,
206cdc920a0Smrg                     struct lp_scene *scene );
207cdc920a0Smrg
208cdc920a0Smrgvoid
209cdc920a0Smrglp_rast_finish( struct lp_rasterizer *rast );
210cdc920a0Smrg
211cdc920a0Smrg
212cdc920a0Smrgunion lp_rast_cmd_arg {
213cdc920a0Smrg   const struct lp_rast_shader_inputs *shade_tile;
2143464ebd5Sriastradh   struct {
2153464ebd5Sriastradh      const struct lp_rast_triangle *tri;
2163464ebd5Sriastradh      unsigned plane_mask;
2173464ebd5Sriastradh   } triangle;
2187ec681f3Smrg   const struct lp_rast_rectangle *rectangle;
219cdc920a0Smrg   const struct lp_rast_state *set_state;
220af69d88dSmrg   const struct lp_rast_clear_rb *clear_rb;
2213464ebd5Sriastradh   struct {
222af69d88dSmrg      uint64_t value;
223af69d88dSmrg      uint64_t mask;
2243464ebd5Sriastradh   } clear_zstencil;
2253464ebd5Sriastradh   const struct lp_rast_state *state;
226cdc920a0Smrg   struct lp_fence *fence;
2273464ebd5Sriastradh   struct llvmpipe_query *query_obj;
228cdc920a0Smrg};
229cdc920a0Smrg
230cdc920a0Smrg
231cdc920a0Smrg/* Cast wrappers.  Hopefully these compile to noops!
232cdc920a0Smrg */
23301e04c3fSmrgstatic inline union lp_rast_cmd_arg
234cdc920a0Smrglp_rast_arg_inputs( const struct lp_rast_shader_inputs *shade_tile )
235cdc920a0Smrg{
236cdc920a0Smrg   union lp_rast_cmd_arg arg;
237cdc920a0Smrg   arg.shade_tile = shade_tile;
238cdc920a0Smrg   return arg;
239cdc920a0Smrg}
240cdc920a0Smrg
24101e04c3fSmrgstatic inline union lp_rast_cmd_arg
2423464ebd5Sriastradhlp_rast_arg_triangle( const struct lp_rast_triangle *triangle,
2433464ebd5Sriastradh                      unsigned plane_mask)
244cdc920a0Smrg{
245cdc920a0Smrg   union lp_rast_cmd_arg arg;
2463464ebd5Sriastradh   arg.triangle.tri = triangle;
2473464ebd5Sriastradh   arg.triangle.plane_mask = plane_mask;
248cdc920a0Smrg   return arg;
249cdc920a0Smrg}
250cdc920a0Smrg
251af69d88dSmrg/**
252af69d88dSmrg * Build argument for a contained triangle.
253af69d88dSmrg *
254af69d88dSmrg * All planes are enabled, so instead of the plane mask we pass the upper
255af69d88dSmrg * left coordinates of the a block that fully encloses the triangle.
256af69d88dSmrg */
25701e04c3fSmrgstatic inline union lp_rast_cmd_arg
258af69d88dSmrglp_rast_arg_triangle_contained( const struct lp_rast_triangle *triangle,
259af69d88dSmrg                                unsigned x, unsigned y)
260af69d88dSmrg{
261af69d88dSmrg   union lp_rast_cmd_arg arg;
262af69d88dSmrg   arg.triangle.tri = triangle;
263af69d88dSmrg   arg.triangle.plane_mask = x | (y << 8);
264af69d88dSmrg   return arg;
265af69d88dSmrg}
266af69d88dSmrg
2677ec681f3Smrgstatic inline union lp_rast_cmd_arg
2687ec681f3Smrglp_rast_arg_rectangle( const struct lp_rast_rectangle *rectangle )
2697ec681f3Smrg{
2707ec681f3Smrg   union lp_rast_cmd_arg arg;
2717ec681f3Smrg   arg.rectangle = rectangle;
2727ec681f3Smrg   return arg;
2737ec681f3Smrg}
2747ec681f3Smrg
27501e04c3fSmrgstatic inline union lp_rast_cmd_arg
276cdc920a0Smrglp_rast_arg_state( const struct lp_rast_state *state )
277cdc920a0Smrg{
278cdc920a0Smrg   union lp_rast_cmd_arg arg;
279cdc920a0Smrg   arg.set_state = state;
280cdc920a0Smrg   return arg;
281cdc920a0Smrg}
282cdc920a0Smrg
28301e04c3fSmrgstatic inline union lp_rast_cmd_arg
284cdc920a0Smrglp_rast_arg_fence( struct lp_fence *fence )
285cdc920a0Smrg{
286cdc920a0Smrg   union lp_rast_cmd_arg arg;
287cdc920a0Smrg   arg.fence = fence;
288cdc920a0Smrg   return arg;
289cdc920a0Smrg}
290cdc920a0Smrg
291cdc920a0Smrg
29201e04c3fSmrgstatic inline union lp_rast_cmd_arg
293af69d88dSmrglp_rast_arg_clearzs( uint64_t value, uint64_t mask )
2943464ebd5Sriastradh{
2953464ebd5Sriastradh   union lp_rast_cmd_arg arg;
2963464ebd5Sriastradh   arg.clear_zstencil.value = value;
2973464ebd5Sriastradh   arg.clear_zstencil.mask = mask;
2983464ebd5Sriastradh   return arg;
2993464ebd5Sriastradh}
3003464ebd5Sriastradh
3013464ebd5Sriastradh
30201e04c3fSmrgstatic inline union lp_rast_cmd_arg
3033464ebd5Sriastradhlp_rast_arg_query( struct llvmpipe_query *pq )
3043464ebd5Sriastradh{
3053464ebd5Sriastradh   union lp_rast_cmd_arg arg;
3063464ebd5Sriastradh   arg.query_obj = pq;
3073464ebd5Sriastradh   return arg;
3083464ebd5Sriastradh}
3093464ebd5Sriastradh
31001e04c3fSmrgstatic inline union lp_rast_cmd_arg
311cdc920a0Smrglp_rast_arg_null( void )
312cdc920a0Smrg{
313cdc920a0Smrg   union lp_rast_cmd_arg arg;
314cdc920a0Smrg   arg.set_state = NULL;
315cdc920a0Smrg   return arg;
316cdc920a0Smrg}
317cdc920a0Smrg
318cdc920a0Smrg
319cdc920a0Smrg/**
320cdc920a0Smrg * Binnable Commands.
321cdc920a0Smrg * These get put into bins by the setup code and are called when
322cdc920a0Smrg * the bins are executed.
323cdc920a0Smrg */
3243464ebd5Sriastradh#define LP_RAST_OP_CLEAR_COLOR       0x0
3253464ebd5Sriastradh#define LP_RAST_OP_CLEAR_ZSTENCIL    0x1
3263464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_1        0x2
3273464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_2        0x3
3283464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_3        0x4
3293464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_4        0x5
3303464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_5        0x6
3313464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_6        0x7
3323464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_7        0x8
3333464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_8        0x9
3343464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_3_4      0xa
3353464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_3_16     0xb
3363464ebd5Sriastradh#define LP_RAST_OP_TRIANGLE_4_16     0xc
3373464ebd5Sriastradh#define LP_RAST_OP_SHADE_TILE        0xd
3383464ebd5Sriastradh#define LP_RAST_OP_SHADE_TILE_OPAQUE 0xe
3393464ebd5Sriastradh#define LP_RAST_OP_BEGIN_QUERY       0xf
3403464ebd5Sriastradh#define LP_RAST_OP_END_QUERY         0x10
3413464ebd5Sriastradh#define LP_RAST_OP_SET_STATE         0x11
342af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_1     0x12
343af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_2     0x13
344af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_3     0x14
345af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_4     0x15
346af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_5     0x16
347af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_6     0x17
348af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_7     0x18
349af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_8     0x19
350af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_3_4   0x1a
351af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_3_16  0x1b
352af69d88dSmrg#define LP_RAST_OP_TRIANGLE_32_4_16  0x1c
353af69d88dSmrg
3547ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_1     0x1d
3557ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_2     0x1e
3567ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_3     0x1f
3577ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_4     0x20
3587ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_5     0x21
3597ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_6     0x22
3607ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_7     0x23
3617ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_8     0x24
3627ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_3_4   0x25
3637ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_3_16  0x26
3647ec681f3Smrg#define LP_RAST_OP_MS_TRIANGLE_4_16  0x27
3657ec681f3Smrg#define LP_RAST_OP_RECTANGLE         0x28  /* Keep at end */
3667ec681f3Smrg#define LP_RAST_OP_BLIT              0x29  /* Keep at end */
3677ec681f3Smrg
3687ec681f3Smrg#define LP_RAST_OP_MAX               0x2a
3693464ebd5Sriastradh#define LP_RAST_OP_MASK              0xff
370cdc920a0Smrg
3717ec681f3Smrg/* Returned by characterize_bin:
3727ec681f3Smrg */
3737ec681f3Smrg#define LP_RAST_FLAGS_TRI            (0x1)
3747ec681f3Smrg#define LP_RAST_FLAGS_RECT           (0x2)
3757ec681f3Smrg#define LP_RAST_FLAGS_TILE           (0x4)
3767ec681f3Smrg#define LP_RAST_FLAGS_BLIT           (0x8)
3777ec681f3Smrg
3787ec681f3Smrgstruct lp_bin_info {
3797ec681f3Smrg   unsigned type:8;
3807ec681f3Smrg   unsigned count:24;
3817ec681f3Smrg};
3827ec681f3Smrg
3837ec681f3Smrgstruct lp_bin_info
3847ec681f3Smrglp_characterize_bin(const struct cmd_bin *bin);
3857ec681f3Smrg
3863464ebd5Sriastradhvoid
3873464ebd5Sriastradhlp_debug_bins( struct lp_scene *scene );
3883464ebd5Sriastradhvoid
3893464ebd5Sriastradhlp_debug_draw_bins_by_cmd_length( struct lp_scene *scene );
3903464ebd5Sriastradhvoid
3913464ebd5Sriastradhlp_debug_draw_bins_by_coverage( struct lp_scene *scene );
392cdc920a0Smrg
393cdc920a0Smrg
394cdc920a0Smrg#endif
395