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#ifndef LP_RAST_PRIV_H 29#define LP_RAST_PRIV_H 30 31#include "util/format/u_format.h" 32#include "util/u_thread.h" 33#include "gallivm/lp_bld_debug.h" 34#include "lp_memory.h" 35#include "lp_rast.h" 36#include "lp_scene.h" 37#include "lp_state.h" 38#include "lp_texture.h" 39#include "lp_limits.h" 40 41 42#define TILE_VECTOR_HEIGHT 4 43#define TILE_VECTOR_WIDTH 4 44 45/* If we crash in a jitted function, we can examine jit_line and jit_state 46 * to get some info. This is not thread-safe, however. 47 */ 48#ifdef DEBUG 49 50struct lp_rasterizer_task; 51extern int jit_line; 52extern const struct lp_rast_state *jit_state; 53extern const struct lp_rasterizer_task *jit_task; 54 55#define BEGIN_JIT_CALL(state, task) \ 56 do { \ 57 jit_line = __LINE__; \ 58 jit_state = state; \ 59 jit_task = task; \ 60 } while (0) 61 62#define END_JIT_CALL() \ 63 do { \ 64 jit_line = 0; \ 65 jit_state = NULL; \ 66 } while (0) 67 68#else 69 70#define BEGIN_JIT_CALL(X, Y) 71#define END_JIT_CALL() 72 73#endif 74 75 76struct lp_rasterizer; 77struct cmd_bin; 78 79/** 80 * Per-thread rasterization state 81 */ 82struct lp_rasterizer_task 83{ 84 const struct cmd_bin *bin; 85 const struct lp_rast_state *state; 86 87 struct lp_scene *scene; 88 unsigned x, y; /**< Pos of this tile in framebuffer, in pixels */ 89 unsigned width, height; /**< width, height of current tile, in pixels */ 90 91 uint8_t *color_tiles[PIPE_MAX_COLOR_BUFS]; 92 uint8_t *depth_tile; 93 94 /** "back" pointer */ 95 struct lp_rasterizer *rast; 96 97 /** "my" index */ 98 unsigned thread_index; 99 100 /** Non-interpolated passthru state and occlude counter for visible pixels */ 101 struct lp_jit_thread_data thread_data; 102 103 pipe_semaphore work_ready; 104 pipe_semaphore work_done; 105}; 106 107 108/** 109 * This is the state required while rasterizing tiles. 110 * Note that this contains per-thread information too. 111 * The tile size is TILE_SIZE x TILE_SIZE pixels. 112 */ 113struct lp_rasterizer 114{ 115 boolean exit_flag; 116 boolean no_rast; /**< For debugging/profiling */ 117 118 /** The incoming queue of scenes ready to rasterize */ 119 struct lp_scene_queue *full_scenes; 120 121 /** The scene currently being rasterized by the threads */ 122 struct lp_scene *curr_scene; 123 124 /** A task object for each rasterization thread */ 125 struct lp_rasterizer_task tasks[LP_MAX_THREADS]; 126 127 unsigned num_threads; 128 thrd_t threads[LP_MAX_THREADS]; 129 130 /** For synchronizing the rasterization threads */ 131 util_barrier barrier; 132}; 133 134void 135lp_rast_shade_quads_mask_sample(struct lp_rasterizer_task *task, 136 const struct lp_rast_shader_inputs *inputs, 137 unsigned x, unsigned y, 138 uint64_t mask); 139void 140lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, 141 const struct lp_rast_shader_inputs *inputs, 142 unsigned x, unsigned y, 143 unsigned mask); 144 145 146/** 147 * Get the pointer to a 4x4 color block (within a 64x64 tile). 148 * \param x, y location of 4x4 block in window coords 149 */ 150static inline uint8_t * 151lp_rast_get_color_block_pointer(struct lp_rasterizer_task *task, 152 unsigned buf, unsigned x, unsigned y, 153 unsigned layer) 154{ 155 unsigned px, py, pixel_offset; 156 uint8_t *color; 157 158 assert(x < task->scene->tiles_x * TILE_SIZE); 159 assert(y < task->scene->tiles_y * TILE_SIZE); 160 assert((x % TILE_VECTOR_WIDTH) == 0); 161 assert((y % TILE_VECTOR_HEIGHT) == 0); 162 assert(buf < task->scene->fb.nr_cbufs); 163 164 assert(task->color_tiles[buf]); 165 166 /* 167 * We don't actually benefit from having per tile cbuf/zsbuf pointers, 168 * it's just extra work - the mul/add would be exactly the same anyway. 169 * Fortunately the extra work (modulo) here is very cheap at least... 170 */ 171 px = x % TILE_SIZE; 172 py = y % TILE_SIZE; 173 174 pixel_offset = px * task->scene->cbufs[buf].format_bytes + 175 py * task->scene->cbufs[buf].stride; 176 color = task->color_tiles[buf] + pixel_offset; 177 178 if (layer) { 179 assert(layer <= task->scene->fb_max_layer); 180 color += layer * task->scene->cbufs[buf].layer_stride; 181 } 182 183 assert(lp_check_alignment(color, llvmpipe_get_format_alignment(task->scene->fb.cbufs[buf]->format))); 184 return color; 185} 186 187 188/** 189 * Get the pointer to a 4x4 depth block (within a 64x64 tile). 190 * \param x, y location of 4x4 block in window coords 191 */ 192static inline uint8_t * 193lp_rast_get_depth_block_pointer(struct lp_rasterizer_task *task, 194 unsigned x, unsigned y, unsigned layer) 195{ 196 unsigned px, py, pixel_offset; 197 uint8_t *depth; 198 199 assert(x < task->scene->tiles_x * TILE_SIZE); 200 assert(y < task->scene->tiles_y * TILE_SIZE); 201 assert((x % TILE_VECTOR_WIDTH) == 0); 202 assert((y % TILE_VECTOR_HEIGHT) == 0); 203 204 assert(task->depth_tile); 205 206 px = x % TILE_SIZE; 207 py = y % TILE_SIZE; 208 209 pixel_offset = px * task->scene->zsbuf.format_bytes + 210 py * task->scene->zsbuf.stride; 211 depth = task->depth_tile + pixel_offset; 212 213 if (layer) { 214 depth += layer * task->scene->zsbuf.layer_stride; 215 } 216 217 assert(lp_check_alignment(depth, llvmpipe_get_format_alignment(task->scene->fb.zsbuf->format))); 218 return depth; 219} 220 221 222 223/** 224 * Shade all pixels in a 4x4 block. The fragment code omits the 225 * triangle in/out tests. 226 * \param x, y location of 4x4 block in window coords 227 */ 228static inline void 229lp_rast_shade_quads_all( struct lp_rasterizer_task *task, 230 const struct lp_rast_shader_inputs *inputs, 231 unsigned x, unsigned y ) 232{ 233 const struct lp_scene *scene = task->scene; 234 const struct lp_rast_state *state = task->state; 235 struct lp_fragment_shader_variant *variant = state->variant; 236 uint8_t *color[PIPE_MAX_COLOR_BUFS]; 237 unsigned stride[PIPE_MAX_COLOR_BUFS]; 238 unsigned sample_stride[PIPE_MAX_COLOR_BUFS]; 239 uint8_t *depth = NULL; 240 unsigned depth_stride = 0; 241 unsigned depth_sample_stride = 0; 242 unsigned i; 243 244 /* color buffer */ 245 for (i = 0; i < scene->fb.nr_cbufs; i++) { 246 if (scene->fb.cbufs[i]) { 247 stride[i] = scene->cbufs[i].stride; 248 sample_stride[i] = scene->cbufs[i].sample_stride; 249 color[i] = lp_rast_get_color_block_pointer(task, i, x, y, 250 inputs->layer + inputs->view_index); 251 } 252 else { 253 stride[i] = 0; 254 sample_stride[i] = 0; 255 color[i] = NULL; 256 } 257 } 258 259 if (scene->zsbuf.map) { 260 depth = lp_rast_get_depth_block_pointer(task, x, y, inputs->layer + inputs->view_index); 261 depth_sample_stride = scene->zsbuf.sample_stride; 262 depth_stride = scene->zsbuf.stride; 263 } 264 265 uint64_t mask = 0; 266 for (unsigned i = 0; i < scene->fb_max_samples; i++) 267 mask |= (uint64_t)0xffff << (16 * i); 268 269 /* 270 * The rasterizer may produce fragments outside our 271 * allocated 4x4 blocks hence need to filter them out here. 272 */ 273 if ((x % TILE_SIZE) < task->width && (y % TILE_SIZE) < task->height) { 274 /* Propagate non-interpolated raster state. */ 275 task->thread_data.raster_state.viewport_index = inputs->viewport_index; 276 task->thread_data.raster_state.view_index = inputs->view_index; 277 278 /* run shader on 4x4 block */ 279 BEGIN_JIT_CALL(state, task); 280 variant->jit_function[RAST_WHOLE]( &state->jit_context, 281 x, y, 282 inputs->frontfacing, 283 GET_A0(inputs), 284 GET_DADX(inputs), 285 GET_DADY(inputs), 286 color, 287 depth, 288 mask, 289 &task->thread_data, 290 stride, 291 depth_stride, 292 sample_stride, 293 depth_sample_stride); 294 END_JIT_CALL(); 295 } 296} 297 298void lp_rast_triangle_1( struct lp_rasterizer_task *, 299 const union lp_rast_cmd_arg ); 300void lp_rast_triangle_2( struct lp_rasterizer_task *, 301 const union lp_rast_cmd_arg ); 302void lp_rast_triangle_3( struct lp_rasterizer_task *, 303 const union lp_rast_cmd_arg ); 304void lp_rast_triangle_4( struct lp_rasterizer_task *, 305 const union lp_rast_cmd_arg ); 306void lp_rast_triangle_5( struct lp_rasterizer_task *, 307 const union lp_rast_cmd_arg ); 308void lp_rast_triangle_6( struct lp_rasterizer_task *, 309 const union lp_rast_cmd_arg ); 310void lp_rast_triangle_7( struct lp_rasterizer_task *, 311 const union lp_rast_cmd_arg ); 312void lp_rast_triangle_8( struct lp_rasterizer_task *, 313 const union lp_rast_cmd_arg ); 314 315void lp_rast_triangle_3_4(struct lp_rasterizer_task *, 316 const union lp_rast_cmd_arg ); 317 318void lp_rast_triangle_3_16( struct lp_rasterizer_task *, 319 const union lp_rast_cmd_arg ); 320 321void lp_rast_triangle_4_16( struct lp_rasterizer_task *, 322 const union lp_rast_cmd_arg ); 323 324 325void lp_rast_triangle_32_1( struct lp_rasterizer_task *, 326 const union lp_rast_cmd_arg ); 327void lp_rast_triangle_32_2( struct lp_rasterizer_task *, 328 const union lp_rast_cmd_arg ); 329void lp_rast_triangle_32_3( struct lp_rasterizer_task *, 330 const union lp_rast_cmd_arg ); 331void lp_rast_triangle_32_4( struct lp_rasterizer_task *, 332 const union lp_rast_cmd_arg ); 333void lp_rast_triangle_32_5( struct lp_rasterizer_task *, 334 const union lp_rast_cmd_arg ); 335void lp_rast_triangle_32_6( struct lp_rasterizer_task *, 336 const union lp_rast_cmd_arg ); 337void lp_rast_triangle_32_7( struct lp_rasterizer_task *, 338 const union lp_rast_cmd_arg ); 339void lp_rast_triangle_32_8( struct lp_rasterizer_task *, 340 const union lp_rast_cmd_arg ); 341 342void lp_rast_triangle_32_3_4(struct lp_rasterizer_task *, 343 const union lp_rast_cmd_arg ); 344 345void lp_rast_triangle_32_3_16( struct lp_rasterizer_task *, 346 const union lp_rast_cmd_arg ); 347 348void lp_rast_triangle_32_4_16( struct lp_rasterizer_task *, 349 const union lp_rast_cmd_arg ); 350 351 352void lp_rast_rectangle( struct lp_rasterizer_task *, 353 const union lp_rast_cmd_arg ); 354 355void lp_rast_triangle_ms_1( struct lp_rasterizer_task *, 356 const union lp_rast_cmd_arg ); 357void lp_rast_triangle_ms_2( struct lp_rasterizer_task *, 358 const union lp_rast_cmd_arg ); 359void lp_rast_triangle_ms_3( struct lp_rasterizer_task *, 360 const union lp_rast_cmd_arg ); 361void lp_rast_triangle_ms_4( struct lp_rasterizer_task *, 362 const union lp_rast_cmd_arg ); 363void lp_rast_triangle_ms_5( struct lp_rasterizer_task *, 364 const union lp_rast_cmd_arg ); 365void lp_rast_triangle_ms_6( struct lp_rasterizer_task *, 366 const union lp_rast_cmd_arg ); 367void lp_rast_triangle_ms_7( struct lp_rasterizer_task *, 368 const union lp_rast_cmd_arg ); 369void lp_rast_triangle_ms_8( struct lp_rasterizer_task *, 370 const union lp_rast_cmd_arg ); 371 372void lp_rast_triangle_ms_3_4(struct lp_rasterizer_task *, 373 const union lp_rast_cmd_arg ); 374 375void lp_rast_triangle_ms_3_16( struct lp_rasterizer_task *, 376 const union lp_rast_cmd_arg ); 377 378void lp_rast_triangle_ms_4_16( struct lp_rasterizer_task *, 379 const union lp_rast_cmd_arg ); 380 381void lp_rast_triangle_ms_32_1( struct lp_rasterizer_task *, 382 const union lp_rast_cmd_arg ); 383void lp_rast_triangle_ms_32_2( struct lp_rasterizer_task *, 384 const union lp_rast_cmd_arg ); 385void lp_rast_triangle_ms_32_3( struct lp_rasterizer_task *, 386 const union lp_rast_cmd_arg ); 387void lp_rast_triangle_ms_32_4( struct lp_rasterizer_task *, 388 const union lp_rast_cmd_arg ); 389void lp_rast_triangle_ms_32_5( struct lp_rasterizer_task *, 390 const union lp_rast_cmd_arg ); 391void lp_rast_triangle_ms_32_6( struct lp_rasterizer_task *, 392 const union lp_rast_cmd_arg ); 393void lp_rast_triangle_ms_32_7( struct lp_rasterizer_task *, 394 const union lp_rast_cmd_arg ); 395void lp_rast_triangle_ms_32_8( struct lp_rasterizer_task *, 396 const union lp_rast_cmd_arg ); 397 398void lp_rast_triangle_ms_32_3_4(struct lp_rasterizer_task *, 399 const union lp_rast_cmd_arg ); 400 401void lp_rast_triangle_ms_32_3_16( struct lp_rasterizer_task *, 402 const union lp_rast_cmd_arg ); 403 404void lp_rast_triangle_ms_32_4_16( struct lp_rasterizer_task *, 405 const union lp_rast_cmd_arg ); 406 407void 408lp_rast_set_state(struct lp_rasterizer_task *task, 409 const union lp_rast_cmd_arg arg); 410 411void 412lp_debug_bin( const struct cmd_bin *bin, int x, int y ); 413 414void 415lp_linear_rasterize_bin(struct lp_rasterizer_task *task, 416 const struct cmd_bin *bin); 417 418void 419lp_rast_linear_rect_fallback(struct lp_rasterizer_task *task, 420 const struct lp_rast_shader_inputs *inputs, 421 const struct u_rect *box); 422 423#endif 424