gallium/u_blitter: add gallium blit implementation

The original blit function is extended and the otAher functions reuse it.

Tested-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Marek Olšák 2012-09-12 23:37:17 +02:00
parent 84d2f2295e
commit 0b0697e80d
10 changed files with 255 additions and 153 deletions

View File

@ -27,7 +27,7 @@
/**
* @file
* Blitter utility to facilitate acceleration of the clear, clear_render_target,
* clear_depth_stencil, and resource_copy_region functions.
* clear_depth_stencil, resource_copy_region, and blit functions.
*
* @author Marek Olšák
*/
@ -88,8 +88,7 @@ struct blitter_context_priv
void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES];
/* Blend state. */
void *blend_write_color; /**< blend state with writemask of RGBA */
void *blend_keep_color; /**< blend state with writemask of 0 */
void *blend[PIPE_MASK_RGBA+1]; /**< blend state with writemask */
/* Depth stencil alpha state. */
void *dsa_write_depth_stencil;
@ -104,11 +103,10 @@ struct blitter_context_priv
void *velem_state_readbuf;
/* Sampler state. */
void *sampler_state;
void *sampler_state, *sampler_state_linear;
/* Rasterizer state. */
void *rs_state;
void *rs_discard_state;
void *rs_state, *rs_state_scissor, *rs_discard_state;
/* Viewport state. */
struct pipe_viewport_state viewport;
@ -182,10 +180,11 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
/* blend state objects */
memset(&blend, 0, sizeof(blend));
ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend);
blend.rt[0].colormask = PIPE_MASK_RGBA;
ctx->blend_write_color = pipe->create_blend_state(pipe, &blend);
for (i = 0; i <= PIPE_MASK_RGBA; i++) {
blend.rt[0].colormask = i;
ctx->blend[i] = pipe->create_blend_state(pipe, &blend);
}
/* depth stencil alpha state objects */
memset(&dsa, 0, sizeof(dsa));
@ -221,6 +220,10 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
sampler_state.normalized_coords = 1;
ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state);
sampler_state.min_img_filter = PIPE_TEX_FILTER_LINEAR;
sampler_state.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
ctx->sampler_state_linear = pipe->create_sampler_state(pipe, &sampler_state);
/* rasterizer state */
memset(&rs_state, 0, sizeof(rs_state));
rs_state.cull_face = PIPE_FACE_NONE;
@ -229,7 +232,11 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
rs_state.depth_clip = 1;
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
rs_state.scissor = 1;
ctx->rs_state_scissor = pipe->create_rasterizer_state(pipe, &rs_state);
if (ctx->has_stream_out) {
rs_state.scissor = 0;
rs_state.rasterizer_discard = 1;
ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state);
}
@ -304,8 +311,9 @@ void util_blitter_destroy(struct blitter_context *blitter)
struct pipe_context *pipe = blitter->pipe;
int i;
pipe->delete_blend_state(pipe, ctx->blend_write_color);
pipe->delete_blend_state(pipe, ctx->blend_keep_color);
for (i = 0; i <= PIPE_MASK_RGBA; i++) {
pipe->delete_blend_state(pipe, ctx->blend[i]);
}
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->delete_depth_stencil_alpha_state(pipe,
ctx->dsa_write_depth_keep_stencil);
@ -313,6 +321,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
pipe->delete_rasterizer_state(pipe, ctx->rs_state_scissor);
if (ctx->rs_discard_state)
pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state);
pipe->delete_vs_state(pipe, ctx->vs);
@ -345,6 +354,7 @@ void util_blitter_destroy(struct blitter_context *blitter)
}
pipe->delete_sampler_state(pipe, ctx->sampler_state);
pipe->delete_sampler_state(pipe, ctx->sampler_state_linear);
u_upload_destroy(ctx->upload);
FREE(ctx);
}
@ -524,8 +534,7 @@ static void blitter_restore_textures(struct blitter_context_priv *ctx)
}
static void blitter_set_rectangle(struct blitter_context_priv *ctx,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
int x1, int y1, int x2, int y2,
float depth)
{
int i;
@ -583,8 +592,7 @@ static void blitter_set_clear_color(struct blitter_context_priv *ctx,
static void get_texcoords(struct pipe_sampler_view *src,
unsigned src_width0, unsigned src_height0,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
int x1, int y1, int x2, int y2,
float out[4])
{
struct pipe_resource *tex = src->texture;
@ -625,8 +633,7 @@ static void blitter_set_texcoords(struct blitter_context_priv *ctx,
struct pipe_sampler_view *src,
unsigned src_width0, unsigned src_height0,
unsigned layer, unsigned sample,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2)
int x1, int y1, int x2, int y2)
{
unsigned i;
float coord[4];
@ -895,11 +902,13 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter)
}
}
static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx)
static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx,
boolean scissor)
{
struct pipe_context *pipe = ctx->base.pipe;
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_rasterizer_state(pipe, scissor ? ctx->rs_state_scissor
: ctx->rs_state);
pipe->bind_vs_state(pipe, ctx->vs);
if (ctx->has_geometry_shader)
pipe->bind_gs_state(pipe, NULL);
@ -908,9 +917,7 @@ static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx)
}
static void blitter_draw(struct blitter_context_priv *ctx,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
float depth)
int x1, int y1, int x2, int y2, float depth)
{
struct pipe_resource *buf = NULL;
unsigned offset = 0;
@ -926,9 +933,7 @@ static void blitter_draw(struct blitter_context_priv *ctx,
}
void util_blitter_draw_rectangle(struct blitter_context *blitter,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
float depth,
int x1, int y1, int x2, int y2, float depth,
enum blitter_attrib_type type,
const union pipe_color_union *attrib)
{
@ -973,9 +978,9 @@ static void util_blitter_clear_custom(struct blitter_context *blitter,
if (custom_blend) {
pipe->bind_blend_state(pipe, custom_blend);
} else if (clear_buffers & PIPE_CLEAR_COLOR) {
pipe->bind_blend_state(pipe, ctx->blend_write_color);
pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]);
} else {
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
pipe->bind_blend_state(pipe, ctx->blend[0]);
}
if (custom_dsa) {
@ -1003,7 +1008,7 @@ static void util_blitter_clear_custom(struct blitter_context *blitter,
ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs, int_format));
pipe->set_sample_mask(pipe, ~0);
blitter_set_common_draw_rect_state(ctx);
blitter_set_common_draw_rect_state(ctx, FALSE);
blitter_set_dst_dimensions(ctx, width, height);
blitter->draw_rectangle(blitter, 0, 0, width, height, depth,
UTIL_BLITTER_ATTRIB_COLOR, color);
@ -1037,7 +1042,7 @@ void util_blitter_custom_clear_depth(struct blitter_context *blitter,
}
static
boolean is_overlap(unsigned dstx, unsigned dsty, unsigned dstz,
boolean is_overlap(int dstx, int dsty, int dstz,
const struct pipe_box *srcbox)
{
struct pipe_box src = *srcbox;
@ -1096,10 +1101,12 @@ void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ,
src_templ->swizzle_a = PIPE_SWIZZLE_ALPHA;
}
boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
const struct pipe_resource *dst,
const struct pipe_resource *src,
unsigned mask)
static boolean is_blit_generic_supported(struct blitter_context *blitter,
const struct pipe_resource *dst,
enum pipe_format dst_format,
const struct pipe_resource *src,
enum pipe_format src_format,
unsigned mask)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_screen *screen = ctx->base.pipe->screen;
@ -1108,7 +1115,7 @@ boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
unsigned bind;
boolean is_stencil;
const struct util_format_description *desc =
util_format_description(dst->format);
util_format_description(dst_format);
is_stencil = util_format_has_stencil(desc);
@ -1122,7 +1129,7 @@ boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
else
bind = PIPE_BIND_RENDER_TARGET;
if (!screen->is_format_supported(screen, dst->format, dst->target,
if (!screen->is_format_supported(screen, dst_format, dst->target,
dst->nr_samples, bind)) {
return FALSE;
}
@ -1133,18 +1140,18 @@ boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
return FALSE;
}
if (!screen->is_format_supported(screen, src->format, src->target,
if (!screen->is_format_supported(screen, src_format, src->target,
src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
return FALSE;
}
/* Check stencil sampler support for stencil copy. */
if (util_format_has_stencil(util_format_description(src->format))) {
if (util_format_has_stencil(util_format_description(src_format))) {
enum pipe_format stencil_format =
util_format_stencil_only(src->format);
util_format_stencil_only(src_format);
assert(stencil_format != PIPE_FORMAT_NONE);
if (stencil_format != src->format &&
if (stencil_format != src_format &&
!screen->is_format_supported(screen, stencil_format, src->target,
src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
return FALSE;
@ -1155,13 +1162,32 @@ boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
return TRUE;
}
boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
const struct pipe_resource *dst,
const struct pipe_resource *src,
unsigned mask)
{
return is_blit_generic_supported(blitter, dst, dst->format,
src, src->format, mask);
}
boolean util_blitter_is_blit_supported(struct blitter_context *blitter,
const struct pipe_blit_info *info)
{
return is_blit_generic_supported(blitter,
info->dst.resource, info->dst.format,
info->src.resource, info->src.format,
info->mask);
}
void util_blitter_copy_texture(struct blitter_context *blitter,
struct pipe_resource *dst,
unsigned dst_level, unsigned dst_sample_mask,
unsigned dst_level,
unsigned dstx, unsigned dsty, unsigned dstz,
struct pipe_resource *src,
unsigned src_level, unsigned src_sample,
const struct pipe_box *srcbox)
unsigned src_level,
const struct pipe_box *srcbox, unsigned mask,
boolean copy_all_samples)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
@ -1180,44 +1206,53 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
src_view = pipe->create_sampler_view(pipe, src, &src_templ);
/* Copy. */
util_blitter_copy_texture_view(blitter, dst_view, dst_sample_mask, dstx,
dsty, src_view, src_sample, srcbox,
src->width0, src->height0, PIPE_MASK_RGBAZS);
util_blitter_blit_generic(blitter, dst_view, dstx, dsty,
abs(srcbox->width), abs(srcbox->height),
src_view, srcbox, src->width0, src->height0,
mask, PIPE_TEX_FILTER_NEAREST, NULL,
copy_all_samples);
pipe_surface_reference(&dst_view, NULL);
pipe_sampler_view_reference(&src_view, NULL);
}
void util_blitter_copy_texture_view(struct blitter_context *blitter,
struct pipe_surface *dst,
unsigned dst_sample_mask,
unsigned dstx, unsigned dsty,
struct pipe_sampler_view *src,
unsigned src_sample,
const struct pipe_box *srcbox,
unsigned src_width0, unsigned src_height0,
unsigned mask)
void util_blitter_blit_generic(struct blitter_context *blitter,
struct pipe_surface *dst,
int dstx, int dsty,
unsigned dst_width, unsigned dst_height,
struct pipe_sampler_view *src,
const struct pipe_box *srcbox,
unsigned src_width0, unsigned src_height0,
unsigned mask, unsigned filter,
const struct pipe_scissor_state *scissor,
boolean copy_all_samples)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
struct pipe_framebuffer_state fb_state;
enum pipe_texture_target src_target = src->texture->target;
int abs_width = abs(srcbox->width);
int abs_height = abs(srcbox->height);
boolean blit_stencil, blit_depth;
boolean has_depth, has_stencil, has_color;
boolean blit_stencil, blit_depth, blit_color;
void *sampler_state;
const struct util_format_description *src_desc =
util_format_description(src->format);
const struct util_format_description *dst_desc =
util_format_description(dst->format);
blit_depth = util_format_has_depth(src_desc) && (mask & PIPE_MASK_Z);
blit_stencil = util_format_has_stencil(src_desc) && (mask & PIPE_MASK_S);
has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
has_depth = util_format_has_depth(src_desc) &&
util_format_has_depth(dst_desc);
has_stencil = util_format_has_stencil(src_desc) &&
util_format_has_stencil(dst_desc);
/* If you want a fallback for stencil copies,
* use util_blitter_copy_texture. */
if (blit_stencil && !ctx->has_stencil_export) {
blit_stencil = FALSE;
blit_color = has_color && (mask & PIPE_MASK_RGBA);
blit_depth = has_depth && (mask & PIPE_MASK_Z);
blit_stencil = has_stencil && (mask & PIPE_MASK_S) &&
ctx->has_stencil_export;
if (!blit_depth)
return;
if (!blit_stencil && !blit_depth && !blit_color) {
return;
}
/* Sanity checks. */
@ -1241,7 +1276,7 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter,
fb_state.height = dst->height;
if (blit_depth || blit_stencil) {
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
pipe->bind_blend_state(pipe, ctx->blend[0]);
if (blit_depth && blit_stencil) {
pipe->bind_depth_stencil_alpha_state(pipe,
@ -1266,7 +1301,7 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter,
fb_state.nr_cbufs = 0;
fb_state.zsbuf = dst;
} else {
pipe->bind_blend_state(pipe, ctx->blend_write_color);
pipe->bind_blend_state(pipe, ctx->blend[mask & PIPE_MASK_RGBA]);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
ctx->bind_fs_state(pipe,
blitter_get_fs_texfetch_col(ctx, src->texture->target,
@ -1277,11 +1312,22 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter,
fb_state.zsbuf = 0;
}
/* Set the linear filter only for scaled color non-MSAA blits. */
if (filter == PIPE_TEX_FILTER_LINEAR &&
!blit_depth && !blit_stencil &&
src->texture->nr_samples <= 1 &&
(dst_width != abs(srcbox->width) || dst_height != abs(srcbox->height))) {
sampler_state = ctx->sampler_state_linear;
} else {
sampler_state = ctx->sampler_state;
}
/* Set samplers. */
if (blit_depth && blit_stencil) {
/* Setup two samplers, one for depth and the other one for stencil. */
struct pipe_sampler_view templ;
struct pipe_sampler_view *views[2];
void *samplers[2] = {ctx->sampler_state, ctx->sampler_state};
void *samplers[2] = {sampler_state, sampler_state};
templ = *src;
templ.format = util_format_stencil_only(templ.format);
@ -1306,19 +1352,22 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter,
view = pipe->create_sampler_view(pipe, src->texture, &templ);
pipe->set_fragment_sampler_views(pipe, 1, &view);
pipe->bind_fragment_sampler_states(pipe, 1, &ctx->sampler_state);
pipe->bind_fragment_sampler_states(pipe, 1, &sampler_state);
pipe_sampler_view_reference(&view, NULL);
} else {
pipe->set_fragment_sampler_views(pipe, 1, &src);
pipe->bind_fragment_sampler_states(pipe, 1, &ctx->sampler_state);
pipe->bind_fragment_sampler_states(pipe, 1, &sampler_state);
}
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, dst_sample_mask);
blitter_set_common_draw_rect_state(ctx);
if (scissor) {
pipe->set_scissor_state(pipe, scissor);
}
blitter_set_common_draw_rect_state(ctx, scissor != NULL);
blitter_set_dst_dimensions(ctx, dst->width, dst->height);
if ((src_target == PIPE_TEXTURE_1D ||
@ -1337,25 +1386,82 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter,
srcbox->x+srcbox->width, srcbox->y+srcbox->height, coord.f);
/* Draw. */
blitter->draw_rectangle(blitter, dstx, dsty, dstx+abs_width, dsty+abs_height, 0,
pipe->set_sample_mask(pipe, ~0);
blitter->draw_rectangle(blitter, dstx, dsty,
dstx+dst_width, dsty+dst_height, 0,
UTIL_BLITTER_ATTRIB_TEXCOORD, &coord);
} else {
/* Draw the quad with the generic codepath. */
blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z,
src_sample,
srcbox->x, srcbox->y,
srcbox->x + srcbox->width, srcbox->y + srcbox->height);
blitter_draw(ctx, dstx, dsty, dstx+abs_width, dsty+abs_height, 0);
if (copy_all_samples &&
src->texture->nr_samples == dst->texture->nr_samples &&
dst->texture->nr_samples > 1) {
/* MSAA copy. */
unsigned i, max_sample = MAX2(dst->texture->nr_samples, 1) - 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,
i, srcbox->x, srcbox->y,
srcbox->x + srcbox->width,
srcbox->y + srcbox->height);
blitter_draw(ctx, dstx, dsty,
dstx+dst_width, dsty+dst_height, 0);
}
} else {
pipe->set_sample_mask(pipe, ~0);
blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z, 0,
srcbox->x, srcbox->y,
srcbox->x + srcbox->width,
srcbox->y + srcbox->height);
blitter_draw(ctx, dstx, dsty, dstx+dst_width, dsty+dst_height, 0);
}
}
blitter_restore_vertex_states(ctx);
blitter_restore_fragment_states(ctx);
blitter_restore_textures(ctx);
blitter_restore_fb_state(ctx);
if (scissor) {
pipe->set_scissor_state(pipe, &ctx->base.saved_scissor);
}
blitter_restore_render_cond(ctx);
blitter_unset_running_flag(ctx);
}
void
util_blitter_blit(struct blitter_context *blitter,
const struct pipe_blit_info *info)
{
struct pipe_resource *dst = info->dst.resource;
struct pipe_resource *src = info->src.resource;
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
struct pipe_surface *dst_view, dst_templ;
struct pipe_sampler_view src_templ, *src_view;
/* Initialize the surface. */
util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level,
info->dst.box.z, &info->src.box);
dst_templ.format = info->dst.format;
dst_view = pipe->create_surface(pipe, dst, &dst_templ);
/* Initialize the sampler view. */
util_blitter_default_src_texture(&src_templ, src, info->src.level);
src_templ.format = info->src.format;
src_view = pipe->create_sampler_view(pipe, src, &src_templ);
/* Copy. */
util_blitter_blit_generic(blitter, dst_view,
info->dst.box.x, info->dst.box.y,
info->dst.box.width, info->dst.box.height,
src_view, &info->src.box, src->width0, src->height0,
info->mask, info->filter,
info->scissor_enable ? &info->scissor : NULL, TRUE);
pipe_surface_reference(&dst_view, NULL);
pipe_sampler_view_reference(&src_view, NULL);
}
/* Clear a region of a color surface to a constant value. */
void util_blitter_clear_render_target(struct blitter_context *blitter,
struct pipe_surface *dstsurf,
@ -1379,7 +1485,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
blitter_disable_render_cond(ctx);
/* bind states */
pipe->bind_blend_state(pipe, ctx->blend_write_color);
pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
@ -1393,7 +1499,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, ~0);
blitter_set_common_draw_rect_state(ctx);
blitter_set_common_draw_rect_state(ctx, FALSE);
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
UTIL_BLITTER_ATTRIB_COLOR, color);
@ -1431,7 +1537,7 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
blitter_disable_render_cond(ctx);
/* bind states */
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
pipe->bind_blend_state(pipe, ctx->blend[0]);
if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
sr.ref_value[0] = stencil & 0xff;
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
@ -1461,7 +1567,7 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, ~0);
blitter_set_common_draw_rect_state(ctx);
blitter_set_common_draw_rect_state(ctx, FALSE);
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, depth,
UTIL_BLITTER_ATTRIB_NONE, NULL);
@ -1496,7 +1602,7 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
blitter_disable_render_cond(ctx);
/* bind states */
pipe->bind_blend_state(pipe, ctx->blend_write_color);
pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]);
pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE));
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
@ -1516,7 +1622,7 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, sample_mask);
blitter_set_common_draw_rect_state(ctx);
blitter_set_common_draw_rect_state(ctx, FALSE);
blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth,
UTIL_BLITTER_ATTRIB_NONE, NULL);
@ -1641,7 +1747,7 @@ void util_blitter_custom_resolve_color(struct blitter_context *blitter,
fb_state.zsbuf = NULL;
pipe->set_framebuffer_state(pipe, &fb_state);
blitter_set_common_draw_rect_state(ctx);
blitter_set_common_draw_rect_state(ctx, FALSE);
blitter_set_dst_dimensions(ctx, src->width0, src->height0);
blitter->draw_rectangle(blitter, 0, 0, src->width0, src->height0,
0, 0, NULL);
@ -1690,7 +1796,7 @@ void util_blitter_custom_color(struct blitter_context *blitter,
pipe->set_framebuffer_state(pipe, &fb_state);
pipe->set_sample_mask(pipe, ~0);
blitter_set_common_draw_rect_state(ctx);
blitter_set_common_draw_rect_state(ctx, FALSE);
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height,
0, 0, NULL);

View File

@ -74,7 +74,7 @@ struct blitter_context
* a rectangular point sprite.
*/
void (*draw_rectangle)(struct blitter_context *blitter,
unsigned x1, unsigned y1, unsigned x2, unsigned y2,
int x1, int y1, int x2, int y2,
float depth,
enum blitter_attrib_type type,
const union pipe_color_union *color);
@ -94,6 +94,7 @@ struct blitter_context
struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */
struct pipe_stencil_ref saved_stencil_ref; /**< stencil ref */
struct pipe_viewport_state saved_viewport;
struct pipe_scissor_state saved_scissor;
boolean is_sample_mask_saved;
unsigned saved_sample_mask;
@ -137,9 +138,7 @@ struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter)
/* The default function to draw a rectangle. This can only be used
* inside of the draw_rectangle callback if the driver overrides it. */
void util_blitter_draw_rectangle(struct blitter_context *blitter,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
float depth,
int x1, int y1, int x2, int y2, float depth,
enum blitter_attrib_type type,
const union pipe_color_union *attrib);
@ -180,19 +179,13 @@ boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
const struct pipe_resource *dst,
const struct pipe_resource *src,
unsigned mask);
boolean util_blitter_is_blit_supported(struct blitter_context *blitter,
const struct pipe_blit_info *info);
/**
* Copy a block of pixels from one surface to another.
*
* You can copy from any color format to any other color format provided
* the former can be sampled from and the latter can be rendered to. Otherwise,
* a software fallback path is taken and both surfaces must be of the same
* format.
*
* Only one sample of a multisample texture can be copied and is specified by
* src_sample. If the destination is a multisample resource, dst_sample_mask
* specifies the sample mask. For single-sample resources, set dst_sample_mask
* to ~0.
*
* These states must be saved in the blitter in addition to the state objects
* already required to be saved:
* - fragment shader
@ -201,19 +194,21 @@ boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
* - fragment sampler states
* - fragment sampler textures
* - framebuffer state
* - sample mask
*/
void util_blitter_copy_texture(struct blitter_context *blitter,
struct pipe_resource *dst,
unsigned dst_level, unsigned dst_sample_mask,
unsigned dst_level,
unsigned dstx, unsigned dsty, unsigned dstz,
struct pipe_resource *src,
unsigned src_level, unsigned src_sample,
const struct pipe_box *srcbox);
unsigned src_level,
const struct pipe_box *srcbox, unsigned mask,
boolean copy_all_samples);
/**
* Same as util_blitter_copy_texture, but dst and src are pipe_surface and
* pipe_sampler_view, respectively. The mipmap level and dstz are part of
* the views.
* Same as util_blitter_copy_texture with the capabilities of util_blitter_blit,
* but dst and src are pipe_surface and pipe_sampler_view, respectively.
* The mipmap level and dstz are part of the views.
*
* Drivers can use this to change resource properties (like format, width,
* height) by changing how the views interpret them, instead of changing
@ -227,18 +222,20 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
*
* The mask is a combination of the PIPE_MASK_* flags.
* Set to PIPE_MASK_RGBAZS if unsure.
*
* NOTE: There are no checks whether the blit is actually supported.
*/
void util_blitter_copy_texture_view(struct blitter_context *blitter,
struct pipe_surface *dst,
unsigned dst_sample_mask,
unsigned dstx, unsigned dsty,
struct pipe_sampler_view *src,
unsigned src_sample,
const struct pipe_box *srcbox,
unsigned src_width0, unsigned src_height0,
unsigned mask);
void util_blitter_blit_generic(struct blitter_context *blitter,
struct pipe_surface *dst,
int dstx, int dsty,
unsigned dst_width, unsigned dst_height,
struct pipe_sampler_view *src,
const struct pipe_box *srcbox,
unsigned src_width0, unsigned src_height0,
unsigned mask, unsigned filter,
const struct pipe_scissor_state *scissor,
boolean copy_all_samples);
void util_blitter_blit(struct blitter_context *blitter,
const struct pipe_blit_info *info);
/**
* Helper function to initialize a view for copy_texture_view.
@ -415,6 +412,13 @@ void util_blitter_save_viewport(struct blitter_context *blitter,
blitter->saved_viewport = *state;
}
static INLINE
void util_blitter_save_scissor(struct blitter_context *blitter,
struct pipe_scissor_state *state)
{
blitter->saved_scissor = *state;
}
static INLINE
void util_blitter_save_fragment_sampler_states(
struct blitter_context *blitter,

View File

@ -86,8 +86,8 @@ i915_surface_copy_render(struct pipe_context *pipe,
i915->saved_nr_sampler_views,
i915->saved_sampler_views);
util_blitter_copy_texture(i915->blitter, dst, dst_level, ~0, dstx, dsty, dstz,
src, src_level, 0, src_box);
util_blitter_copy_texture(i915->blitter, dst, dst_level, dstx, dsty, dstz,
src, src_level, src_box, PIPE_MASK_RGBAZS, TRUE);
}
static void

View File

@ -577,9 +577,11 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
src_view = r300_create_sampler_view_custom(pipe, src, &src_templ, src_width0, src_height0);
r300_blitter_begin(r300, R300_COPY);
util_blitter_copy_texture_view(r300->blitter, dst_view, ~0, dstx, dsty,
src_view, 0, src_box,
src_width0, src_height0, PIPE_MASK_RGBAZS);
util_blitter_blit_generic(r300->blitter, dst_view, dstx, dsty,
abs(src_box->width), abs(src_box->height),
src_view, src_box,
src_width0, src_height0, PIPE_MASK_RGBAZS,
PIPE_TEX_FILTER_NEAREST, NULL, FALSE);
r300_blitter_end(r300);
pipe_surface_reference(&dst_view, NULL);

View File

@ -722,8 +722,7 @@ void r300_plug_in_stencil_ref_fallback(struct r300_context *r300);
void r300_draw_flush_vbuf(struct r300_context *r300);
void r500_emit_index_bias(struct r300_context *r300, int index_bias);
void r300_blitter_draw_rectangle(struct blitter_context *blitter,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
int x1, int y1, int x2, int y2,
float depth,
enum blitter_attrib_type type,
const union pipe_color_union *attrib);

View File

@ -1172,8 +1172,7 @@ void r300_draw_flush_vbuf(struct r300_context *r300)
* would be computed and stored twice, which makes the clear/copy codepaths
* somewhat inefficient. Instead we use a rectangular point sprite. */
void r300_blitter_draw_rectangle(struct blitter_context *blitter,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
int x1, int y1, int x2, int y2,
float depth,
enum blitter_attrib_type type,
const union pipe_color_union *attrib)

View File

@ -379,10 +379,11 @@ static void r600_copy_first_sample(struct pipe_context *ctx,
/* Copy the first sample into dst. */
r600_blitter_begin(ctx, R600_COPY_TEXTURE);
util_blitter_copy_texture_view(rctx->blitter, dst_view, ~0, info->dst.x0,
info->dst.y0, src_view, 0, &box,
info->src.res->width0, info->src.res->height0,
info->mask);
util_blitter_blit_generic(rctx->blitter, dst_view, info->dst.x0,
info->dst.y0, abs(box.width), abs(box.height),
src_view, &box,
info->src.res->width0, info->src.res->height0,
info->mask, PIPE_TEX_FILTER_NEAREST, NULL, FALSE);
r600_blitter_end(ctx);
pipe_surface_reference(&dst_view, NULL);
@ -460,8 +461,8 @@ static void r600_color_resolve(struct pipe_context *ctx,
r600_blitter_begin(ctx, R600_COPY_TEXTURE);
util_blitter_copy_texture(rctx->blitter, info->dst.res, info->dst.level,
~0, info->dst.x0, info->dst.y0, info->dst.layer,
tmp, 0, 0, &box);
info->dst.x0, info->dst.y0, info->dst.layer,
tmp, 0, &box, PIPE_MASK_RGBAZS, FALSE);
r600_blitter_end(ctx);
pipe_resource_reference(&tmp, NULL);
@ -678,7 +679,6 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
struct pipe_box sbox;
const struct pipe_box *psbox = src_box;
boolean restore_orig[2];
unsigned last_sample, i;
memset(orig_info, 0, sizeof(orig_info));
@ -689,7 +689,6 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
}
assert(u_max_sample(dst) == u_max_sample(src));
last_sample = u_max_sample(dst);
/* The driver doesn't decompress resources automatically while
* u_blitter is rendering. */
@ -756,21 +755,14 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
restore_orig[1] = TRUE;
}
/* XXX Properly implement multisample textures on Cayman. In the meantime,
* copy only the first sample (which is the only one that doesn't return garbage). */
if (rctx->chip_class == CAYMAN) {
r600_blitter_begin(ctx, R600_COPY_TEXTURE);
util_blitter_copy_texture(rctx->blitter, dst, dst_level, ~0, dstx, dsty, dstz,
src, src_level, 0, psbox);
r600_blitter_end(ctx);
} else {
for (i = 0; i <= last_sample; i++) {
r600_blitter_begin(ctx, R600_COPY_TEXTURE);
util_blitter_copy_texture(rctx->blitter, dst, dst_level, 1 << i, dstx, dsty, dstz,
src, src_level, i, psbox);
r600_blitter_end(ctx);
}
}
/* XXX Multisample texturing is unimplemented on Cayman. In the meantime,
* copy only the first sample (which is the only one that is uncompressed
* and therefore doesn't return garbage). */
r600_blitter_begin(ctx, R600_COPY_TEXTURE);
util_blitter_copy_texture(rctx->blitter, dst, dst_level, dstx, dsty, dstz,
src, src_level, psbox, PIPE_MASK_RGBAZS,
rctx->chip_class != CAYMAN);
r600_blitter_end(ctx);
if (restore_orig[0])
r600_reset_blittable_to_orig(src, src_level, &orig_info[0]);

View File

@ -643,7 +643,7 @@ void r600_sampler_states_dirty(struct r600_context *rctx,
void r600_set_max_scissor(struct r600_context *rctx);
void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf_state *state);
void r600_draw_rectangle(struct blitter_context *blitter,
unsigned x1, unsigned y1, unsigned x2, unsigned y2, float depth,
int x1, int y1, int x2, int y2, float depth,
enum blitter_attrib_type type, const union pipe_color_union *attrib);
uint32_t r600_translate_stencil_op(int s_op);
uint32_t r600_translate_fill(uint32_t func);

View File

@ -1343,7 +1343,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
}
void r600_draw_rectangle(struct blitter_context *blitter,
unsigned x1, unsigned y1, unsigned x2, unsigned y2, float depth,
int x1, int y1, int x2, int y2, float depth,
enum blitter_attrib_type type, const union pipe_color_union *attrib)
{
struct r600_context *rctx = (struct r600_context*)util_blitter_get_pipe(blitter);

View File

@ -249,8 +249,8 @@ static void r600_hw_copy_region(struct pipe_context *ctx,
struct r600_context *rctx = (struct r600_context *)ctx;
r600_blitter_begin(ctx, R600_COPY);
util_blitter_copy_texture(rctx->blitter, dst, dst_level, ~0, dstx, dsty, dstz,
src, src_level, 0, src_box);
util_blitter_copy_texture(rctx->blitter, dst, dst_level, dstx, dsty, dstz,
src, src_level, src_box, PIPE_MASK_RGBAZS, TRUE);
r600_blitter_end(ctx);
}