llvmpipe: adapt to clear interface changes
with some newfangled code, should support separate depth/stencil clears. Needs some testing.
This commit is contained in:
@@ -177,7 +177,7 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
|
||||
if (zsbuf) {
|
||||
struct llvmpipe_resource *lpt = llvmpipe_resource(zsbuf->texture);
|
||||
|
||||
if (scene->has_depth_clear)
|
||||
if (scene->has_depthstencil_clear)
|
||||
usage = LP_TEX_USAGE_WRITE_ALL;
|
||||
else
|
||||
usage = LP_TEX_USAGE_READ_WRITE;
|
||||
@@ -269,6 +269,9 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
|
||||
const union lp_rast_cmd_arg arg)
|
||||
{
|
||||
struct lp_rasterizer *rast = task->rast;
|
||||
const struct lp_rast_clearzs *clearzs = arg.clear_zstencil;
|
||||
unsigned clear_value = clearzs->clearzs_value;
|
||||
unsigned clear_mask = clearzs->clearzs_mask;
|
||||
const unsigned height = TILE_SIZE / TILE_VECTOR_HEIGHT;
|
||||
const unsigned width = TILE_SIZE * TILE_VECTOR_HEIGHT;
|
||||
const unsigned block_size = rast->zsbuf.blocksize;
|
||||
@@ -276,7 +279,7 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
|
||||
uint8_t *dst;
|
||||
unsigned i, j;
|
||||
|
||||
LP_DBG(DEBUG_RAST, "%s 0x%x\n", __FUNCTION__, arg.clear_zstencil);
|
||||
LP_DBG(DEBUG_RAST, "%s 0x%x%x\n", __FUNCTION__, clear_value, clear_mask);
|
||||
|
||||
/*
|
||||
* Clear the aera of the swizzled depth/depth buffer matching this tile, in
|
||||
@@ -292,22 +295,34 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
|
||||
|
||||
switch (block_size) {
|
||||
case 1:
|
||||
memset(dst, (uint8_t) arg.clear_zstencil, height * width);
|
||||
memset(dst, (uint8_t) clear_value, height * width);
|
||||
break;
|
||||
case 2:
|
||||
for (i = 0; i < height; i++) {
|
||||
uint16_t *row = (uint16_t *)dst;
|
||||
for (j = 0; j < width; j++)
|
||||
*row++ = (uint16_t) arg.clear_zstencil;
|
||||
*row++ = (uint16_t) clear_value;
|
||||
dst += dst_stride;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
for (i = 0; i < height; i++) {
|
||||
uint32_t *row = (uint32_t *)dst;
|
||||
for (j = 0; j < width; j++)
|
||||
*row++ = arg.clear_zstencil;
|
||||
dst += dst_stride;
|
||||
if (clear_mask == 0xffffffff) {
|
||||
for (i = 0; i < height; i++) {
|
||||
uint32_t *row = (uint32_t *)dst;
|
||||
for (j = 0; j < width; j++)
|
||||
*row++ = clear_value;
|
||||
dst += dst_stride;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < height; i++) {
|
||||
uint32_t *row = (uint32_t *)dst;
|
||||
for (j = 0; j < width; j++) {
|
||||
uint32_t tmp = ~clear_mask & *row;
|
||||
*row++ = (clear_value & clear_mask) | tmp;
|
||||
}
|
||||
dst += dst_stride;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@@ -92,6 +92,11 @@ struct lp_rast_shader_inputs {
|
||||
PIPE_ALIGN_VAR(16) int step[3][16];
|
||||
};
|
||||
|
||||
struct lp_rast_clearzs {
|
||||
unsigned clearzs_value;
|
||||
unsigned clearzs_mask;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rasterization information for a triangle known to be in this bin,
|
||||
@@ -155,7 +160,7 @@ union lp_rast_cmd_arg {
|
||||
const struct lp_rast_triangle *triangle;
|
||||
const struct lp_rast_state *set_state;
|
||||
uint8_t clear_color[4];
|
||||
unsigned clear_zstencil;
|
||||
const struct lp_rast_clearzs *clear_zstencil;
|
||||
struct lp_fence *fence;
|
||||
struct llvmpipe_query *query_obj;
|
||||
};
|
||||
@@ -196,6 +201,14 @@ lp_rast_arg_fence( struct lp_fence *fence )
|
||||
}
|
||||
|
||||
|
||||
static INLINE union lp_rast_cmd_arg
|
||||
lp_rast_arg_clearzs( const struct lp_rast_clearzs *clearzs )
|
||||
{
|
||||
union lp_rast_cmd_arg arg;
|
||||
arg.clear_zstencil = clearzs;
|
||||
return arg;
|
||||
}
|
||||
|
||||
static INLINE union lp_rast_cmd_arg
|
||||
lp_rast_arg_null( void )
|
||||
{
|
||||
@@ -205,7 +218,6 @@ lp_rast_arg_null( void )
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Binnable Commands.
|
||||
* These get put into bins by the setup code and are called when
|
||||
|
@@ -201,7 +201,7 @@ lp_scene_reset(struct lp_scene *scene )
|
||||
scene->scene_size = 0;
|
||||
|
||||
scene->has_color_clear = FALSE;
|
||||
scene->has_depth_clear = FALSE;
|
||||
scene->has_depthstencil_clear = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -125,7 +125,7 @@ struct lp_scene {
|
||||
unsigned scene_size;
|
||||
|
||||
boolean has_color_clear;
|
||||
boolean has_depth_clear;
|
||||
boolean has_depthstencil_clear;
|
||||
|
||||
/**
|
||||
* Number of active tiles in each dimension.
|
||||
|
@@ -162,6 +162,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
||||
case PIPE_CAP_MAX_VS_PREDS:
|
||||
case PIPE_CAP_MAX_FS_PREDS:
|
||||
return LP_MAX_TGSI_PREDS;
|
||||
case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
|
||||
return 1;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
|
@@ -143,6 +143,7 @@ static void reset_context( struct lp_setup_context *setup )
|
||||
/* Reset some state:
|
||||
*/
|
||||
setup->clear.flags = 0;
|
||||
setup->clear.clearzs.clearzs_mask = 0;
|
||||
|
||||
/* Have an explicit "start-binning" call and get rid of this
|
||||
* pointer twiddling?
|
||||
@@ -172,10 +173,15 @@ static void
|
||||
begin_binning( struct lp_setup_context *setup )
|
||||
{
|
||||
struct lp_scene *scene = lp_setup_get_current_scene(setup);
|
||||
boolean need_zsload = FALSE;
|
||||
if (setup->fb.zsbuf &&
|
||||
((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
|
||||
util_format_is_depth_and_stencil(setup->fb.zsbuf->format))
|
||||
need_zsload = TRUE;
|
||||
|
||||
LP_DBG(DEBUG_SETUP, "%s color: %s depth: %s\n", __FUNCTION__,
|
||||
(setup->clear.flags & PIPE_CLEAR_COLOR) ? "clear": "load",
|
||||
(setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) ? "clear": "load");
|
||||
need_zsload ? "clear": "load");
|
||||
|
||||
if (setup->fb.nr_cbufs) {
|
||||
if (setup->clear.flags & PIPE_CLEAR_COLOR) {
|
||||
@@ -188,10 +194,11 @@ begin_binning( struct lp_setup_context *setup )
|
||||
|
||||
if (setup->fb.zsbuf) {
|
||||
if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) {
|
||||
if (!need_zsload)
|
||||
scene->has_depthstencil_clear = TRUE;
|
||||
lp_scene_bin_everywhere( scene,
|
||||
lp_rast_clear_zstencil,
|
||||
setup->clear.zstencil );
|
||||
scene->has_depth_clear = TRUE;
|
||||
lp_rast_clear_zstencil,
|
||||
lp_rast_arg_clearzs(&setup->clear.clearzs) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,6 +313,8 @@ lp_setup_clear( struct lp_setup_context *setup,
|
||||
{
|
||||
struct lp_scene *scene = lp_setup_get_current_scene(setup);
|
||||
unsigned i;
|
||||
boolean full_zs_clear = TRUE;
|
||||
uint32_t mask = 0;
|
||||
|
||||
LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state);
|
||||
|
||||
@@ -316,10 +325,53 @@ lp_setup_clear( struct lp_setup_context *setup,
|
||||
}
|
||||
|
||||
if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
|
||||
setup->clear.zstencil.clear_zstencil =
|
||||
util_pack_z_stencil(setup->fb.zsbuf->format,
|
||||
depth,
|
||||
stencil);
|
||||
if (setup->fb.zsbuf &&
|
||||
((setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
|
||||
util_format_is_depth_and_stencil(setup->fb.zsbuf->format))
|
||||
full_zs_clear = FALSE;
|
||||
|
||||
if (full_zs_clear) {
|
||||
setup->clear.clearzs.clearzs_value =
|
||||
util_pack_z_stencil(setup->fb.zsbuf->format,
|
||||
depth,
|
||||
stencil);
|
||||
setup->clear.clearzs.clearzs_mask = 0xffffffff;
|
||||
}
|
||||
else {
|
||||
/* hmm */
|
||||
uint32_t tmpval;
|
||||
if (flags & PIPE_CLEAR_DEPTH) {
|
||||
tmpval = util_pack_z(setup->fb.zsbuf->format,
|
||||
depth);
|
||||
switch (setup->fb.zsbuf->format) {
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
|
||||
mask = 0xffffff;
|
||||
break;
|
||||
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
|
||||
mask = 0xffffff00;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (setup->fb.zsbuf->format) {
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
|
||||
mask = 0xff000000;
|
||||
tmpval = stencil << 24;
|
||||
break;
|
||||
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
|
||||
mask = 0xff;
|
||||
tmpval = stencil;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
setup->clear.clearzs.clearzs_mask |= mask;
|
||||
setup->clear.clearzs.clearzs_value =
|
||||
(setup->clear.clearzs.clearzs_value & ~mask) | (tmpval & mask);
|
||||
}
|
||||
}
|
||||
|
||||
if (setup->state == SETUP_ACTIVE) {
|
||||
@@ -336,11 +388,16 @@ lp_setup_clear( struct lp_setup_context *setup,
|
||||
scene->has_color_clear = TRUE;
|
||||
}
|
||||
|
||||
if (setup->clear.flags & PIPE_CLEAR_DEPTHSTENCIL) {
|
||||
if (flags & PIPE_CLEAR_DEPTHSTENCIL) {
|
||||
if (full_zs_clear)
|
||||
scene->has_depthstencil_clear = TRUE;
|
||||
else
|
||||
setup->clear.clearzs.clearzs_mask = mask;
|
||||
lp_scene_bin_everywhere( scene,
|
||||
lp_rast_clear_zstencil,
|
||||
setup->clear.zstencil );
|
||||
scene->has_depth_clear = TRUE;
|
||||
lp_rast_arg_clearzs(&setup->clear.clearzs) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -97,7 +97,7 @@ struct lp_setup_context
|
||||
struct {
|
||||
unsigned flags;
|
||||
union lp_rast_cmd_arg color; /**< lp_rast_clear_color() cmd */
|
||||
union lp_rast_cmd_arg zstencil; /**< lp_rast_clear_zstencil() cmd */
|
||||
struct lp_rast_clearzs clearzs; /**< lp_rast_clear_zstencil() cmd */
|
||||
} clear;
|
||||
|
||||
enum setup_state {
|
||||
|
@@ -153,5 +153,4 @@ void
|
||||
llvmpipe_init_surface_functions(struct llvmpipe_context *lp)
|
||||
{
|
||||
lp->pipe.resource_copy_region = lp_resource_copy;
|
||||
lp->pipe.resource_fill_region = util_resource_fill_region;
|
||||
}
|
||||
|
Reference in New Issue
Block a user