From: Marek Olšák <marek.ol...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev