static boolean lp_setup_try_clear_zs(struct lp_setup_context *setup, double depth, unsigned stencil, unsigned flags) { uint64_t zsmask = 0; uint64_t zsvalue = 0; uint32_t zmask32; uint8_t smask8; enum pipe_format format = setup->fb.zsbuf->format; LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state); zmask32 = (flags & PIPE_CLEAR_DEPTH) ? ~0 : 0; smask8 = (flags & PIPE_CLEAR_STENCIL) ? ~0 : 0; zsvalue = util_pack64_z_stencil(format, depth, stencil); zsmask = util_pack64_mask_z_stencil(format, zmask32, smask8); zsvalue &= zsmask; if (format == PIPE_FORMAT_Z24X8_UNORM || format == PIPE_FORMAT_X8Z24_UNORM) { /* * Make full mask if there's "X" bits so we can do full * clear (without rmw). */ uint32_t zsmask_full = 0; zsmask_full = util_pack_mask_z_stencil(format, ~0, ~0); zsmask |= ~zsmask_full; } if (setup->state == SETUP_ACTIVE) { struct lp_scene *scene = setup->scene; /* Add the clear to existing scene. In the unusual case where * both color and depth-stencil are being cleared when there's * already been some rendering, we could discard the currently * binned scene and start again, but I don't see that as being * a common usage. */ if (!lp_scene_bin_everywhere(scene, LP_RAST_OP_CLEAR_ZSTENCIL, lp_rast_arg_clearzs(zsvalue, zsmask))) return FALSE; } else { /* Put ourselves into the 'pre-clear' state, specifically to try * and accumulate multiple clears to color and depth_stencil * buffers which the app or state-tracker might issue * separately. */ set_scene_state( setup, SETUP_CLEARED, __FUNCTION__ ); setup->clear.flags |= flags; setup->clear.zsmask |= zsmask; setup->clear.zsvalue = (setup->clear.zsvalue & ~zsmask) | (zsvalue & zsmask); } return TRUE; }
static boolean lp_setup_try_clear( struct lp_setup_context *setup, const float *color, double depth, unsigned stencil, unsigned flags ) { uint32_t zsmask = 0; uint32_t zsvalue = 0; union lp_rast_cmd_arg color_arg; unsigned i; LP_DBG(DEBUG_SETUP, "%s state %d\n", __FUNCTION__, setup->state); if (flags & PIPE_CLEAR_COLOR) { for (i = 0; i < 4; i++) color_arg.clear_color[i] = float_to_ubyte(color[i]); } if (flags & PIPE_CLEAR_DEPTHSTENCIL) { uint32_t zmask = (flags & PIPE_CLEAR_DEPTH) ? ~0 : 0; uint32_t smask = (flags & PIPE_CLEAR_STENCIL) ? ~0 : 0; zsvalue = util_pack_z_stencil(setup->fb.zsbuf->format, depth, stencil); zsmask = util_pack_mask_z_stencil(setup->fb.zsbuf->format, zmask, smask); zsvalue &= zsmask; } if (setup->state == SETUP_ACTIVE) { struct lp_scene *scene = setup->scene; /* Add the clear to existing scene. In the unusual case where * both color and depth-stencil are being cleared when there's * already been some rendering, we could discard the currently * binned scene and start again, but I don't see that as being * a common usage. */ if (flags & PIPE_CLEAR_COLOR) { if (!lp_scene_bin_everywhere( scene, LP_RAST_OP_CLEAR_COLOR, color_arg )) return FALSE; } if (flags & PIPE_CLEAR_DEPTHSTENCIL) { if (!lp_scene_bin_everywhere( scene, LP_RAST_OP_CLEAR_ZSTENCIL, lp_rast_arg_clearzs(zsvalue, zsmask) )) return FALSE; } } else { /* Put ourselves into the 'pre-clear' state, specifically to try * and accumulate multiple clears to color and depth_stencil * buffers which the app or state-tracker might issue * separately. */ set_scene_state( setup, SETUP_CLEARED, __FUNCTION__ ); setup->clear.flags |= flags; if (flags & PIPE_CLEAR_DEPTHSTENCIL) { setup->clear.zsmask |= zsmask; setup->clear.zsvalue = (setup->clear.zsvalue & ~zsmask) | (zsvalue & zsmask); } if (flags & PIPE_CLEAR_COLOR) { memcpy(setup->clear.color.clear_color, &color_arg, sizeof setup->clear.color.clear_color); } } return TRUE; }