/** * 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]; void *depth; 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++) { 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, 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->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(); } }
/** * Execute fragment shader for the four fragments in the quad. */ ALIGN_STACK static void shade_quads(struct llvmpipe_context *llvmpipe, struct quad_header *quads[], unsigned nr) { struct lp_fragment_shader *fs = llvmpipe->fs; struct quad_header *quad = quads[0]; const unsigned x = quad->input.x0; const unsigned y = quad->input.y0; uint8_t *tile; uint8_t *color; void *depth; uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS]; unsigned chan_index; unsigned q; assert(fs->current); if(!fs->current) return; /* Sanity checks */ assert(nr * QUAD_SIZE == TILE_VECTOR_HEIGHT * TILE_VECTOR_WIDTH); assert(x % TILE_VECTOR_WIDTH == 0); assert(y % TILE_VECTOR_HEIGHT == 0); for (q = 0; q < nr; ++q) { assert(quads[q]->input.x0 == x + q*2); assert(quads[q]->input.y0 == y); } /* mask */ for (q = 0; q < 4; ++q) for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index) mask[q][chan_index] = quads[q]->inout.mask & (1 << chan_index) ? ~0 : 0; /* color buffer */ if(llvmpipe->framebuffer.nr_cbufs >= 1 && llvmpipe->framebuffer.cbufs[0]) { tile = lp_get_cached_tile(llvmpipe->cbuf_cache[0], x, y); color = &TILE_PIXEL(tile, x & (TILE_SIZE-1), y & (TILE_SIZE-1), 0); } else color = NULL; /* depth buffer */ if(llvmpipe->zsbuf_map) { assert((x % 2) == 0); assert((y % 2) == 0); depth = llvmpipe->zsbuf_map + y*llvmpipe->zsbuf_transfer->stride + 2*x*llvmpipe->zsbuf_transfer->block.size; } else depth = NULL; /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */ assert(lp_check_alignment(mask, 16)); assert(lp_check_alignment(depth, 16)); assert(lp_check_alignment(color, 16)); assert(lp_check_alignment(llvmpipe->jit_context.blend_color, 16)); /* run shader */ fs->current->jit_function( &llvmpipe->jit_context, x, y, quad->coef->a0, quad->coef->dadx, quad->coef->dady, &mask[0][0], color, depth); }