[Mesa-dev] [PATCH 10/18] gallium/u_blitter: use draw_rectangle for all blits except cubemaps
Marek Olšák
maraeo at gmail.com
Thu Aug 17 18:31:31 UTC 2017
From: Marek Olšák <marek.olsak at amd.com>
Add ZW coordinates to the draw_rectangle callback and use it.
---
src/gallium/auxiliary/util/u_blitter.c | 181 ++++++++++++++------------
src/gallium/auxiliary/util/u_blitter.h | 5 +-
src/gallium/drivers/r300/r300_render.c | 7 +-
src/gallium/drivers/radeon/r600_pipe_common.c | 6 +-
4 files changed, 107 insertions(+), 92 deletions(-)
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index de2a27a..d71a238 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -740,124 +740,94 @@ static void blitter_set_clear_color(struct blitter_context_priv *ctx,
for (i = 0; i < 4; i++)
memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4);
} else {
for (i = 0; i < 4; i++)
memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4);
}
}
static void get_texcoords(struct pipe_sampler_view *src,
unsigned src_width0, unsigned src_height0,
- int x1, int y1, int x2, int y2, bool uses_txf,
- union blitter_attrib *out)
+ int x1, int y1, int x2, int y2,
+ float layer, unsigned sample,
+ bool uses_txf, union blitter_attrib *out)
{
unsigned level = src->u.tex.first_level;
boolean normalized = !uses_txf &&
src->target != PIPE_TEXTURE_RECT &&
src->texture->nr_samples <= 1;
if (normalized) {
out->texcoord.x1 = x1 / (float)u_minify(src_width0, level);
out->texcoord.y1 = y1 / (float)u_minify(src_height0, level);
out->texcoord.x2 = x2 / (float)u_minify(src_width0, level);
out->texcoord.y2 = y2 / (float)u_minify(src_height0, level);
} else {
out->texcoord.x1 = x1;
out->texcoord.y1 = y1;
out->texcoord.x2 = x2;
out->texcoord.y2 = y2;
}
-}
-static void set_texcoords_in_vertices(const union blitter_attrib *attrib,
- float *out, unsigned stride)
-{
- out[0] = attrib->texcoord.x1;
- out[1] = attrib->texcoord.y1;
- out += stride;
- out[0] = attrib->texcoord.x2;
- out[1] = attrib->texcoord.y1;
- out += stride;
- out[0] = attrib->texcoord.x2;
- out[1] = attrib->texcoord.y2;
- out += stride;
- out[0] = attrib->texcoord.x1;
- out[1] = attrib->texcoord.y2;
-}
-
-static void blitter_set_texcoords(struct blitter_context_priv *ctx,
- struct pipe_sampler_view *src,
- unsigned src_width0, unsigned src_height0,
- float layer, unsigned sample,
- int x1, int y1, int x2, int y2,
- bool uses_txf)
-{
- unsigned i;
- union blitter_attrib coord;
- float face_coord[4][2];
-
- get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, uses_txf,
- &coord);
-
- if (src->target == PIPE_TEXTURE_CUBE ||
- src->target == PIPE_TEXTURE_CUBE_ARRAY) {
- set_texcoords_in_vertices(&coord, &face_coord[0][0], 2);
- util_map_texcoords2d_onto_cubemap((unsigned)layer % 6,
- /* pointer, stride in floats */
- &face_coord[0][0], 2,
- &ctx->vertices[0][1][0], 8,
- FALSE);
- } else {
- set_texcoords_in_vertices(&coord, &ctx->vertices[0][1][0], 8);
- }
+ out->texcoord.z = 0;
+ out->texcoord.w = 0;
/* Set the layer. */
switch (src->target) {
case PIPE_TEXTURE_3D:
{
float r = layer;
if (!uses_txf)
r /= u_minify(src->texture->depth0, src->u.tex.first_level);
- for (i = 0; i < 4; i++)
- ctx->vertices[i][1][2] = r; /*r*/
+ out->texcoord.z = r;
}
break;
case PIPE_TEXTURE_1D_ARRAY:
- for (i = 0; i < 4; i++)
- ctx->vertices[i][1][1] = (float) layer; /*t*/
+ out->texcoord.y1 = out->texcoord.y2 = layer;
break;
case PIPE_TEXTURE_2D_ARRAY:
- for (i = 0; i < 4; i++) {
- ctx->vertices[i][1][2] = (float) layer; /*r*/
- ctx->vertices[i][1][3] = (float) sample; /*q*/
- }
+ out->texcoord.z = layer;
+ out->texcoord.w = sample;
break;
case PIPE_TEXTURE_CUBE_ARRAY:
- for (i = 0; i < 4; i++)
- ctx->vertices[i][1][3] = (float) ((unsigned)layer / 6); /*w*/
+ out->texcoord.w = (unsigned)layer / 6;
break;
case PIPE_TEXTURE_2D:
- for (i = 0; i < 4; i++) {
- ctx->vertices[i][1][3] = (float) sample; /*r*/
- }
+ out->texcoord.w = sample;
break;
default:;
}
}
+static void set_texcoords_in_vertices(const union blitter_attrib *attrib,
+ float *out, unsigned stride)
+{
+ out[0] = attrib->texcoord.x1;
+ out[1] = attrib->texcoord.y1;
+ out += stride;
+ out[0] = attrib->texcoord.x2;
+ out[1] = attrib->texcoord.y1;
+ out += stride;
+ out[0] = attrib->texcoord.x2;
+ out[1] = attrib->texcoord.y2;
+ out += stride;
+ out[0] = attrib->texcoord.x1;
+ out[1] = attrib->texcoord.y2;
+}
+
static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
enum pipe_format src_format,
enum pipe_format dst_format,
enum pipe_texture_target target,
unsigned src_nr_samples,
unsigned dst_nr_samples,
unsigned filter,
bool use_txf)
{
struct pipe_context *pipe = ctx->base.pipe;
@@ -1252,27 +1222,34 @@ static void blitter_draw(struct blitter_context_priv *ctx,
pipe_resource_reference(&vb.buffer.resource, NULL);
}
void util_blitter_draw_rectangle(struct blitter_context *blitter,
int x1, int y1, int x2, int y2,
float depth, unsigned num_instances,
enum blitter_attrib_type type,
const union blitter_attrib *attrib)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ unsigned i;
switch (type) {
case UTIL_BLITTER_ATTRIB_COLOR:
blitter_set_clear_color(ctx, (uint32_t*)attrib->color);
break;
- case UTIL_BLITTER_ATTRIB_TEXCOORD:
+ case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
+ for (i = 0; i < 4; i++) {
+ ctx->vertices[i][1][2] = attrib->texcoord.z;
+ ctx->vertices[i][1][3] = attrib->texcoord.w;
+ }
+ /* fall through */
+ case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8);
break;
default:;
}
blitter_draw(ctx, x1, y1, x2, y2, depth, num_instances);
}
static void *get_clear_blend_state(struct blitter_context_priv *ctx,
@@ -1573,20 +1550,56 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
/* Copy. */
util_blitter_blit_generic(blitter, dst_view, &dstbox,
src_view, srcbox, src->width0, src->height0,
PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
FALSE);
pipe_surface_reference(&dst_view, NULL);
pipe_sampler_view_reference(&src_view, NULL);
}
+static void
+blitter_draw_tex(struct blitter_context_priv *ctx,
+ int dst_x1, int dst_y1, int dst_x2, int dst_y2,
+ struct pipe_sampler_view *src,
+ unsigned src_width0, unsigned src_height0,
+ int src_x1, int src_y1, int src_x2, int src_y2,
+ float layer, unsigned sample,
+ bool uses_txf, enum blitter_attrib_type type)
+{
+ union blitter_attrib coord;
+
+ get_texcoords(src, src_width0, src_height0,
+ src_x1, src_y1, src_x2, src_y2, layer, sample,
+ uses_txf, &coord);
+
+ if (src->target == PIPE_TEXTURE_CUBE ||
+ src->target == PIPE_TEXTURE_CUBE_ARRAY) {
+ float face_coord[4][2];
+
+ set_texcoords_in_vertices(&coord, &face_coord[0][0], 2);
+ util_map_texcoords2d_onto_cubemap((unsigned)layer % 6,
+ /* pointer, stride in floats */
+ &face_coord[0][0], 2,
+ &ctx->vertices[0][1][0], 8,
+ FALSE);
+ for (unsigned i = 0; i < 4; i++)
+ ctx->vertices[i][1][3] = coord.texcoord.w;
+
+ /* Cubemaps don't use draw_rectangle. */
+ blitter_draw(ctx, dst_x1, dst_y1, dst_x2, dst_y2, 0, 1);
+ } else {
+ ctx->base.draw_rectangle(&ctx->base, dst_x1, dst_y1, dst_x2, dst_y2, 0,
+ 1, type, &coord);
+ }
+}
+
static void do_blits(struct blitter_context_priv *ctx,
struct pipe_surface *dst,
const struct pipe_box *dstbox,
struct pipe_sampler_view *src,
unsigned src_width0,
unsigned src_height0,
const struct pipe_box *srcbox,
bool is_zsbuf,
bool uses_txf)
{
@@ -1598,42 +1611,36 @@ static void do_blits(struct blitter_context_priv *ctx,
/* Initialize framebuffer state. */
fb_state.width = dst->width;
fb_state.height = dst->height;
fb_state.nr_cbufs = is_zsbuf ? 0 : 1;
if ((src_target == PIPE_TEXTURE_1D ||
src_target == PIPE_TEXTURE_2D ||
src_target == PIPE_TEXTURE_RECT) &&
src_samples <= 1) {
- /* Draw the quad with the draw_rectangle callback. */
-
- /* Set texture coordinates. */
- union blitter_attrib coord;
- get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y,
- srcbox->x+srcbox->width, srcbox->y+srcbox->height,
- uses_txf, &coord);
-
/* Set framebuffer state. */
if (is_zsbuf) {
fb_state.zsbuf = dst;
} else {
fb_state.cbufs[0] = dst;
}
pipe->set_framebuffer_state(pipe, &fb_state);
/* Draw. */
pipe->set_sample_mask(pipe, ~0);
- ctx->base.draw_rectangle(&ctx->base, dstbox->x, dstbox->y,
- dstbox->x + dstbox->width,
- dstbox->y + dstbox->height, 0, 1,
- UTIL_BLITTER_ATTRIB_TEXCOORD, &coord);
+ blitter_draw_tex(ctx, dstbox->x, dstbox->y,
+ dstbox->x + dstbox->width,
+ dstbox->y + dstbox->height,
+ src, src_width0, src_height0, srcbox->x, srcbox->y,
+ srcbox->x + srcbox->width, srcbox->y + srcbox->height,
+ 0, 0, uses_txf, UTIL_BLITTER_ATTRIB_TEXCOORD_XY);
} else {
/* Draw the quad with the generic codepath. */
int dst_z;
for (dst_z = 0; dst_z < dstbox->depth; dst_z++) {
struct pipe_surface *old;
float dst2src_scale = srcbox->depth / (float)dstbox->depth;
/* Scale Z properly if the blit is scaled.
*
* When downscaling, we want the coordinates centered, so that
@@ -1663,40 +1670,42 @@ static void do_blits(struct blitter_context_priv *ctx,
}
pipe->set_framebuffer_state(pipe, &fb_state);
/* See if we need to blit a multisample or singlesample buffer. */
if (src_samples == dst_samples && dst_samples > 1) {
/* MSAA copy. */
unsigned i, max_sample = dst_samples - 1;
for (i = 0; i <= max_sample; i++) {
pipe->set_sample_mask(pipe, 1 << i);
- blitter_set_texcoords(ctx, src, src_width0, src_height0,
- srcbox->z + src_z,
- i, srcbox->x, srcbox->y,
- srcbox->x + srcbox->width,
- srcbox->y + srcbox->height, uses_txf);
- blitter_draw(ctx, dstbox->x, dstbox->y,
- dstbox->x + dstbox->width,
- dstbox->y + dstbox->height, 0, 1);
+ blitter_draw_tex(ctx, dstbox->x, dstbox->y,
+ dstbox->x + dstbox->width,
+ dstbox->y + dstbox->height,
+ src, src_width0, src_height0,
+ srcbox->x, srcbox->y,
+ srcbox->x + srcbox->width,
+ srcbox->y + srcbox->height,
+ srcbox->z + src_z, i, uses_txf,
+ UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
}
} else {
/* Normal copy, MSAA upsampling, or MSAA resolve. */
pipe->set_sample_mask(pipe, ~0);
- blitter_set_texcoords(ctx, src, src_width0, src_height0,
- srcbox->z + src_z, 0,
- srcbox->x, srcbox->y,
- srcbox->x + srcbox->width,
- srcbox->y + srcbox->height, uses_txf);
- blitter_draw(ctx, dstbox->x, dstbox->y,
- dstbox->x + dstbox->width,
- dstbox->y + dstbox->height, 0, 1);
+ blitter_draw_tex(ctx, dstbox->x, dstbox->y,
+ dstbox->x + dstbox->width,
+ dstbox->y + dstbox->height,
+ src, src_width0, src_height0,
+ srcbox->x, srcbox->y,
+ srcbox->x + srcbox->width,
+ srcbox->y + srcbox->height,
+ srcbox->z + src_z, 0, uses_txf,
+ UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
}
/* Get the next surface or (if this is the last iteration)
* just unreference the last one. */
old = dst;
if (dst_z < dstbox->depth-1) {
dst = util_blitter_get_next_surface_layer(ctx->base.pipe, dst);
}
if (dst_z) {
pipe_surface_reference(&old, NULL);
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index 304d27e..3d1f285 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -34,28 +34,29 @@
#ifdef __cplusplus
extern "C" {
#endif
struct pipe_context;
enum blitter_attrib_type {
UTIL_BLITTER_ATTRIB_NONE,
UTIL_BLITTER_ATTRIB_COLOR,
- UTIL_BLITTER_ATTRIB_TEXCOORD
+ UTIL_BLITTER_ATTRIB_TEXCOORD_XY,
+ UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW,
};
union blitter_attrib {
float color[4];
struct {
- float x1, y1, x2, y2;
+ float x1, y1, x2, y2, z, w;
} texcoord;
};
struct blitter_context
{
/**
* Draw a rectangle.
*
* \param x1 An X coordinate of the top-left corner.
* \param y1 A Y coordinate of the top-left corner.
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 1f896da..ddd2452 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -1118,54 +1118,55 @@ void r300_blitter_draw_rectangle(struct blitter_context *blitter,
enum blitter_attrib_type type,
const union blitter_attrib *attrib)
{
struct r300_context *r300 = r300_context(util_blitter_get_pipe(blitter));
unsigned last_sprite_coord_enable = r300->sprite_coord_enable;
unsigned width = x2 - x1;
unsigned height = y2 - y1;
unsigned vertex_size =
type == UTIL_BLITTER_ATTRIB_COLOR || !r300->draw ? 8 : 4;
unsigned dwords = 13 + vertex_size +
- (type == UTIL_BLITTER_ATTRIB_TEXCOORD ? 7 : 0);
+ (type == UTIL_BLITTER_ATTRIB_TEXCOORD_XY ? 7 : 0);
static const union blitter_attrib zeros;
CS_LOCALS(r300);
/* XXX workaround for a lockup in MSAA resolve on SWTCL chipsets, this
* function most probably doesn't handle type=NONE correctly */
if ((!r300->screen->caps.has_tcl && type == UTIL_BLITTER_ATTRIB_NONE) ||
+ type == UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW ||
num_instances > 1) {
util_blitter_draw_rectangle(blitter, x1, y1, x2, y2, depth,
num_instances, type, attrib);
return;
}
if (r300->skip_rendering)
return;
- if (type == UTIL_BLITTER_ATTRIB_TEXCOORD)
+ if (type == UTIL_BLITTER_ATTRIB_TEXCOORD_XY)
r300->sprite_coord_enable = 1;
r300_update_derived_state(r300);
/* Mark some states we don't care about as non-dirty. */
r300->viewport_state.dirty = FALSE;
if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1))
goto done;
DBG(r300, DBG_DRAW, "r300: draw_rectangle\n");
BEGIN_CS(dwords);
/* Set up GA. */
OUT_CS_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16));
- if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) {
+ if (type == UTIL_BLITTER_ATTRIB_TEXCOORD_XY) {
/* Set up the GA to generate texcoords. */
OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
(R300_GB_TEX_STR << R300_GB_TEX0_SOURCE_SHIFT));
OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4);
OUT_CS_32F(attrib->texcoord.x1);
OUT_CS_32F(attrib->texcoord.y2);
OUT_CS_32F(attrib->texcoord.x2);
OUT_CS_32F(attrib->texcoord.y1);
}
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
index 90127dc..af4b4e8 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -256,21 +256,25 @@ void r600_draw_rectangle(struct blitter_context *blitter,
vb[17] = -1;
vb[18] = 0;
vb[19] = 1;
switch (type) {
case UTIL_BLITTER_ATTRIB_COLOR:
memcpy(vb+4, attrib->color, sizeof(float)*4);
memcpy(vb+12, attrib->color, sizeof(float)*4);
memcpy(vb+20, attrib->color, sizeof(float)*4);
break;
- case UTIL_BLITTER_ATTRIB_TEXCOORD:
+ case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
+ vb[6] = vb[14] = vb[22] = attrib->texcoord.z;
+ vb[7] = vb[15] = vb[23] = attrib->texcoord.w;
+ /* fall through */
+ case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
vb[4] = attrib->texcoord.x1;
vb[5] = attrib->texcoord.y1;
vb[12] = attrib->texcoord.x1;
vb[13] = attrib->texcoord.y2;
vb[20] = attrib->texcoord.x2;
vb[21] = attrib->texcoord.y1;
break;
default:; /* Nothing to do. */
}
--
2.7.4
More information about the mesa-dev
mailing list