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 "os/os_thread.h" 32 #include "util/u_format.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 50 struct lp_rasterizer_task; 51 extern int jit_line; 52 extern const struct lp_rast_state *jit_state; 53 extern 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 76 struct lp_rasterizer; 77 struct cmd_bin; 78 79 /** 80 * Per-thread rasterization state 81 */ 82 struct 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 uint64_t ps_invocations; 103 uint8_t ps_inv_multiplier; 104 105 pipe_semaphore work_ready; 106 pipe_semaphore work_done; 107 }; 108 109 110 /** 111 * This is the state required while rasterizing tiles. 112 * Note that this contains per-thread information too. 113 * The tile size is TILE_SIZE x TILE_SIZE pixels. 114 */ 115 struct lp_rasterizer 116 { 117 boolean exit_flag; 118 boolean no_rast; /**< For debugging/profiling */ 119 120 /** The incoming queue of scenes ready to rasterize */ 121 struct lp_scene_queue *full_scenes; 122 123 /** The scene currently being rasterized by the threads */ 124 struct lp_scene *curr_scene; 125 126 /** A task object for each rasterization thread */ 127 struct lp_rasterizer_task tasks[LP_MAX_THREADS]; 128 129 unsigned num_threads; 130 pipe_thread threads[LP_MAX_THREADS]; 131 132 /** For synchronizing the rasterization threads */ 133 pipe_barrier barrier; 134 }; 135 136 137 void 138 lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, 139 const struct lp_rast_shader_inputs *inputs, 140 unsigned x, unsigned y, 141 unsigned mask); 142 143 144 /** 145 * Get the pointer to a 4x4 color block (within a 64x64 tile). 146 * \param x, y location of 4x4 block in window coords 147 */ 148 static inline uint8_t * 149 lp_rast_get_color_block_pointer(struct lp_rasterizer_task *task, 150 unsigned buf, unsigned x, unsigned y, 151 unsigned layer) 152 { 153 unsigned px, py, pixel_offset; 154 uint8_t *color; 155 156 assert(x < task->scene->tiles_x * TILE_SIZE); 157 assert(y < task->scene->tiles_y * TILE_SIZE); 158 assert((x % TILE_VECTOR_WIDTH) == 0); 159 assert((y % TILE_VECTOR_HEIGHT) == 0); 160 assert(buf < task->scene->fb.nr_cbufs); 161 162 assert(task->color_tiles[buf]); 163 164 /* 165 * We don't actually benefit from having per tile cbuf/zsbuf pointers, 166 * it's just extra work - the mul/add would be exactly the same anyway. 167 * Fortunately the extra work (modulo) here is very cheap at least... 168 */ 169 px = x % TILE_SIZE; 170 py = y % TILE_SIZE; 171 172 pixel_offset = px * task->scene->cbufs[buf].format_bytes + 173 py * task->scene->cbufs[buf].stride; 174 color = task->color_tiles[buf] + pixel_offset; 175 176 if (layer) { 177 color += layer * task->scene->cbufs[buf].layer_stride; 178 } 179 180 assert(lp_check_alignment(color, llvmpipe_get_format_alignment(task->scene->fb.cbufs[buf]->format))); 181 return color; 182 } 183 184 185 /** 186 * Get the pointer to a 4x4 depth block (within a 64x64 tile). 187 * \param x, y location of 4x4 block in window coords 188 */ 189 static inline uint8_t * 190 lp_rast_get_depth_block_pointer(struct lp_rasterizer_task *task, 191 unsigned x, unsigned y, unsigned layer) 192 { 193 unsigned px, py, pixel_offset; 194 uint8_t *depth; 195 196 assert(x < task->scene->tiles_x * TILE_SIZE); 197 assert(y < task->scene->tiles_y * TILE_SIZE); 198 assert((x % TILE_VECTOR_WIDTH) == 0); 199 assert((y % TILE_VECTOR_HEIGHT) == 0); 200 201 assert(task->depth_tile); 202 203 px = x % TILE_SIZE; 204 py = y % TILE_SIZE; 205 206 pixel_offset = px * task->scene->zsbuf.format_bytes + 207 py * task->scene->zsbuf.stride; 208 depth = task->depth_tile + pixel_offset; 209 210 if (layer) { 211 depth += layer * task->scene->zsbuf.layer_stride; 212 } 213 214 assert(lp_check_alignment(depth, llvmpipe_get_format_alignment(task->scene->fb.zsbuf->format))); 215 return depth; 216 } 217 218 219 220 /** 221 * Shade all pixels in a 4x4 block. The fragment code omits the 222 * triangle in/out tests. 223 * \param x, y location of 4x4 block in window coords 224 */ 225 static inline void 226 lp_rast_shade_quads_all( struct lp_rasterizer_task *task, 227 const struct lp_rast_shader_inputs *inputs, 228 unsigned x, unsigned y ) 229 { 230 const struct lp_scene *scene = task->scene; 231 const struct lp_rast_state *state = task->state; 232 struct lp_fragment_shader_variant *variant = state->variant; 233 uint8_t *color[PIPE_MAX_COLOR_BUFS]; 234 unsigned stride[PIPE_MAX_COLOR_BUFS]; 235 uint8_t *depth = NULL; 236 unsigned depth_stride = 0; 237 unsigned i; 238 239 /* color buffer */ 240 for (i = 0; i < scene->fb.nr_cbufs; i++) { 241 if (scene->fb.cbufs[i]) { 242 stride[i] = scene->cbufs[i].stride; 243 color[i] = lp_rast_get_color_block_pointer(task, i, x, y, 244 inputs->layer); 245 } 246 else { 247 stride[i] = 0; 248 color[i] = NULL; 249 } 250 } 251 252 if (scene->zsbuf.map) { 253 depth = lp_rast_get_depth_block_pointer(task, x, y, inputs->layer); 254 depth_stride = scene->zsbuf.stride; 255 } 256 257 /* 258 * The rasterizer may produce fragments outside our 259 * allocated 4x4 blocks hence need to filter them out here. 260 */ 261 if ((x % TILE_SIZE) < task->width && (y % TILE_SIZE) < task->height) { 262 /* not very accurate would need a popcount on the mask */ 263 /* always count this not worth bothering? */ 264 task->ps_invocations += 1 * variant->ps_inv_multiplier; 265 266 /* Propagate non-interpolated raster state. */ 267 task->thread_data.raster_state.viewport_index = inputs->viewport_index; 268 269 /* run shader on 4x4 block */ 270 BEGIN_JIT_CALL(state, task); 271 variant->jit_function[RAST_WHOLE]( &state->jit_context, 272 x, y, 273 inputs->frontfacing, 274 GET_A0(inputs), 275 GET_DADX(inputs), 276 GET_DADY(inputs), 277 color, 278 depth, 279 0xffff, 280 &task->thread_data, 281 stride, 282 depth_stride); 283 END_JIT_CALL(); 284 } 285 } 286 287 void lp_rast_triangle_1( struct lp_rasterizer_task *, 288 const union lp_rast_cmd_arg ); 289 void lp_rast_triangle_2( struct lp_rasterizer_task *, 290 const union lp_rast_cmd_arg ); 291 void lp_rast_triangle_3( struct lp_rasterizer_task *, 292 const union lp_rast_cmd_arg ); 293 void lp_rast_triangle_4( struct lp_rasterizer_task *, 294 const union lp_rast_cmd_arg ); 295 void lp_rast_triangle_5( struct lp_rasterizer_task *, 296 const union lp_rast_cmd_arg ); 297 void lp_rast_triangle_6( struct lp_rasterizer_task *, 298 const union lp_rast_cmd_arg ); 299 void lp_rast_triangle_7( struct lp_rasterizer_task *, 300 const union lp_rast_cmd_arg ); 301 void lp_rast_triangle_8( struct lp_rasterizer_task *, 302 const union lp_rast_cmd_arg ); 303 304 void lp_rast_triangle_3_4(struct lp_rasterizer_task *, 305 const union lp_rast_cmd_arg ); 306 307 void lp_rast_triangle_3_16( struct lp_rasterizer_task *, 308 const union lp_rast_cmd_arg ); 309 310 void lp_rast_triangle_4_16( struct lp_rasterizer_task *, 311 const union lp_rast_cmd_arg ); 312 313 314 void lp_rast_triangle_32_1( struct lp_rasterizer_task *, 315 const union lp_rast_cmd_arg ); 316 void lp_rast_triangle_32_2( struct lp_rasterizer_task *, 317 const union lp_rast_cmd_arg ); 318 void lp_rast_triangle_32_3( struct lp_rasterizer_task *, 319 const union lp_rast_cmd_arg ); 320 void lp_rast_triangle_32_4( struct lp_rasterizer_task *, 321 const union lp_rast_cmd_arg ); 322 void lp_rast_triangle_32_5( struct lp_rasterizer_task *, 323 const union lp_rast_cmd_arg ); 324 void lp_rast_triangle_32_6( struct lp_rasterizer_task *, 325 const union lp_rast_cmd_arg ); 326 void lp_rast_triangle_32_7( struct lp_rasterizer_task *, 327 const union lp_rast_cmd_arg ); 328 void lp_rast_triangle_32_8( struct lp_rasterizer_task *, 329 const union lp_rast_cmd_arg ); 330 331 void lp_rast_triangle_32_3_4(struct lp_rasterizer_task *, 332 const union lp_rast_cmd_arg ); 333 334 void lp_rast_triangle_32_3_16( struct lp_rasterizer_task *, 335 const union lp_rast_cmd_arg ); 336 337 void lp_rast_triangle_32_4_16( struct lp_rasterizer_task *, 338 const union lp_rast_cmd_arg ); 339 340 void 341 lp_rast_set_state(struct lp_rasterizer_task *task, 342 const union lp_rast_cmd_arg arg); 343 344 void 345 lp_debug_bin( const struct cmd_bin *bin, int x, int y ); 346 347 #endif 348