r600g: move fast color clear code to a common place

Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
Marek Olšák 2014-03-06 02:38:57 +01:00
parent d3c1be530a
commit 28eb0bcf19
3 changed files with 88 additions and 84 deletions

View file

@ -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) {

View file

@ -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);

View file

@ -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;