/** * Run the shader on all blocks in a tile. This is used when a tile is * completely contained inside a triangle. * This is a bin command called during bin processing. */ static void lp_rast_shade_tile(struct lp_rasterizer_task *task, const union lp_rast_cmd_arg arg) { const struct lp_scene *scene = task->scene; const struct lp_rast_shader_inputs *inputs = arg.shade_tile; const struct lp_rast_state *state = inputs->state; struct lp_fragment_shader_variant *variant = state->variant; const unsigned tile_x = task->x, tile_y = task->y; unsigned x, y; if (inputs->disable) { /* This command was partially binned and has been disabled */ return; } LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); /* render the whole 64x64 tile in 4x4 chunks */ for (y = 0; y < TILE_SIZE; y += 4){ for (x = 0; x < TILE_SIZE; x += 4) { uint8_t *color[PIPE_MAX_COLOR_BUFS]; uint32_t *depth; unsigned i; /* color buffer */ for (i = 0; i < scene->fb.nr_cbufs; i++) color[i] = lp_rast_get_color_block_pointer(task, i, tile_x + x, tile_y + y); /* depth buffer */ depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y); /* run shader on 4x4 block */ BEGIN_JIT_CALL(state); variant->jit_function[RAST_WHOLE]( &state->jit_context, tile_x + x, tile_y + y, inputs->facing, inputs->a0, inputs->dadx, inputs->dady, color, depth, 0xffff, &task->vis_counter); END_JIT_CALL(); } } }
/** * Compute shading for a 4x4 block of pixels inside a triangle. * This is a bin command called during bin processing. * \param x X position of quad in window coords * \param y Y position of quad in window coords */ void lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, unsigned mask) { const struct lp_rast_state *state = inputs->state; struct lp_fragment_shader_variant *variant = state->variant; const struct lp_scene *scene = task->scene; uint8_t *color[PIPE_MAX_COLOR_BUFS]; void *depth; unsigned i; assert(state); /* Sanity checks */ assert(x % TILE_VECTOR_WIDTH == 0); assert(y % TILE_VECTOR_HEIGHT == 0); assert((x % 4) == 0); assert((y % 4) == 0); /* color buffer */ for (i = 0; i < scene->fb.nr_cbufs; i++) { color[i] = lp_rast_get_color_block_pointer(task, i, x, y); assert(lp_check_alignment(color[i], 16)); } /* depth buffer */ depth = lp_rast_get_depth_block_pointer(task, x, y); assert(lp_check_alignment(state->jit_context.blend_color, 16)); /* run shader on 4x4 block */ BEGIN_JIT_CALL(state); variant->jit_function[RAST_EDGE_TEST](&state->jit_context, x, y, inputs->facing, inputs->a0, inputs->dadx, inputs->dady, color, depth, mask, &task->vis_counter); END_JIT_CALL(); }
/** * Compute shading for a 4x4 block of pixels inside a triangle. * This is a bin command called during bin processing. * \param x X position of quad in window coords * \param y Y position of quad in window coords */ void lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, const struct lp_rast_shader_inputs *inputs, unsigned x, unsigned y, unsigned mask) { const struct lp_rast_state *state = task->state; struct lp_fragment_shader_variant *variant = state->variant; const struct lp_scene *scene = task->scene; uint8_t *color[PIPE_MAX_COLOR_BUFS]; unsigned stride[PIPE_MAX_COLOR_BUFS]; uint8_t *depth = NULL; unsigned depth_stride = 0; unsigned i; assert(state); /* Sanity checks */ assert(x < scene->tiles_x * TILE_SIZE); assert(y < scene->tiles_y * TILE_SIZE); assert(x % TILE_VECTOR_WIDTH == 0); assert(y % TILE_VECTOR_HEIGHT == 0); assert((x % 4) == 0); assert((y % 4) == 0); /* color buffer */ for (i = 0; i < scene->fb.nr_cbufs; i++) { if (scene->fb.cbufs[i]) { stride[i] = scene->cbufs[i].stride; color[i] = lp_rast_get_color_block_pointer(task, i, x, y, inputs->layer); } else { stride[i] = 0; color[i] = NULL; } } /* depth buffer */ if (scene->zsbuf.map) { depth_stride = scene->zsbuf.stride; depth = lp_rast_get_depth_block_pointer(task, x, y, inputs->layer); } assert(lp_check_alignment(state->jit_context.u8_blend_color, 16)); /* * The rasterizer may produce fragments outside our * allocated 4x4 blocks hence need to filter them out here. */ if ((x % TILE_SIZE) < task->width && (y % TILE_SIZE) < task->height) { /* not very accurate would need a popcount on the mask */ /* always count this not worth bothering? */ task->ps_invocations += 1 * variant->ps_inv_multiplier; /* Propagate non-interpolated raster state. */ task->thread_data.raster_state.viewport_index = inputs->viewport_index; /* run shader on 4x4 block */ BEGIN_JIT_CALL(state, task); variant->jit_function[RAST_EDGE_TEST](&state->jit_context, x, y, inputs->frontfacing, GET_A0(inputs), GET_DADX(inputs), GET_DADY(inputs), color, depth, mask, &task->thread_data, stride, depth_stride); END_JIT_CALL(); } }
/** * Run the shader on all blocks in a tile. This is used when a tile is * completely contained inside a triangle. * This is a bin command called during bin processing. */ static void lp_rast_shade_tile(struct lp_rasterizer_task *task, const union lp_rast_cmd_arg arg) { const struct lp_scene *scene = task->scene; const struct lp_rast_shader_inputs *inputs = arg.shade_tile; const struct lp_rast_state *state; struct lp_fragment_shader_variant *variant; const unsigned tile_x = task->x, tile_y = task->y; unsigned x, y; if (inputs->disable) { /* This command was partially binned and has been disabled */ return; } LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__); state = task->state; assert(state); if (!state) { return; } variant = state->variant; /* render the whole 64x64 tile in 4x4 chunks */ for (y = 0; y < task->height; y += 4){ for (x = 0; x < task->width; x += 4) { uint8_t *color[PIPE_MAX_COLOR_BUFS]; unsigned stride[PIPE_MAX_COLOR_BUFS]; uint8_t *depth = NULL; unsigned depth_stride = 0; unsigned i; /* color buffer */ for (i = 0; i < scene->fb.nr_cbufs; i++){ if (scene->fb.cbufs[i]) { stride[i] = scene->cbufs[i].stride; color[i] = lp_rast_get_color_block_pointer(task, i, tile_x + x, tile_y + y, inputs->layer); } else { stride[i] = 0; color[i] = NULL; } } /* depth buffer */ if (scene->zsbuf.map) { depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y, inputs->layer); depth_stride = scene->zsbuf.stride; } /* Propagate non-interpolated raster state. */ task->thread_data.raster_state.viewport_index = inputs->viewport_index; /* run shader on 4x4 block */ BEGIN_JIT_CALL(state, task); variant->jit_function[RAST_WHOLE]( &state->jit_context, tile_x + x, tile_y + y, inputs->frontfacing, GET_A0(inputs), GET_DADX(inputs), GET_DADY(inputs), color, depth, 0xffff, &task->thread_data, stride, depth_stride); END_JIT_CALL(); } } }