mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 22:30:11 +01:00
r600g: move fast color clear code to a common place
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
parent
d3c1be530a
commit
28eb0bcf19
3 changed files with 88 additions and 84 deletions
|
|
@ -386,85 +386,6 @@ static bool r600_decompress_subresource(struct pipe_context *ctx,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst,
|
||||
unsigned offset, unsigned size, unsigned value);
|
||||
|
||||
static void evergreen_set_clear_color(struct pipe_surface *cbuf,
|
||||
const union pipe_color_union *color)
|
||||
{
|
||||
unsigned *clear_value = ((struct r600_texture *)cbuf->texture)->color_clear_value;
|
||||
union util_color uc;
|
||||
|
||||
memset(&uc, 0, sizeof(uc));
|
||||
|
||||
if (util_format_is_pure_uint(cbuf->format)) {
|
||||
util_format_write_4ui(cbuf->format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
|
||||
} else if (util_format_is_pure_sint(cbuf->format)) {
|
||||
util_format_write_4i(cbuf->format, color->i, 0, &uc, 0, 0, 0, 1, 1);
|
||||
} else {
|
||||
util_pack_color(color->f, cbuf->format, &uc);
|
||||
}
|
||||
|
||||
memcpy(clear_value, &uc, 2 * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static void r600_try_fast_color_clear(struct r600_context *rctx, unsigned *buffers,
|
||||
const union pipe_color_union *color)
|
||||
{
|
||||
struct pipe_framebuffer_state *fb = &rctx->framebuffer.state;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fb->nr_cbufs; i++) {
|
||||
struct r600_texture *tex;
|
||||
unsigned clear_bit = PIPE_CLEAR_COLOR0 << i;
|
||||
|
||||
if (!fb->cbufs[i])
|
||||
continue;
|
||||
|
||||
/* if this colorbuffer is not being cleared */
|
||||
if (!(*buffers & clear_bit))
|
||||
continue;
|
||||
|
||||
tex = (struct r600_texture *)fb->cbufs[i]->texture;
|
||||
|
||||
/* 128-bit formats are unusupported */
|
||||
if (util_format_get_blocksizebits(fb->cbufs[i]->format) > 64) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* the clear is allowed if all layers are bound */
|
||||
if (fb->cbufs[i]->u.tex.first_layer != 0 ||
|
||||
fb->cbufs[i]->u.tex.last_layer != util_max_layer(&tex->resource.b.b, 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* cannot clear mipmapped textures */
|
||||
if (fb->cbufs[i]->texture->last_level != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only supported on tiled surfaces */
|
||||
if (tex->surface.level[0].mode < RADEON_SURF_MODE_1D) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ensure CMASK is enabled */
|
||||
r600_texture_alloc_cmask_separate(&rctx->screen->b, tex);
|
||||
if (tex->cmask.size == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Do the fast clear. */
|
||||
evergreen_set_clear_color(fb->cbufs[i], color);
|
||||
r600_clear_buffer(&rctx->b.b, &tex->cmask_buffer->b.b,
|
||||
tex->cmask.offset, tex->cmask.size, 0);
|
||||
|
||||
tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
|
||||
rctx->framebuffer.atom.dirty = true;
|
||||
*buffers &= ~clear_bit;
|
||||
}
|
||||
}
|
||||
|
||||
static void r600_clear(struct pipe_context *ctx, unsigned buffers,
|
||||
const union pipe_color_union *color,
|
||||
double depth, unsigned stencil)
|
||||
|
|
@ -473,7 +394,8 @@ static void r600_clear(struct pipe_context *ctx, unsigned buffers,
|
|||
struct pipe_framebuffer_state *fb = &rctx->framebuffer.state;
|
||||
|
||||
if (buffers & PIPE_CLEAR_COLOR && rctx->b.chip_class >= EVERGREEN) {
|
||||
r600_try_fast_color_clear(rctx, &buffers, color);
|
||||
evergreen_do_fast_color_clear(&rctx->b, fb, &rctx->framebuffer.atom,
|
||||
&buffers, color);
|
||||
}
|
||||
|
||||
if (buffers & PIPE_CLEAR_COLOR) {
|
||||
|
|
|
|||
|
|
@ -426,8 +426,6 @@ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen,
|
|||
void r600_texture_get_cmask_info(struct r600_common_screen *rscreen,
|
||||
struct r600_texture *rtex,
|
||||
struct r600_cmask_info *out);
|
||||
void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen,
|
||||
struct r600_texture *rtex);
|
||||
bool r600_init_flushed_depth_texture(struct pipe_context *ctx,
|
||||
struct pipe_resource *texture,
|
||||
struct r600_texture **staging);
|
||||
|
|
@ -438,6 +436,11 @@ struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
|
|||
const struct pipe_surface *templ,
|
||||
unsigned width, unsigned height);
|
||||
unsigned r600_translate_colorswap(enum pipe_format format);
|
||||
void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
|
||||
struct pipe_framebuffer_state *fb,
|
||||
struct r600_atom *fb_state,
|
||||
unsigned *buffers,
|
||||
const union pipe_color_union *color);
|
||||
void r600_init_screen_texture_functions(struct r600_common_screen *rscreen);
|
||||
void r600_init_context_texture_functions(struct r600_common_context *rctx);
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "r600_cs.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_pack_color.h"
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
|
|
@ -449,8 +450,8 @@ static void r600_texture_allocate_cmask(struct r600_common_screen *rscreen,
|
|||
rtex->cb_color_info |= EG_S_028C70_FAST_CLEAR(1);
|
||||
}
|
||||
|
||||
void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen,
|
||||
struct r600_texture *rtex)
|
||||
static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen,
|
||||
struct r600_texture *rtex)
|
||||
{
|
||||
if (rtex->cmask_buffer)
|
||||
return;
|
||||
|
|
@ -1197,6 +1198,84 @@ unsigned r600_translate_colorswap(enum pipe_format format)
|
|||
return ~0U;
|
||||
}
|
||||
|
||||
static void evergreen_set_clear_color(struct r600_texture *rtex,
|
||||
enum pipe_format surface_format,
|
||||
const union pipe_color_union *color)
|
||||
{
|
||||
union util_color uc;
|
||||
|
||||
memset(&uc, 0, sizeof(uc));
|
||||
|
||||
if (util_format_is_pure_uint(surface_format)) {
|
||||
util_format_write_4ui(surface_format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
|
||||
} else if (util_format_is_pure_sint(surface_format)) {
|
||||
util_format_write_4i(surface_format, color->i, 0, &uc, 0, 0, 0, 1, 1);
|
||||
} else {
|
||||
util_pack_color(color->f, surface_format, &uc);
|
||||
}
|
||||
|
||||
memcpy(rtex->color_clear_value, &uc, 2 * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
|
||||
struct pipe_framebuffer_state *fb,
|
||||
struct r600_atom *fb_state,
|
||||
unsigned *buffers,
|
||||
const union pipe_color_union *color)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < fb->nr_cbufs; i++) {
|
||||
struct r600_texture *tex;
|
||||
unsigned clear_bit = PIPE_CLEAR_COLOR0 << i;
|
||||
|
||||
if (!fb->cbufs[i])
|
||||
continue;
|
||||
|
||||
/* if this colorbuffer is not being cleared */
|
||||
if (!(*buffers & clear_bit))
|
||||
continue;
|
||||
|
||||
tex = (struct r600_texture *)fb->cbufs[i]->texture;
|
||||
|
||||
/* 128-bit formats are unusupported */
|
||||
if (util_format_get_blocksizebits(fb->cbufs[i]->format) > 64) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* the clear is allowed if all layers are bound */
|
||||
if (fb->cbufs[i]->u.tex.first_layer != 0 ||
|
||||
fb->cbufs[i]->u.tex.last_layer != util_max_layer(&tex->resource.b.b, 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* cannot clear mipmapped textures */
|
||||
if (fb->cbufs[i]->texture->last_level != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only supported on tiled surfaces */
|
||||
if (tex->surface.level[0].mode < RADEON_SURF_MODE_1D) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* ensure CMASK is enabled */
|
||||
r600_texture_alloc_cmask_separate(rctx->screen, tex);
|
||||
if (tex->cmask.size == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Do the fast clear. */
|
||||
evergreen_set_clear_color(tex, fb->cbufs[i]->format, color);
|
||||
rctx->clear_buffer(&rctx->b, &tex->cmask_buffer->b.b,
|
||||
tex->cmask.offset, tex->cmask.size, 0);
|
||||
|
||||
tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
|
||||
fb_state->dirty = true;
|
||||
*buffers &= ~clear_bit;
|
||||
}
|
||||
}
|
||||
|
||||
void r600_init_screen_texture_functions(struct r600_common_screen *rscreen)
|
||||
{
|
||||
rscreen->b.resource_from_handle = r600_texture_from_handle;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue