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