summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/r600/r600_blit.c82
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.h7
-rw-r--r--src/gallium/drivers/radeon/r600_texture.c83
3 files changed, 88 insertions, 84 deletions
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index e0f3373ce05..98c07b5afdb 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -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) {
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 5808ec30b6a..f858b8c9345 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -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);
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 011efb0442b..0ff43e7bae4 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -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;