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/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 134 135void 136lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, 137 const struct lp_rast_shader_inputs *inputs, 138 unsigned x, unsigned y, 139 unsigned mask); 140 141 142/** 143 * Get the pointer to a 4x4 color block (within a 64x64 tile). 144 * \param x, y location of 4x4 block in window coords 145 */ 146static inline uint8_t * 147lp_rast_get_color_block_pointer(struct lp_rasterizer_task *task, 148 unsigned buf, unsigned x, unsigned y, 149 unsigned layer) 150{ 151 unsigned px, py, pixel_offset; 152 uint8_t *color; 153 154 assert(x < task->scene->tiles_x * TILE_SIZE); 155 assert(y < task->scene->tiles_y * TILE_SIZE); 156 assert((x % TILE_VECTOR_WIDTH) == 0); 157 assert((y % TILE_VECTOR_HEIGHT) == 0); 158 assert(buf < task->scene->fb.nr_cbufs); 159 160 assert(task->color_tiles[buf]); 161 162 /* 163 * We don't actually benefit from having per tile cbuf/zsbuf pointers, 164 * it's just extra work - the mul/add would be exactly the same anyway. 165 * Fortunately the extra work (modulo) here is very cheap at least... 166 */ 167 px = x % TILE_SIZE; 168 py = y % TILE_SIZE; 169 170 pixel_offset = px * task->scene->cbufs[buf].format_bytes + 171 py * task->scene->cbufs[buf].stride; 172 color = task->color_tiles[buf] + pixel_offset; 173 174 if (layer) { 175 color += layer * task->scene->cbufs[buf].layer_stride; 176 } 177 178 assert(lp_check_alignment(color, llvmpipe_get_format_alignment(task->scene->fb.cbufs[buf]->format))); 179 return color; 180} 181 182 183/** 184 * Get the pointer to a 4x4 depth block (within a 64x64 tile). 185 * \param x, y location of 4x4 block in window coords 186 */ 187static inline uint8_t * 188lp_rast_get_depth_block_pointer(struct lp_rasterizer_task *task, 189 unsigned x, unsigned y, unsigned layer) 190{ 191 unsigned px, py, pixel_offset; 192 uint8_t *depth; 193 194 assert(x < task->scene->tiles_x * TILE_SIZE); 195 assert(y < task->scene->tiles_y * TILE_SIZE); 196 assert((x % TILE_VECTOR_WIDTH) == 0); 197 assert((y % TILE_VECTOR_HEIGHT) == 0); 198 199 assert(task->depth_tile); 200 201 px = x % TILE_SIZE; 202 py = y % TILE_SIZE; 203 204 pixel_offset = px * task->scene->zsbuf.format_bytes + 205 py * task->scene->zsbuf.stride; 206 depth = task->depth_tile + pixel_offset; 207 208 if (layer) { 209 depth += layer * task->scene->zsbuf.layer_stride; 210 } 211 212 assert(lp_check_alignment(depth, llvmpipe_get_format_alignment(task->scene->fb.zsbuf->format))); 213 return depth; 214} 215 216 217 218/** 219 * Shade all pixels in a 4x4 block. The fragment code omits the 220 * triangle in/out tests. 221 * \param x, y location of 4x4 block in window coords 222 */ 223static inline void 224lp_rast_shade_quads_all( struct lp_rasterizer_task *task, 225 const struct lp_rast_shader_inputs *inputs, 226 unsigned x, unsigned y ) 227{ 228 const struct lp_scene *scene = task->scene; 229 const struct lp_rast_state *state = task->state; 230 struct lp_fragment_shader_variant *variant = state->variant; 231 uint8_t *color[PIPE_MAX_COLOR_BUFS]; 232 unsigned stride[PIPE_MAX_COLOR_BUFS]; 233 uint8_t *depth = NULL; 234 unsigned depth_stride = 0; 235 unsigned i; 236 237 /* color buffer */ 238 for (i = 0; i < scene->fb.nr_cbufs; i++) { 239 if (scene->fb.cbufs[i]) { 240 stride[i] = scene->cbufs[i].stride; 241 color[i] = lp_rast_get_color_block_pointer(task, i, x, y, 242 inputs->layer); 243 } 244 else { 245 stride[i] = 0; 246 color[i] = NULL; 247 } 248 } 249 250 if (scene->zsbuf.map) { 251 depth = lp_rast_get_depth_block_pointer(task, x, y, inputs->layer); 252 depth_stride = scene->zsbuf.stride; 253 } 254 255 /* 256 * The rasterizer may produce fragments outside our 257 * allocated 4x4 blocks hence need to filter them out here. 258 */ 259 if ((x % TILE_SIZE) < task->width && (y % TILE_SIZE) < task->height) { 260 /* Propagate non-interpolated raster state. */ 261 task->thread_data.raster_state.viewport_index = inputs->viewport_index; 262 263 /* run shader on 4x4 block */ 264 BEGIN_JIT_CALL(state, task); 265 variant->jit_function[RAST_WHOLE]( &state->jit_context, 266 x, y, 267 inputs->frontfacing, 268 GET_A0(inputs), 269 GET_DADX(inputs), 270 GET_DADY(inputs), 271 color, 272 depth, 273 0xffff, 274 &task->thread_data, 275 stride, 276 depth_stride); 277 END_JIT_CALL(); 278 } 279} 280 281void lp_rast_triangle_1( struct lp_rasterizer_task *, 282 const union lp_rast_cmd_arg ); 283void lp_rast_triangle_2( struct lp_rasterizer_task *, 284 const union lp_rast_cmd_arg ); 285void lp_rast_triangle_3( struct lp_rasterizer_task *, 286 const union lp_rast_cmd_arg ); 287void lp_rast_triangle_4( struct lp_rasterizer_task *, 288 const union lp_rast_cmd_arg ); 289void lp_rast_triangle_5( struct lp_rasterizer_task *, 290 const union lp_rast_cmd_arg ); 291void lp_rast_triangle_6( struct lp_rasterizer_task *, 292 const union lp_rast_cmd_arg ); 293void lp_rast_triangle_7( struct lp_rasterizer_task *, 294 const union lp_rast_cmd_arg ); 295void lp_rast_triangle_8( struct lp_rasterizer_task *, 296 const union lp_rast_cmd_arg ); 297 298void lp_rast_triangle_3_4(struct lp_rasterizer_task *, 299 const union lp_rast_cmd_arg ); 300 301void lp_rast_triangle_3_16( struct lp_rasterizer_task *, 302 const union lp_rast_cmd_arg ); 303 304void lp_rast_triangle_4_16( struct lp_rasterizer_task *, 305 const union lp_rast_cmd_arg ); 306 307 308void lp_rast_triangle_32_1( struct lp_rasterizer_task *, 309 const union lp_rast_cmd_arg ); 310void lp_rast_triangle_32_2( struct lp_rasterizer_task *, 311 const union lp_rast_cmd_arg ); 312void lp_rast_triangle_32_3( struct lp_rasterizer_task *, 313 const union lp_rast_cmd_arg ); 314void lp_rast_triangle_32_4( struct lp_rasterizer_task *, 315 const union lp_rast_cmd_arg ); 316void lp_rast_triangle_32_5( struct lp_rasterizer_task *, 317 const union lp_rast_cmd_arg ); 318void lp_rast_triangle_32_6( struct lp_rasterizer_task *, 319 const union lp_rast_cmd_arg ); 320void lp_rast_triangle_32_7( struct lp_rasterizer_task *, 321 const union lp_rast_cmd_arg ); 322void lp_rast_triangle_32_8( struct lp_rasterizer_task *, 323 const union lp_rast_cmd_arg ); 324 325void lp_rast_triangle_32_3_4(struct lp_rasterizer_task *, 326 const union lp_rast_cmd_arg ); 327 328void lp_rast_triangle_32_3_16( struct lp_rasterizer_task *, 329 const union lp_rast_cmd_arg ); 330 331void lp_rast_triangle_32_4_16( struct lp_rasterizer_task *, 332 const union lp_rast_cmd_arg ); 333 334void 335lp_rast_set_state(struct lp_rasterizer_task *task, 336 const union lp_rast_cmd_arg arg); 337 338void 339lp_debug_bin( const struct cmd_bin *bin, int x, int y ); 340 341#endif 342