diff options
author | Roland Scheidegger <[email protected]> | 2010-05-21 20:02:22 +0200 |
---|---|---|
committer | Roland Scheidegger <[email protected]> | 2010-05-21 20:02:22 +0200 |
commit | 3293bcdc80cdfa20a2381aae2b94505bdf95d857 (patch) | |
tree | 16ab1ae66010f6d8b1325dbfa9006126a8e95771 /src | |
parent | 8504c5d931e47765a15fdaec2df2cb6502a1bd5c (diff) | |
parent | ce65caba846b03b5ef4144e311b85cfd48ab9bbb (diff) |
Merge branch 'gallium-msaa'
Conflicts:
src/mesa/state_tracker/st_gen_mipmap.c
src/mesa/state_tracker/st_texture.c
Diffstat (limited to 'src')
112 files changed, 1325 insertions, 934 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 75bf8d5d407..20a8612dcae 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -99,6 +99,7 @@ struct cso_context { struct pipe_framebuffer_state fb, fb_saved; struct pipe_viewport_state vp, vp_saved; struct pipe_blend_color blend_color; + unsigned sample_mask; struct pipe_stencil_ref stencil_ref, stencil_ref_saved; }; @@ -953,6 +954,16 @@ enum pipe_error cso_set_blend_color(struct cso_context *ctx, return PIPE_OK; } +enum pipe_error cso_set_sample_mask(struct cso_context *ctx, + unsigned sample_mask) +{ + if (ctx->sample_mask != sample_mask) { + ctx->sample_mask = sample_mask; + ctx->pipe->set_sample_mask(ctx->pipe, sample_mask); + } + return PIPE_OK; +} + enum pipe_error cso_set_stencil_ref(struct cso_context *ctx, const struct pipe_stencil_ref *sr) { diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index d6bcb1fe8f7..f0b07f73765 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -159,6 +159,8 @@ void cso_restore_viewport(struct cso_context *cso); enum pipe_error cso_set_blend_color(struct cso_context *cso, const struct pipe_blend_color *bc); +enum pipe_error cso_set_sample_mask(struct cso_context *cso, + unsigned stencil_mask); enum pipe_error cso_set_stencil_ref(struct cso_context *cso, const struct pipe_stencil_ref *sr); diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index f6f6e481d94..d4fbd658f40 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -190,7 +190,6 @@ get_next_slot( struct blit_state *ctx ) return ctx->vbuf_slot++ * sizeof ctx->vertices; } - @@ -277,10 +276,11 @@ regions_overlap(int srcX0, int srcY0, */ void util_blit_pixels_writemask(struct blit_state *ctx, - struct pipe_surface *src, - struct pipe_sampler_view *src_sampler_view, + struct pipe_resource *src_tex, + struct pipe_subresource srcsub, int srcX0, int srcY0, int srcX1, int srcY1, + int srcZ0, struct pipe_surface *dst, int dstX0, int dstY0, int dstX1, int dstY1, @@ -290,6 +290,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; struct pipe_sampler_view *sampler_view = NULL; + struct pipe_sampler_view sv_templ; struct pipe_framebuffer_state fb; const int srcW = abs(srcX1 - srcX0); const int srcH = abs(srcY1 - srcY0); @@ -300,13 +301,13 @@ util_blit_pixels_writemask(struct blit_state *ctx, assert(filter == PIPE_TEX_MIPFILTER_NEAREST || filter == PIPE_TEX_MIPFILTER_LINEAR); - assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, - PIPE_BIND_SAMPLER_VIEW, 0)); - assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, - PIPE_BIND_RENDER_TARGET, 0)); + assert(srcsub.level <= src_tex->last_level); /* do the regions overlap? */ - overlap = util_same_surface(src, dst) && + overlap = src_tex == dst->texture && + dst->face == srcsub.face && + dst->level == srcsub.level && + dst->zslice == srcZ0 && regions_overlap(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1); @@ -315,8 +316,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, * no overlapping. * Filter mode should not matter since there's no stretching. */ - if (pipe->surface_copy && - dst->format == src->format && + if (dst->format == src_tex->format && srcX0 < srcX1 && dstX0 < dstX1 && srcY0 < srcY1 && @@ -324,29 +324,36 @@ util_blit_pixels_writemask(struct blit_state *ctx, (dstX1 - dstX0) == (srcX1 - srcX0) && (dstY1 - dstY0) == (srcY1 - srcY0) && !overlap) { - pipe->surface_copy(pipe, - dst, dstX0, dstY0, /* dest */ - src, srcX0, srcY0, /* src */ - srcW, srcH); /* size */ + struct pipe_subresource subdst; + subdst.face = dst->face; + subdst.level = dst->level; + pipe->resource_copy_region(pipe, + dst->texture, subdst, + dstX0, dstY0, dst->zslice,/* dest */ + src_tex, srcsub, + srcX0, srcY0, srcZ0,/* src */ + srcW, srcH); /* size */ return; } - - assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, - PIPE_BIND_RENDER_TARGET, 0)); + /* Create a temporary texture when src and dest alias or when src - * is anything other than a single-level 2d texture. + * is anything other than a 2d texture. + * XXX should just use appropriate shader to access 1d / 3d slice / cube face, + * much like the u_blitter code does (should be pretty trivial). * * This can still be improved upon. */ - if (util_same_surface(src, dst) || - src->texture->target != PIPE_TEXTURE_2D || - src->texture->last_level != 0) + if ((src_tex == dst->texture && + dst->face == srcsub.face && + dst->level == srcsub.level && + dst->zslice == srcZ0) || + src_tex->target != PIPE_TEXTURE_2D) { struct pipe_resource texTemp; struct pipe_resource *tex; struct pipe_sampler_view sv_templ; - struct pipe_surface *texSurf; + struct pipe_subresource texsub; const int srcLeft = MIN2(srcX0, srcX1); const int srcTop = MIN2(srcY0, srcY1); @@ -367,7 +374,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, /* create temp texture */ memset(&texTemp, 0, sizeof(texTemp)); texTemp.target = PIPE_TEXTURE_2D; - texTemp.format = src->format; + texTemp.format = src_tex->format; texTemp.last_level = 0; texTemp.width0 = srcW; texTemp.height0 = srcH; @@ -378,49 +385,50 @@ util_blit_pixels_writemask(struct blit_state *ctx, if (!tex) return; - u_sampler_view_default_template(&sv_templ, tex, tex->format); - - sampler_view = ctx->pipe->create_sampler_view(ctx->pipe, tex, &sv_templ); - if (!sampler_view) { - pipe_resource_reference(&tex, NULL); - return; - } - - texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, - PIPE_BIND_BLIT_DESTINATION); - + texsub.face = 0; + texsub.level = 0; /* load temp texture */ - if (pipe->surface_copy) { - pipe->surface_copy(pipe, - texSurf, 0, 0, /* dest */ - src, srcLeft, srcTop, /* src */ - srcW, srcH); /* size */ - } else { - util_surface_copy(pipe, FALSE, - texSurf, 0, 0, /* dest */ - src, srcLeft, srcTop, /* src */ - srcW, srcH); /* size */ - } + pipe->resource_copy_region(pipe, + tex, texsub, 0, 0, 0, /* dest */ + src_tex, srcsub, srcLeft, srcTop, srcZ0, /* src */ + srcW, srcH); /* size */ - /* free the surface, update the texture if necessary. - */ - pipe_surface_reference(&texSurf, NULL); s0 = 0.0f; s1 = 1.0f; t0 = 0.0f; t1 = 1.0f; + u_sampler_view_default_template(&sv_templ, tex, tex->format); + sampler_view = pipe->create_sampler_view(pipe, tex, &sv_templ); + + if (!sampler_view) { + pipe_resource_reference(&tex, NULL); + return; + } pipe_resource_reference(&tex, NULL); } else { - pipe_sampler_view_reference(&sampler_view, src_sampler_view); - s0 = srcX0 / (float)src->texture->width0; - s1 = srcX1 / (float)src->texture->width0; - t0 = srcY0 / (float)src->texture->height0; - t1 = srcY1 / (float)src->texture->height0; + u_sampler_view_default_template(&sv_templ, src_tex, src_tex->format); + sv_templ.first_level = sv_templ.last_level = srcsub.level; + sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ); + + if (!sampler_view) { + return; + } + + s0 = srcX0 / (float)(u_minify(sampler_view->texture->width0, srcsub.level)); + s1 = srcX1 / (float)(u_minify(sampler_view->texture->width0, srcsub.level)); + t0 = srcY0 / (float)(u_minify(sampler_view->texture->height0, srcsub.level)); + t1 = srcY1 / (float)(u_minify(sampler_view->texture->height0, srcsub.level)); } - + + assert(screen->is_format_supported(screen, sampler_view->format, PIPE_TEXTURE_2D, + sampler_view->texture->nr_samples, + PIPE_BIND_SAMPLER_VIEW, 0)); + assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, + dst->texture->nr_samples, + PIPE_BIND_RENDER_TARGET, 0)); /* save state (restored below) */ cso_save_blend(ctx->cso); @@ -445,6 +453,9 @@ util_blit_pixels_writemask(struct blit_state *ctx, /* sampler */ ctx->sampler.min_img_filter = filter; ctx->sampler.mag_img_filter = filter; + /* we've limited this already with the sampler view but you never know... */ + ctx->sampler.min_lod = srcsub.level; + ctx->sampler.max_lod = srcsub.level; cso_single_sampler(ctx->cso, 0, &ctx->sampler); cso_single_sampler_done(ctx->cso); @@ -513,18 +524,21 @@ util_blit_pixels_writemask(struct blit_state *ctx, void util_blit_pixels(struct blit_state *ctx, - struct pipe_surface *src, - struct pipe_sampler_view *src_sampler_view, + struct pipe_resource *src_tex, + struct pipe_subresource srcsub, int srcX0, int srcY0, int srcX1, int srcY1, + int srcZ, struct pipe_surface *dst, int dstX0, int dstY0, int dstX1, int dstY1, float z, uint filter ) { - util_blit_pixels_writemask( ctx, src, src_sampler_view, + util_blit_pixels_writemask( ctx, src_tex, + srcsub, srcX0, srcY0, srcX1, srcY1, + srcZ, dst, dstX0, dstY0, dstX1, dstY1, @@ -546,7 +560,6 @@ void util_blit_flush( struct blit_state *ctx ) /** * Copy pixel block from src texture to dst surface. - * Overlapping regions are acceptable. * * XXX Should support selection of level. * XXX need some control over blitting Z and/or stencil. @@ -580,6 +593,7 @@ util_blit_pixels_tex(struct blit_state *ctx, assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, PIPE_TEXTURE_2D, + dst->texture->nr_samples, PIPE_BIND_RENDER_TARGET, 0)); diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h index 464ff9aaced..ef95134f324 100644 --- a/src/gallium/auxiliary/util/u_blit.h +++ b/src/gallium/auxiliary/util/u_blit.h @@ -52,10 +52,11 @@ util_destroy_blit(struct blit_state *ctx); extern void util_blit_pixels(struct blit_state *ctx, - struct pipe_surface *src, - struct pipe_sampler_view *src_sampler_view, + struct pipe_resource *src_tex, + struct pipe_subresource srcsub, int srcX0, int srcY0, int srcX1, int srcY1, + int srcZ0, struct pipe_surface *dst, int dstX0, int dstY0, int dstX1, int dstY1, @@ -63,10 +64,11 @@ util_blit_pixels(struct blit_state *ctx, void util_blit_pixels_writemask(struct blit_state *ctx, - struct pipe_surface *src, - struct pipe_sampler_view *src_sampler_view, + struct pipe_resource *src_tex, + struct pipe_subresource srcsub, int srcX0, int srcY0, int srcX1, int srcY1, + int srcZ0, struct pipe_surface *dst, int dstX0, int dstY0, int dstX1, int dstY1, diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 3a7c4db6f34..e0bd89154cb 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -26,8 +26,8 @@ /** * @file - * Blitter utility to facilitate acceleration of the clear, surface_copy, - * and surface_fill functions. + * Blitter utility to facilitate acceleration of the clear, resource_copy_region, + * and resource_fill_region functions. * * @author Marek Olšák */ @@ -709,53 +709,6 @@ static void util_blitter_do_copy(struct blitter_context *blitter, } -static void util_blitter_overlap_copy(struct blitter_context *blitter, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - struct pipe_surface *src, - unsigned srcx, unsigned srcy, - unsigned width, unsigned height) -{ - struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; - struct pipe_context *pipe = ctx->pipe; - struct pipe_screen *screen = pipe->screen; - - struct pipe_resource texTemp; - struct pipe_resource *texture; - struct pipe_surface *tex_surf; - - /* check whether the states are properly saved */ - blitter_check_saved_CSOs(ctx); - - memset(&texTemp, 0, sizeof(texTemp)); - texTemp.target = PIPE_TEXTURE_2D; - texTemp.format = dst->texture->format; /* XXX verify supported by driver! */ - texTemp.last_level = 0; - texTemp.width0 = width; - texTemp.height0 = height; - texTemp.depth0 = 1; - - texture = screen->resource_create(screen, &texTemp); - if (!texture) - return; - - tex_surf = screen->get_tex_surface(screen, texture, 0, 0, 0, - PIPE_BIND_BLIT_SOURCE | - PIPE_BIND_BLIT_DESTINATION); - - /* blit from the src to the temp */ - util_blitter_do_copy(blitter, tex_surf, 0, 0, - src, srcx, srcy, - width, height, - FALSE); - util_blitter_do_copy(blitter, dst, dstx, dsty, - tex_surf, 0, 0, - width, height, - FALSE); - pipe_surface_reference(&tex_surf, NULL); - pipe_resource_reference(&texture, NULL); - blitter_restore_CSOs(ctx); -} void util_blitter_copy(struct blitter_context *blitter, struct pipe_surface *dst, @@ -777,14 +730,10 @@ void util_blitter_copy(struct blitter_context *blitter, return; if (dst->texture == src->texture) { - if (is_overlap(srcx, srcx + width, srcy, srcy + height, - dstx, dstx + width, dsty, dsty + height)) { - util_blitter_overlap_copy(blitter, dst, dstx, dsty, src, srcx, srcy, - width, height); - return; - } + assert(!is_overlap(srcx, srcx + width, srcy, srcy + height, + dstx, dstx + width, dsty, dsty + height)); } - + is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0; dst_tex_usage = is_depth || is_stencil ? PIPE_BIND_DEPTH_STENCIL : @@ -794,11 +743,17 @@ void util_blitter_copy(struct blitter_context *blitter, /* (assuming copying a stencil buffer is not possible) */ if ((!ignore_stencil && is_stencil) || !screen->is_format_supported(screen, dst->format, dst->texture->target, - dst_tex_usage, 0) || + dst->texture->nr_samples, dst_tex_usage, 0) || !screen->is_format_supported(screen, src->format, src->texture->target, - PIPE_BIND_SAMPLER_VIEW, 0)) { - util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, - width, height); + src->texture->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) { + struct pipe_subresource subdst, subsrc; + subdst.face = dst->face; + subdst.level = dst->level; + subsrc.face = src->face; + subsrc.level = src->level; + util_resource_copy_region(pipe, dst->texture, subdst, dstx, dsty, dst->zslice, + src->texture, subsrc, srcx, srcy, src->zslice, + width, height); return; } @@ -833,8 +788,13 @@ void util_blitter_fill(struct blitter_context *blitter, /* check if we can render to the surface */ if (util_format_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */ !screen->is_format_supported(screen, dst->format, dst->texture->target, + dst->texture->nr_samples, PIPE_BIND_RENDER_TARGET, 0)) { - util_surface_fill(pipe, dst, dstx, dsty, width, height, value); + struct pipe_subresource subdst; + subdst.face = dst->face; + subdst.level = dst->level; + util_resource_fill_region(pipe, dst->texture, subdst, dstx, dsty, + dst->zslice, width, height, value); return; } diff --git a/src/gallium/auxiliary/util/u_caps.c b/src/gallium/auxiliary/util/u_caps.c index c7c1e830e01..294ee37033d 100644 --- a/src/gallium/auxiliary/util/u_caps.c +++ b/src/gallium/auxiliary/util/u_caps.c @@ -68,6 +68,7 @@ util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out) if (!screen->is_format_supported(screen, list[i++], PIPE_TEXTURE_2D, + 0, PIPE_BIND_SAMPLER_VIEW, 0)) { *out = i - 2; diff --git a/src/gallium/auxiliary/util/u_clear.h b/src/gallium/auxiliary/util/u_clear.h index 40da2d75a72..31f7fb2169a 100644 --- a/src/gallium/auxiliary/util/u_clear.h +++ b/src/gallium/auxiliary/util/u_clear.h @@ -47,25 +47,24 @@ util_clear(struct pipe_context *pipe, { if (buffers & PIPE_CLEAR_COLOR) { struct pipe_surface *ps = framebuffer->cbufs[0]; + struct pipe_subresource subdst; union util_color uc; + subdst.face = ps->face; + subdst.level = ps->level; util_pack_color(rgba, ps->format, &uc); - if (pipe->surface_fill) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui); - } else { - util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui); - } + pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice, + ps->width, ps->height, uc.ui); } if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { struct pipe_surface *ps = framebuffer->zsbuf; + struct pipe_subresource subdst; - if (pipe->surface_fill) { - pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, - util_pack_z_stencil(ps->format, depth, stencil)); - } else { - util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, - util_pack_z_stencil(ps->format, depth, stencil)); - } + subdst.face = ps->face; + subdst.level = ps->level; + pipe->resource_fill_region(pipe, ps->texture, subdst, 0, 0, ps->zslice, + ps->width, ps->height, + util_pack_z_stencil(ps->format, depth, stencil)); } } diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 1553e08d6ce..d19267be72f 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -1493,7 +1493,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, /* check if we can render in the texture's format */ if (!screen->is_format_supported(screen, psv->format, PIPE_TEXTURE_2D, - PIPE_BIND_RENDER_TARGET, 0)) { + pt->nr_samples, PIPE_BIND_RENDER_TARGET, 0)) { fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); return; } diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index 377c48c0266..9adf22c471e 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -69,7 +69,7 @@ util_create_rgba_surface(struct pipe_screen *screen, /* Choose surface format */ for (i = 0; rgbaFormats[i]; i++) { if (screen->is_format_supported(screen, rgbaFormats[i], - target, bind, 0)) { + target, 0, bind, 0)) { format = rgbaFormats[i]; break; } @@ -119,44 +119,44 @@ util_destroy_rgba_surface(struct pipe_resource *texture, /** - * Fallback function for pipe->surface_copy(). + * Fallback function for pipe->resource_copy_region(). * Note: (X,Y)=(0,0) is always the upper-left corner. - * if do_flip, flip the image vertically on its way from src rect to dst rect. */ void -util_surface_copy(struct pipe_context *pipe, - boolean do_flip, - struct pipe_surface *dst, - unsigned dst_x, unsigned dst_y, - struct pipe_surface *src, - unsigned src_x, unsigned src_y, - unsigned w, unsigned h) +util_resource_copy_region(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dst_x, unsigned dst_y, unsigned dst_z, + struct pipe_resource *src, + struct pipe_subresource subsrc, + unsigned src_x, unsigned src_y, unsigned src_z, + unsigned w, unsigned h) { struct pipe_transfer *src_trans, *dst_trans; void *dst_map; const void *src_map; enum pipe_format src_format, dst_format; - assert(src->texture && dst->texture); - if (!src->texture || !dst->texture) + assert(src && dst); + if (!src || !dst) return; - src_format = src->texture->format; - dst_format = dst->texture->format; + src_format = src->format; + dst_format = dst->format; src_trans = pipe_get_transfer(pipe, - src->texture, - src->face, - src->level, - src->zslice, + src, + subsrc.face, + subsrc.level, + src_z, PIPE_TRANSFER_READ, src_x, src_y, w, h); dst_trans = pipe_get_transfer(pipe, - dst->texture, - dst->face, - dst->level, - dst->zslice, + dst, + subdst.face, + subdst.level, + src_z, PIPE_TRANSFER_WRITE, dst_x, dst_y, w, h); @@ -171,16 +171,15 @@ util_surface_copy(struct pipe_context *pipe, assert(dst_map); if (src_map && dst_map) { - /* If do_flip, invert src_y position and pass negative src stride */ util_copy_rect(dst_map, dst_format, dst_trans->stride, 0, 0, w, h, src_map, - do_flip ? -(int) src_trans->stride : src_trans->stride, + src_trans->stride, 0, - do_flip ? h - 1 : 0); + 0); } pipe->transfer_unmap(pipe, src_trans); @@ -196,25 +195,26 @@ util_surface_copy(struct pipe_context *pipe, /** - * Fallback for pipe->surface_fill() function. + * Fallback for pipe->resource_fill_region() function. */ void -util_surface_fill(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, unsigned value) +util_resource_fill_region(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + unsigned width, unsigned height, unsigned value) { struct pipe_transfer *dst_trans; void *dst_map; - assert(dst->texture); - if (!dst->texture) + assert(dst); + if (!dst) return; dst_trans = pipe_get_transfer(pipe, - dst->texture, - dst->face, - dst->level, - dst->zslice, + dst, + subdst.face, + subdst.level, + dstz, PIPE_TRANSFER_WRITE, dstx, dsty, width, height); @@ -225,11 +225,11 @@ util_surface_fill(struct pipe_context *pipe, if (dst_map) { assert(dst_trans->stride > 0); - switch (util_format_get_blocksize(dst->texture->format)) { + switch (util_format_get_blocksize(dst->format)) { case 1: case 2: case 4: - util_fill_rect(dst_map, dst->texture->format, + util_fill_rect(dst_map, dst->format, dst_trans->stride, 0, 0, width, height, value); break; diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h index c43169b5278..ccde738ca40 100644 --- a/src/gallium/auxiliary/util/u_surface.h +++ b/src/gallium/auxiliary/util/u_surface.h @@ -33,23 +33,6 @@ #include "pipe/p_state.h" -/** - * Are s1 and s2 the same surface? - * Surfaces are basically views into textures so check if the two surfaces - * name the same part of the same texture. - */ -static INLINE boolean -util_same_surface(const struct pipe_surface *s1, const struct pipe_surface *s2) -{ - return (s1->texture == s2->texture && - s1->face == s2->face && - s1->level == s2->level && - s1->zslice == s2->zslice); -} - - - - extern boolean util_create_rgba_surface(struct pipe_screen *screen, uint width, uint height, uint bind, @@ -64,19 +47,21 @@ util_destroy_rgba_surface(struct pipe_resource *texture, extern void -util_surface_copy(struct pipe_context *pipe, - boolean do_flip, - struct pipe_surface *dst, - unsigned dst_x, unsigned dst_y, - struct pipe_surface *src, - unsigned src_x, unsigned src_y, - unsigned w, unsigned h); +util_resource_copy_region(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dst_x, unsigned dst_y, unsigned dst_z, + struct pipe_resource *src, + struct pipe_subresource subsrc, + unsigned src_x, unsigned src_y, unsigned src_z, + unsigned w, unsigned h); extern void -util_surface_fill(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, unsigned value); +util_resource_fill_region(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + unsigned width, unsigned height, unsigned value); diff --git a/src/gallium/docs/d3d11ddi.txt b/src/gallium/docs/d3d11ddi.txt index 8f2509ce035..d9c2b441a94 100644 --- a/src/gallium/docs/d3d11ddi.txt +++ b/src/gallium/docs/d3d11ddi.txt @@ -79,7 +79,7 @@ set_clip_state set_polygon_stipple + Gallium supports polygon stipple -surface_fill +resource_fill_region + Gallium supports subrectangle fills of surfaces, D3D10 only supports full clears of views * DirectX 10/11 DDI functions and Gallium equivalents @@ -114,11 +114,10 @@ CheckDeferredContextHandleSizes (D3D11 only) CheckFormatSupport -> screen->is_format_supported ! Gallium passes usages to this function, D3D11 returns them - Gallium does not differentiate between blendable and non-blendable render targets - - Gallium lacks multisampled-texture and multisampled-render-target usages + ! Gallium includes sample count directly, D3D11 uses additional query CheckMultisampleQualityLevels - * could merge this with is_format_supported - - Gallium lacks multisampling support + ! is merged with is_format_supported CommandListExecute (D3D11 only) - Gallium does not support command lists @@ -139,7 +138,6 @@ ClearUnorderedAccessViewUint (D3D11 only) CreateBlendState (extended in D3D10.1) -> create_blend_state # D3D10 does not support per-RT blend modes (but per-RT blending), only D3D10.1 does - - Gallium lacks alpha-to-coverage + Gallium supports logic ops + Gallium supports dithering + Gallium supports using the broadcast alpha component of the blend constant color @@ -198,7 +196,6 @@ CreateQuery -> create_query CreateRasterizerState - Gallium lacks clamping of polygon offset depth biases - Gallium lacks support to disable depth clipping - - Gallium lacks multisampling + Gallium, like OpenGL, supports PIPE_POLYGON_MODE_POINT + Gallium, like OpenGL, supports per-face polygon fill modes + Gallium, like OpenGL, supports culling everything @@ -228,7 +225,6 @@ CreateResource -> texture_create or buffer_create ! D3D11 specifies mapping flags (i.e. read/write/discard);:it's unclear what they are used for here - D3D11 supports odd things in the D3D10_DDI_RESOURCE_MISC_FLAG enum (D3D10_DDI_RESOURCE_MISC_DISCARD_ON_PRESENT, D3D11_DDI_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS, D3D11_DDI_RESOURCE_MISC_BUFFER_STRUCTURED) - Gallium does not support indirect draw call parameter buffers - - Gallium lacks multisampling - Gallium lacks array textures ! D3D11 supports specifying hardware modes and other stuff here for scanout resources + Gallium allows specifying minimum buffer alignment @@ -400,7 +396,7 @@ ResourceCopy ResourceCopyRegion ResourceConvert (D3D10.1+ only) ResourceConvertRegion (D3D10.1+ only) - -> surface_copy + -> resource_copy_region - Gallium does not support hardware buffer copies - Gallium does not support copying 3D texture subregions in a single call @@ -410,8 +406,7 @@ ResourceIsStagingBusy -> is_texture_referenced, is_buffer_referenced ResourceReadAfterWriteHazard ! Gallium specifies hides this, except for the render and texture caches -ResourceResolveSubresource - - Gallium does not support multisample sample resolution +ResourceResolveSubresource -> resource_resolve ResourceMap ResourceUnmap @@ -433,9 +428,8 @@ StagingResourceUnmap ResourceUpdateSubresourceUP -> transfer functionality, transfer_inline_write in gallium-resources DefaultConstantBufferUpdateSubresourceUP -> transfer functionality, transfer_inline_write in gallium-resources -SetBlendState -> bind_blend_state and set_blend_color - ! D3D11 fuses bind_blend_state and set_blend_color in a single function - - Gallium lacks the sample mask +SetBlendState -> bind_blend_state, set_blend_color and set_sample_mask + ! D3D11 fuses bind_blend_state, set_blend_color and set_sample_mask in a single function SetDepthStencilState -> bind_depth_stencil_alpha_state and set_stencil_ref ! D3D11 fuses bind_depth_stencil_alpha_state and set_stencil_ref in a single function diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index ec358e34545..89c02b1b703 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -54,6 +54,7 @@ objects. They all follow simple, one-method binding calls, e.g. * ``set_stencil_ref`` sets the stencil front and back reference values which are used as comparison values in stencil test. * ``set_blend_color`` +* ``set_sample_mask`` * ``set_clip_state`` * ``set_polygon_stipple`` * ``set_scissor_state`` sets the bounds for the scissor test, which culls @@ -259,18 +260,22 @@ Resource Busy Queries Blitting ^^^^^^^^ -These methods emulate classic blitter controls. They are not guaranteed to be -available; if they are set to NULL, then they are not present. +These methods emulate classic blitter controls. -These methods operate directly on ``pipe_surface`` objects, and stand +These methods operate directly on ``pipe_resource`` objects, and stand apart from any 3D state in the context. Blitting functionality may be moved to a separate abstraction at some point in the future. -``surface_fill`` performs a fill operation on a section of a surface. +``resource_fill_region`` performs a fill operation on a section of a resource. -``surface_copy`` blits a region of a surface to a region of another surface, -provided that both surfaces are the same format. The source and destination -may be the same surface, and overlapping blits are permitted. +``resource_copy_region`` blits a region of a subresource of a resource to a +region of another subresource of a resource, provided that both resources have the +same format. The source and destination may be the same resource, but overlapping +blits are not permitted. + +``resource_resolve`` resolves a multisampled resource into a non-multisampled +one. Formats and dimensions must match. This function must be present if a driver +supports multisampling. The interfaces to these calls are likely to change to make it easier for a driver to batch multiple blits with the same source and diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index 96257f93df9..48d9d570b6f 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -147,9 +147,6 @@ resources might be created and handled quite differently. * ``PIPE_BIND_VERTEX_BUFFER``: A vertex buffer. * ``PIPE_BIND_INDEX_BUFFER``: An vertex index/element buffer. * ``PIPE_BIND_CONSTANT_BUFFER``: A buffer of shader constants. -* ``PIPE_BIND_BLIT_SOURCE``: A blit source, as given to surface_copy. -* ``PIPE_BIND_BLIT_DESTINATION``: A blit destination, as given to surface_copy - and surface_fill. * ``PIPE_BIND_TRANSFER_WRITE``: A transfer object which will be written to. * ``PIPE_BIND_TRANSFER_READ``: A transfer object which will be read from. * ``PIPE_BIND_CUSTOM``: @@ -236,13 +233,15 @@ Determine if a resource in the given format can be used in a specific manner. **target** one of the PIPE_TEXTURE_x flags +**sample_count** the number of samples. 0 and 1 mean no multisampling, +the maximum allowed legal value is 32. + **bindings** is a bitmask of :ref:`PIPE_BIND` flags. **geom_flags** is a bitmask of PIPE_TEXTURE_GEOM_x flags. Returns TRUE if all usages can be satisfied. - .. _resource_create: resource_create diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index f4c614eef95..03f84d295b5 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -125,6 +125,7 @@ cell_set_stencil_ref(struct pipe_context *pipe, cell->dirty |= CELL_NEW_DEPTH_STENCIL; } + static void cell_set_clip_state(struct pipe_context *pipe, const struct pipe_clip_state *clip) @@ -136,6 +137,12 @@ cell_set_clip_state(struct pipe_context *pipe, } +static void +cell_set_sample_mask(struct pipe_context *pipe, + unsigned sample_mask) +{ +} + /* Called when driver state tracker notices changes to the viewport * matrix: @@ -430,7 +437,6 @@ cell_set_framebuffer_state(struct pipe_context *pipe, } - void cell_init_state_functions(struct cell_context *cell) { @@ -457,6 +463,7 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.set_blend_color = cell_set_blend_color; cell->pipe.set_stencil_ref = cell_set_stencil_ref; cell->pipe.set_clip_state = cell_set_clip_state; + cell->pipe.set_sample_mask = cell_set_sample_mask; cell->pipe.set_framebuffer_state = cell_set_framebuffer_state; diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 750f0aa98ab..0f12e0667eb 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -134,13 +134,17 @@ cell_get_paramf(struct pipe_screen *screen, enum pipe_cap param) static boolean cell_is_format_supported( struct pipe_screen *screen, - enum pipe_format format, + enum pipe_format format, enum pipe_texture_target target, - unsigned tex_usage, + unsigned sample_count, + unsigned tex_usage, unsigned geom_flags ) { struct sw_winsys *winsys = cell_screen(screen)->winsys; + if (sample_count > 1) + return FALSE; + if (tex_usage & (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED)) { diff --git a/src/gallium/drivers/cell/ppu/cell_surface.c b/src/gallium/drivers/cell/ppu/cell_surface.c index 6696a4591c1..8000eee88a3 100644 --- a/src/gallium/drivers/cell/ppu/cell_surface.c +++ b/src/gallium/drivers/cell/ppu/cell_surface.c @@ -30,21 +30,9 @@ #include "cell_surface.h" -static void -cell_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, unsigned destx, unsigned desty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, - unsigned width, unsigned height) -{ - util_surface_copy(pipe, FALSE, - dest, destx, desty, - src, srcx, srcy, - width, height); -} - void cell_init_surface_functions(struct cell_context *cell) { - cell->pipe.surface_copy = cell_surface_copy; - cell->pipe.surface_fill = util_surface_fill; + cell->pipe.resource_copy_region = util_resource_copy_region; + cell->pipe.resource_fill_region = util_resource_fill_region; } diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index 9515cd8938c..2246c1468ca 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -156,8 +156,8 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover_init_state_functions( failover ); - failover->pipe.surface_copy = hw->surface_copy; - failover->pipe.surface_fill = hw->surface_fill; + failover->pipe.resource_copy_region = hw->resource_copy_region; + failover->pipe.resource_fill_region = hw->resource_fill_region; #if 0 failover->pipe.texture_create = hw->texture_create; diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 88ae5ad60d5..9d3e0d0dba0 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -55,6 +55,7 @@ #define FO_NEW_CLEAR_COLOR 0x20000 #define FO_NEW_VERTEX_BUFFER 0x40000 #define FO_NEW_VERTEX_ELEMENT 0x80000 +#define FO_NEW_SAMPLE_MASK 0x100000 @@ -90,6 +91,7 @@ struct failover_context { struct pipe_blend_color blend_color; struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; + unsigned sample_mask; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index 272e683067e..12e42379f98 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -125,6 +125,19 @@ failover_set_clip_state( struct pipe_context *pipe, failover->hw->set_clip_state( failover->hw, clip ); } +static void +failover_set_sample_mask(struct pipe_context *pipe, + unsigned sample_mask) +{ + struct failover_context *failover = failover_context(pipe); + + failover->sample_mask = sample_mask; + failover->dirty |= FO_NEW_SAMPLE_MASK; + failover->sw->set_sample_mask( failover->sw, sample_mask ); + failover->hw->set_sample_mask( failover->hw, sample_mask ); + +} + static void * failover_create_depth_stencil_state(struct pipe_context *pipe, @@ -614,6 +627,7 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.set_blend_color = failover_set_blend_color; failover->pipe.set_stencil_ref = failover_set_stencil_ref; failover->pipe.set_clip_state = failover_set_clip_state; + failover->pipe.set_sample_mask = failover_set_sample_mask; failover->pipe.set_framebuffer_state = failover_set_framebuffer_state; failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; failover->pipe.set_scissor_state = failover_set_scissor_state; diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index 42bd6929a7f..147f23269ca 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -63,6 +63,9 @@ failover_state_emit( struct failover_context *failover ) if (failover->dirty & FO_NEW_CLIP) failover->sw->set_clip_state( failover->sw, &failover->clip ); + if (failover->dirty & FO_NEW_SAMPLE_MASK) + failover->sw->set_sample_mask( failover->sw, failover->sample_mask ); + if (failover->dirty & FO_NEW_DEPTH_STENCIL) failover->sw->bind_depth_stencil_alpha_state( failover->sw, failover->depth_stencil->sw_state ); diff --git a/src/gallium/drivers/i915/i915_blit.c b/src/gallium/drivers/i915/i915_blit.c index 533fa81219b..6717e46e1b4 100644 --- a/src/gallium/drivers/i915/i915_blit.c +++ b/src/gallium/drivers/i915/i915_blit.c @@ -84,7 +84,6 @@ i915_fill_blit(struct i915_context *i915, void i915_copy_blit(struct i915_context *i915, - unsigned do_flip, unsigned cpp, unsigned short src_pitch, struct i915_winsys_buffer *src_buffer, diff --git a/src/gallium/drivers/i915/i915_blit.h b/src/gallium/drivers/i915/i915_blit.h index db576ed4c90..43f8e7c9aad 100644 --- a/src/gallium/drivers/i915/i915_blit.h +++ b/src/gallium/drivers/i915/i915_blit.h @@ -31,7 +31,6 @@ #include "i915_context.h" extern void i915_copy_blit(struct i915_context *i915, - unsigned do_flip, unsigned cpp, unsigned short src_pitch, struct i915_winsys_buffer *src_buffer, diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 7cf627d975b..0897a863dbd 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -161,9 +161,10 @@ i915_get_paramf(struct pipe_screen *screen, enum pipe_cap param) static boolean i915_is_format_supported(struct pipe_screen *screen, - enum pipe_format format, + enum pipe_format format, enum pipe_texture_target target, - unsigned tex_usage, + unsigned sample_count, + unsigned tex_usage, unsigned geom_flags) { static const enum pipe_format tex_supported[] = { @@ -183,17 +184,25 @@ i915_is_format_supported(struct pipe_screen *screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_NONE /* list terminator */ }; - static const enum pipe_format surface_supported[] = { + static const enum pipe_format render_supported[] = { PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_B5G6R5_UNORM, + PIPE_FORMAT_NONE /* list terminator */ + }; + static const enum pipe_format depth_supported[] = { PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_NONE /* list terminator */ }; const enum pipe_format *list; uint i; - if(tex_usage & PIPE_BIND_RENDER_TARGET) - list = surface_supported; + if (sample_count > 1) + return FALSE; + + if(tex_usage & PIPE_BIND_DEPTH_STENCIL) + list = depth_supported; + else if (tex_usage & PIPE_BIND_RENDER_TARGET) + list = render_supported; else list = tex_supported; diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index cd963e4df75..e767aa9f8f0 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -812,6 +812,12 @@ i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) FREE( velems ); } +static void +i915_set_sample_mask(struct pipe_context *pipe, + unsigned sample_mask) +{ +} + void i915_init_state_functions( struct i915_context *i915 ) { @@ -843,6 +849,7 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.set_blend_color = i915_set_blend_color; i915->base.set_stencil_ref = i915_set_stencil_ref; i915->base.set_clip_state = i915_set_clip_state; + i915->base.set_sample_mask = i915_set_sample_mask; i915->base.set_constant_buffer = i915_set_constant_buffer; i915->base.set_framebuffer_state = i915_set_framebuffer_state; diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c index 453437b8090..41b1fed36d0 100644 --- a/src/gallium/drivers/i915/i915_surface.c +++ b/src/gallium/drivers/i915/i915_surface.c @@ -41,15 +41,41 @@ */ static void i915_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - struct pipe_surface *src, - unsigned srcx, unsigned srcy, unsigned width, unsigned height) + struct pipe_resource *dst, struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, + unsigned width, unsigned height) { - struct i915_texture *dst_tex = i915_texture(dst->texture); - struct i915_texture *src_tex = i915_texture(src->texture); + struct i915_texture *dst_tex = i915_texture(dst); + struct i915_texture *src_tex = i915_texture(src); struct pipe_resource *dpt = &dst_tex->b.b; struct pipe_resource *spt = &src_tex->b.b; + unsigned dst_offset, src_offset; /* in bytes */ + + if (dst->target == PIPE_TEXTURE_CUBE) { + dst_offset = dst_tex->image_offset[subdst.level][subdst.face]; + } + else if (dst->target == PIPE_TEXTURE_3D) { + dst_offset = dst_tex->image_offset[subdst.level][dstz]; + } + else { + dst_offset = dst_tex->image_offset[subdst.level][0]; + assert(subdst.face == 0); + assert(dstz == 0); + } + if (src->target == PIPE_TEXTURE_CUBE) { + src_offset = src_tex->image_offset[subsrc.level][subsrc.face]; + } + else if (src->target == PIPE_TEXTURE_3D) { + src_offset = src_tex->image_offset[subsrc.level][srcz]; + } + else { + src_offset = src_tex->image_offset[subsrc.level][0]; + assert(subsrc.face == 0); + assert(srcz == 0); + } + assert( dst != src ); assert( util_format_get_blocksize(dpt->format) == util_format_get_blocksize(spt->format) ); @@ -59,22 +85,34 @@ i915_surface_copy(struct pipe_context *pipe, assert( util_format_get_blockheight(dpt->format) == 1 ); i915_copy_blit( i915_context(pipe), - FALSE, util_format_get_blocksize(dpt->format), - (unsigned short) src_tex->stride, src_tex->buffer, src->offset, - (unsigned short) dst_tex->stride, dst_tex->buffer, dst->offset, + (unsigned short) src_tex->stride, src_tex->buffer, src_offset, + (unsigned short) dst_tex->stride, dst_tex->buffer, dst_offset, (short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height ); } static void i915_surface_fill(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, + struct pipe_resource *dst, struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, unsigned width, unsigned height, unsigned value) { - struct i915_texture *tex = i915_texture(dst->texture); + struct i915_texture *tex = i915_texture(dst); struct pipe_resource *pt = &tex->b.b; + unsigned dst_offset; /* in bytes */ + + if (dst->target == PIPE_TEXTURE_CUBE) { + dst_offset = tex->image_offset[subdst.level][subdst.face]; + } + else if (dst->target == PIPE_TEXTURE_3D) { + dst_offset = tex->image_offset[subdst.level][dstz]; + } + else { + dst_offset = tex->image_offset[subdst.level][0]; + assert(subdst.face == 0); + assert(dstz == 0); + } assert(util_format_get_blockwidth(pt->format) == 1); assert(util_format_get_blockheight(pt->format) == 1); @@ -82,7 +120,7 @@ i915_surface_fill(struct pipe_context *pipe, i915_fill_blit( i915_context(pipe), util_format_get_blocksize(pt->format), (unsigned short) tex->stride, - tex->buffer, dst->offset, + tex->buffer, dst_offset, (short) dstx, (short) dsty, (short) width, (short) height, value ); @@ -137,13 +175,11 @@ i915_tex_surface_destroy(struct pipe_surface *surf) } -/* Probably going to make blits work on textures rather than surfaces. - */ void i915_init_surface_functions(struct i915_context *i915) { - i915->base.surface_copy = i915_surface_copy; - i915->base.surface_fill = i915_surface_fill; + i915->base.resource_copy_region = i915_surface_copy; + i915->base.resource_fill_region = i915_surface_fill; } /* No good reason for these to be in the screen. diff --git a/src/gallium/drivers/i965/brw_pipe_depth.c b/src/gallium/drivers/i965/brw_pipe_depth.c index b7000d5e334..31c2c343d89 100644 --- a/src/gallium/drivers/i965/brw_pipe_depth.c +++ b/src/gallium/drivers/i965/brw_pipe_depth.c @@ -167,12 +167,19 @@ static void brw_set_stencil_ref(struct pipe_context *pipe, brw->state.dirty.mesa |= PIPE_NEW_DEPTH_STENCIL_ALPHA; } +static void +brw_set_sample_mask(struct pipe_context *pipe, + unsigned sample_mask) +{ +} + void brw_pipe_depth_stencil_init( struct brw_context *brw ) { brw->base.set_stencil_ref = brw_set_stencil_ref; brw->base.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; brw->base.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; brw->base.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; + brw->base.set_sample_mask = brw_set_sample_mask; } void brw_pipe_depth_stencil_cleanup( struct brw_context *brw ) diff --git a/src/gallium/drivers/i965/brw_resource.c b/src/gallium/drivers/i965/brw_resource.c index 069a12b27f7..1efdb1e0b4d 100644 --- a/src/gallium/drivers/i965/brw_resource.c +++ b/src/gallium/drivers/i965/brw_resource.c @@ -1,4 +1,5 @@ #include "util/u_debug.h" +#include "util/u_surface.h" #include "brw_resource.h" #include "brw_context.h" @@ -37,6 +38,8 @@ brw_init_resource_functions(struct brw_context *brw ) brw->base.transfer_unmap = u_transfer_unmap_vtbl; brw->base.transfer_destroy = u_transfer_destroy_vtbl; brw->base.transfer_inline_write = u_transfer_inline_write_vtbl; + brw->base.resource_copy_region = util_resource_copy_region; + brw->base.resource_fill_region = util_resource_fill_region; } void diff --git a/src/gallium/drivers/i965/brw_resource.h b/src/gallium/drivers/i965/brw_resource.h index 3390c270d42..78defb37b2a 100644 --- a/src/gallium/drivers/i965/brw_resource.h +++ b/src/gallium/drivers/i965/brw_resource.h @@ -124,7 +124,8 @@ boolean brw_is_format_supported( struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, - unsigned tex_usage, + unsigned sample_count, + unsigned tex_usage, unsigned geom_flags ); */ diff --git a/src/gallium/drivers/i965/brw_resource_texture.c b/src/gallium/drivers/i965/brw_resource_texture.c index ca09d88fd12..ffd0f38672c 100644 --- a/src/gallium/drivers/i965/brw_resource_texture.c +++ b/src/gallium/drivers/i965/brw_resource_texture.c @@ -594,7 +594,8 @@ fail: boolean brw_is_format_supported( struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, - unsigned tex_usage, + unsigned sample_count, + unsigned tex_usage, unsigned geom_flags ) { return translate_tex_format(format) != BRW_SURFACEFORMAT_INVALID; diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c index 1890b640e90..7a7b9c1a5a9 100644 --- a/src/gallium/drivers/i965/brw_screen.c +++ b/src/gallium/drivers/i965/brw_screen.c @@ -220,9 +220,10 @@ brw_get_paramf(struct pipe_screen *screen, enum pipe_cap param) static boolean brw_is_format_supported(struct pipe_screen *screen, - enum pipe_format format, + enum pipe_format format, enum pipe_texture_target target, - unsigned tex_usage, + unsigned sample_count, + unsigned tex_usage, unsigned geom_flags) { static const enum pipe_format tex_supported[] = { @@ -278,6 +279,9 @@ brw_is_format_supported(struct pipe_screen *screen, const enum pipe_format *list; uint i; + if (sample_count > 1) + return FALSE; + if (tex_usage & PIPE_BIND_DEPTH_STENCIL) list = depth_supported; else if (tex_usage & PIPE_BIND_RENDER_TARGET) diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index 7e62213597c..9813170fb18 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -452,6 +452,17 @@ identity_set_clip_state(struct pipe_context *_pipe, } static void +identity_set_sample_mask(struct pipe_context *_pipe, + unsigned sample_mask) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_sample_mask(pipe, + sample_mask); +} + +static void identity_set_constant_buffer(struct pipe_context *_pipe, uint shader, uint index, @@ -601,55 +612,67 @@ identity_set_vertex_buffers(struct pipe_context *_pipe, buffers); } static void -identity_surface_copy(struct pipe_context *_pipe, - struct pipe_surface *_dst, - unsigned dstx, - unsigned dsty, - struct pipe_surface *_src, - unsigned srcx, - unsigned srcy, - unsigned width, - unsigned height) +identity_resource_copy_region(struct pipe_context *_pipe, + struct pipe_resource *_dst, + struct pipe_subresource subdst, + unsigned dstx, + unsigned dsty, + unsigned dstz, + struct pipe_resource *_src, + struct pipe_subresource subsrc, + unsigned srcx, + unsigned srcy, + unsigned srcz, + unsigned width, + unsigned height) { struct identity_context *id_pipe = identity_context(_pipe); - struct identity_surface *id_surface_dst = identity_surface(_dst); - struct identity_surface *id_surface_src = identity_surface(_src); + struct identity_resource *id_resource_dst = identity_resource(_dst); + struct identity_resource *id_resource_src = identity_resource(_src); struct pipe_context *pipe = id_pipe->pipe; - struct pipe_surface *dst = id_surface_dst->surface; - struct pipe_surface *src = id_surface_src->surface; + struct pipe_resource *dst = id_resource_dst->resource; + struct pipe_resource *src = id_resource_src->resource; - pipe->surface_copy(pipe, - dst, - dstx, - dsty, - src, - srcx, - srcy, - width, - height); + pipe->resource_copy_region(pipe, + dst, + subdst, + dstx, + dsty, + dstz, + src, + subsrc, + srcx, + srcy, + srcz, + width, + height); } static void -identity_surface_fill(struct pipe_context *_pipe, - struct pipe_surface *_dst, - unsigned dstx, - unsigned dsty, - unsigned width, - unsigned height, - unsigned value) +identity_resource_fill_region(struct pipe_context *_pipe, + struct pipe_resource *_dst, + struct pipe_subresource subdst, + unsigned dstx, + unsigned dsty, + unsigned dstz, + unsigned width, + unsigned height, + unsigned value) { struct identity_context *id_pipe = identity_context(_pipe); - struct identity_surface *id_surface_dst = identity_surface(_dst); + struct identity_resource *id_resource_dst = identity_resource(_dst); struct pipe_context *pipe = id_pipe->pipe; - struct pipe_surface *dst = id_surface_dst->surface; + struct pipe_resource *dst = id_resource_dst->resource; - pipe->surface_fill(pipe, - dst, - dstx, - dsty, - width, - height, - value); + pipe->resource_fill_region(pipe, + dst, + subdst, + dstx, + dsty, + dstz, + width, + height, + value); } static void @@ -880,6 +903,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.set_blend_color = identity_set_blend_color; id_pipe->base.set_stencil_ref = identity_set_stencil_ref; id_pipe->base.set_clip_state = identity_set_clip_state; + id_pipe->base.set_sample_mask = identity_set_sample_mask; id_pipe->base.set_constant_buffer = identity_set_constant_buffer; id_pipe->base.set_framebuffer_state = identity_set_framebuffer_state; id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple; @@ -888,8 +912,8 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views; id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views; id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers; - id_pipe->base.surface_copy = identity_surface_copy; - id_pipe->base.surface_fill = identity_surface_fill; + id_pipe->base.resource_copy_region = identity_resource_copy_region; + id_pipe->base.resource_fill_region = identity_resource_fill_region; id_pipe->base.clear = identity_clear; id_pipe->base.flush = identity_flush; id_pipe->base.is_resource_referenced = identity_is_resource_referenced; diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c index 3c94e04a7a8..f71585e06f8 100644 --- a/src/gallium/drivers/identity/id_screen.c +++ b/src/gallium/drivers/identity/id_screen.c @@ -91,6 +91,7 @@ static boolean identity_screen_is_format_supported(struct pipe_screen *_screen, enum pipe_format format, enum pipe_texture_target target, + unsigned sample_count, unsigned tex_usage, unsigned geom_flags) { @@ -100,6 +101,7 @@ identity_screen_is_format_supported(struct pipe_screen *_screen, return screen->is_format_supported(screen, format, target, + sample_count, tex_usage, geom_flags); } diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 22fbf381ae0..cedc08e9292 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -204,8 +204,9 @@ llvmpipe_get_paramf(struct pipe_screen *screen, enum pipe_cap param) */ static boolean llvmpipe_is_format_supported( struct pipe_screen *_screen, - enum pipe_format format, + enum pipe_format format, enum pipe_texture_target target, + unsigned sample_count, unsigned bind, unsigned geom_flags ) { @@ -222,6 +223,9 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, target == PIPE_TEXTURE_3D || target == PIPE_TEXTURE_CUBE); + if (sample_count > 1) + return FALSE; + if (bind & PIPE_BIND_RENDER_TARGET) { if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) return FALSE; diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c index 8569507f4e5..5b39d9d1a91 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c @@ -148,6 +148,11 @@ llvmpipe_set_stencil_ref(struct pipe_context *pipe, llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA; } +static void +llvmpipe_set_sample_mask(struct pipe_context *pipe, + unsigned sample_mask) +{ +} void llvmpipe_init_blend_funcs(struct llvmpipe_context *llvmpipe) @@ -163,4 +168,5 @@ llvmpipe_init_blend_funcs(struct llvmpipe_context *llvmpipe) llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color; llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref; + llvmpipe->pipe.set_sample_mask = llvmpipe_set_sample_mask; } diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index 245171120dd..85687ada1c4 100644 --- a/src/gallium/drivers/llvmpipe/lp_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -51,24 +51,27 @@ adjust_to_tile_bounds(unsigned x, unsigned y, unsigned width, unsigned height, static void -lp_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dst, unsigned dstx, unsigned dsty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, - unsigned width, unsigned height) +lp_resource_copy(struct pipe_context *pipe, + struct pipe_resource *dst, struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, + unsigned width, unsigned height) { - struct llvmpipe_resource *src_tex = llvmpipe_resource(src->texture); - struct llvmpipe_resource *dst_tex = llvmpipe_resource(dst->texture); + /* XXX what about the dstz/srcz parameters - zslice wasn't used... */ + struct llvmpipe_resource *src_tex = llvmpipe_resource(src); + struct llvmpipe_resource *dst_tex = llvmpipe_resource(dst); const enum pipe_format format = src_tex->base.format; llvmpipe_flush_resource(pipe, - dst->texture, dst->face, dst->level, + dst, subdst.face, subdst.level, 0, /* flush_flags */ FALSE, /* read_only */ FALSE, /* cpu_access */ FALSE); /* do_not_block */ llvmpipe_flush_resource(pipe, - src->texture, src->face, src->level, + src, subsrc.face, subsrc.level, 0, /* flush_flags */ TRUE, /* read_only */ FALSE, /* cpu_access */ @@ -90,8 +93,8 @@ lp_surface_copy(struct pipe_context *pipe, for (y = 0; y < th; y += TILE_SIZE) { for (x = 0; x < tw; x += TILE_SIZE) { (void) llvmpipe_get_texture_tile_linear(src_tex, - src->face, src->level, - LP_TEX_USAGE_READ, + subsrc.face, subsrc.level, + LP_TEX_USAGE_READ, tx + x, ty + y); } } @@ -117,7 +120,7 @@ lp_surface_copy(struct pipe_context *pipe, for (y = 0; y < th; y += TILE_SIZE) { for (x = 0; x < tw; x += TILE_SIZE) { (void) llvmpipe_get_texture_tile_linear(dst_tex, - dst->face, dst->level, + subdst.face, subdst.level, usage, tx + x, ty + y); } @@ -127,20 +130,20 @@ lp_surface_copy(struct pipe_context *pipe, /* copy */ { const ubyte *src_linear_ptr - = llvmpipe_get_texture_image_address(src_tex, src->face, - src->level, + = llvmpipe_get_texture_image_address(src_tex, subsrc.face, + subsrc.level, LP_TEX_LAYOUT_LINEAR); ubyte *dst_linear_ptr - = llvmpipe_get_texture_image_address(dst_tex, dst->face, - dst->level, + = llvmpipe_get_texture_image_address(dst_tex, subdst.face, + subdst.level, LP_TEX_LAYOUT_LINEAR); util_copy_rect(dst_linear_ptr, format, - llvmpipe_resource_stride(&dst_tex->base, dst->level), + llvmpipe_resource_stride(&dst_tex->base, subdst.level), dstx, dsty, width, height, src_linear_ptr, - llvmpipe_resource_stride(&src_tex->base, src->level), + llvmpipe_resource_stride(&src_tex->base, subsrc.level), srcx, srcy); } } @@ -149,6 +152,6 @@ lp_surface_copy(struct pipe_context *pipe, void llvmpipe_init_surface_functions(struct llvmpipe_context *lp) { - lp->pipe.surface_copy = lp_surface_copy; - lp->pipe.surface_fill = util_surface_fill; + lp->pipe.resource_copy_region = lp_resource_copy; + lp->pipe.resource_fill_region = util_resource_fill_region; } diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index a91b00b5ada..60bdd7276aa 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -52,8 +52,6 @@ nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment, if (bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL | - PIPE_BIND_BLIT_SOURCE | - PIPE_BIND_BLIT_DESTINATION | PIPE_BIND_SCANOUT | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SAMPLER_VIEW)) diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 757f13b640a..2c0caada366 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -33,8 +33,12 @@ static boolean nv50_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, enum pipe_texture_target target, + unsigned sample_count, unsigned tex_usage, unsigned geom_flags) { + if (sample_count > 1) + return FALSE; + if (tex_usage & PIPE_BIND_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_B8G8R8X8_UNORM: diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index b20781fa1fb..f8bff764f27 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -661,6 +661,12 @@ nv50_set_clip_state(struct pipe_context *pipe, } static void +nv50_set_sample_mask(struct pipe_context *pipe, + unsigned sample_mask) +{ +} + +static void nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct pipe_resource *buf ) { @@ -805,6 +811,7 @@ nv50_init_state_functions(struct nv50_context *nv50) nv50->pipe.set_blend_color = nv50_set_blend_color; nv50->pipe.set_stencil_ref = nv50_set_stencil_ref; nv50->pipe.set_clip_state = nv50_set_clip_state; + nv50->pipe.set_sample_mask = nv50_set_sample_mask; nv50->pipe.set_constant_buffer = nv50_set_constant_buffer; nv50->pipe.set_framebuffer_state = nv50_set_framebuffer_state; nv50->pipe.set_polygon_stipple = nv50_set_polygon_stipple; diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c index d905d95354f..40b8d255335 100644 --- a/src/gallium/drivers/nv50/nv50_surface.c +++ b/src/gallium/drivers/nv50/nv50_surface.c @@ -195,27 +195,40 @@ nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, static void nv50_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, unsigned destx, unsigned desty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, + struct pipe_resource *dest, struct pipe_subresource subdst, + unsigned destx, unsigned desty, unsigned destz, + struct pipe_resource *src, struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, unsigned width, unsigned height) { struct nv50_context *nv50 = nv50_context(pipe); struct nv50_screen *screen = nv50->screen; + struct pipe_surface *ps_dst, *ps_src; assert((src->format == dest->format) || (nv50_2d_format_faithful(src->format) && nv50_2d_format_faithful(dest->format))); - nv50_surface_do_copy(screen, dest, destx, desty, src, srcx, - srcy, width, height); + ps_src = nv50_miptree_surface_new(pipe->screen, dest, subsrc.face, + subsrc.level, srcz, 0 /* bind flags */); + ps_dst = nv50_miptree_surface_new(pipe->screen, dest, subdst.face, + subdst.level, destz, 0 /* bindflags */); + + nv50_surface_do_copy(screen, ps_dst, destx, desty, ps_src, srcx, + srcy, width, height); + + nv50_miptree_surface_del(ps_src); + nv50_miptree_surface_del(ps_dst); } static void -nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, - unsigned destx, unsigned desty, unsigned width, - unsigned height, unsigned value) +nv50_surface_fill(struct pipe_context *pipe, struct pipe_resource *dest, + struct pipe_subresource subdst, + unsigned destx, unsigned desty, unsigned destz, + unsigned width, unsigned height, unsigned value) { struct nv50_context *nv50 = nv50_context(pipe); + struct pipe_surface *ps; struct nv50_screen *screen = nv50->screen; struct nouveau_channel *chan = screen->eng2d->channel; struct nouveau_grobj *eng2d = screen->eng2d; @@ -225,9 +238,12 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, if (format < 0) return; + ps = nv50_miptree_surface_new(pipe->screen, dest, subdst.face, + subdst.level, destz, 0 /* bind flags */); + WAIT_RING (chan, 32); - ret = nv50_surface_set(screen, dest, 1); + ret = nv50_surface_set(screen, ps, 1); if (ret) return; @@ -240,13 +256,15 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, OUT_RING (chan, desty); OUT_RING (chan, width); OUT_RING (chan, height); + + nv50_miptree_surface_del(ps); } void nv50_init_surface_functions(struct nv50_context *nv50) { - nv50->pipe.surface_copy = nv50_surface_copy; - nv50->pipe.surface_fill = nv50_surface_fill; + nv50->pipe.resource_copy_region = nv50_surface_copy; + nv50->pipe.resource_fill_region = nv50_surface_fill; } diff --git a/src/gallium/drivers/nvfx/nv04_surface_2d.c b/src/gallium/drivers/nvfx/nv04_surface_2d.c index 4ed574227d6..7acbb505df3 100644 --- a/src/gallium/drivers/nvfx/nv04_surface_2d.c +++ b/src/gallium/drivers/nvfx/nv04_surface_2d.c @@ -502,12 +502,9 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, struct nv04_surface* temp_ns; int temp_flags; - temp_flags = (ns->base.usage | - PIPE_BIND_BLIT_SOURCE | - PIPE_BIND_BLIT_DESTINATION); + temp_flags = ns->base.usage; - ns->base.usage = (PIPE_BIND_BLIT_SOURCE | - PIPE_BIND_BLIT_DESTINATION); + ns->base.usage = 0; memset(&templ, 0, sizeof(templ)); templ.format = ns->base.texture->format; @@ -526,7 +523,7 @@ nv04_surface_wrap_for_render(struct pipe_screen *pscreen, temp_ns = (struct nv04_surface*)pscreen->get_tex_surface(pscreen, temp_tex, 0, 0, 0, temp_flags); temp_ns->backing = ns; - if(ns->base.usage & PIPE_BIND_BLIT_SOURCE) + if(1) /* hmm */ eng2d->copy(eng2d, &temp_ns->backing->base, 0, 0, &ns->base, 0, 0, ns->base.width, ns->base.height); diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c index aeb88e9ac96..b5639bb4645 100644 --- a/src/gallium/drivers/nvfx/nvfx_miptree.c +++ b/src/gallium/drivers/nvfx/nvfx_miptree.c @@ -300,7 +300,7 @@ nvfx_miptree_surface_del(struct pipe_surface *ps) if(ns->backing) { struct nvfx_screen* screen = (struct nvfx_screen*)ps->texture->screen; - if(ns->backing->base.usage & PIPE_BIND_BLIT_DESTINATION) + if(1 /*ns->backing->base.usage & PIPE_BIND_BLIT_DESTINATION*/) screen->eng2d->copy(screen->eng2d, &ns->backing->base, 0, 0, ps, 0, 0, ns->base.width, ns->base.height); nvfx_miptree_surface_del(&ns->backing->base); } diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 6cb8428e4b6..7e534a0c738 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -157,11 +157,15 @@ static boolean nvfx_screen_surface_format_supported(struct pipe_screen *pscreen, enum pipe_format format, enum pipe_texture_target target, + unsigned sample_count, unsigned tex_usage, unsigned geom_flags) { struct nvfx_screen *screen = nvfx_screen(pscreen); struct pipe_surface *front = ((struct nouveau_winsys *) pscreen->winsys)->front; + if (sample_count > 1) + return FALSE; + if (tex_usage & PIPE_BIND_RENDER_TARGET) { switch (format) { case PIPE_FORMAT_B8G8R8A8_UNORM: diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c index 17f3f701406..30322d46d93 100644 --- a/src/gallium/drivers/nvfx/nvfx_state.c +++ b/src/gallium/drivers/nvfx/nvfx_state.c @@ -479,6 +479,12 @@ nvfx_set_clip_state(struct pipe_context *pipe, } static void +nvfx_set_sample_mask(struct pipe_context *pipe, + unsigned sample_mask) +{ +} + +static void nvfx_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, struct pipe_resource *buf ) { @@ -617,6 +623,7 @@ nvfx_init_state_functions(struct nvfx_context *nvfx) nvfx->pipe.set_blend_color = nvfx_set_blend_color; nvfx->pipe.set_stencil_ref = nvfx_set_stencil_ref; nvfx->pipe.set_clip_state = nvfx_set_clip_state; + nvfx->pipe.set_sample_mask = nvfx_set_sample_mask; nvfx->pipe.set_constant_buffer = nvfx_set_constant_buffer; nvfx->pipe.set_framebuffer_state = nvfx_set_framebuffer_state; nvfx->pipe.set_polygon_stipple = nvfx_set_polygon_stipple; diff --git a/src/gallium/drivers/nvfx/nvfx_surface.c b/src/gallium/drivers/nvfx/nvfx_surface.c index 2e115650aeb..fc3a670d400 100644 --- a/src/gallium/drivers/nvfx/nvfx_surface.c +++ b/src/gallium/drivers/nvfx/nvfx_surface.c @@ -27,35 +27,54 @@ **************************************************************************/ #include "nvfx_context.h" +#include "nvfx_resource.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" static void nvfx_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, unsigned destx, unsigned desty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, + struct pipe_resource *dest, struct pipe_subresource subdst, + unsigned destx, unsigned desty, unsigned destz, + struct pipe_resource *src, struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, unsigned width, unsigned height) { struct nvfx_context *nvfx = nvfx_context(pipe); struct nv04_surface_2d *eng2d = nvfx->screen->eng2d; + struct pipe_surface *ps_dst, *ps_src; - eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); + ps_src = nvfx_miptree_surface_new(pipe->screen, dest, subsrc.face, + subsrc.level, srcz, 0 /* bind flags */); + ps_dst = nvfx_miptree_surface_new(pipe->screen, dest, subdst.face, + subdst.level, destz, 0 /* bindflags */); + + eng2d->copy(eng2d, ps_dst, destx, desty, ps_src, srcx, srcy, width, height); + + nvfx_miptree_surface_del(ps_src); + nvfx_miptree_surface_del(ps_dst); } static void -nvfx_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest, - unsigned destx, unsigned desty, unsigned width, - unsigned height, unsigned value) +nvfx_surface_fill(struct pipe_context *pipe, struct pipe_resource *dest, + struct pipe_subresource subdst, + unsigned destx, unsigned desty, unsigned destz, + unsigned width, unsigned height, unsigned value) { struct nvfx_context *nvfx = nvfx_context(pipe); + struct pipe_surface *ps; struct nv04_surface_2d *eng2d = nvfx->screen->eng2d; - eng2d->fill(eng2d, dest, destx, desty, width, height, value); + ps = nvfx_miptree_surface_new(pipe->screen, dest, subdst.face, + subdst.level, destz, 0 /* bind flags */); + + eng2d->fill(eng2d, ps, destx, desty, width, height, value); + + nvfx_miptree_surface_del(ps); } void nvfx_init_surface_functions(struct nvfx_context *nvfx) { - nvfx->pipe.surface_copy = nvfx_surface_copy; - nvfx->pipe.surface_fill = nvfx_surface_fill; + nvfx->pipe.resource_copy_region = nvfx_surface_copy; + nvfx->pipe.resource_fill_region = nvfx_surface_fill; } diff --git a/src/gallium/drivers/nvfx/nvfx_transfer.c b/src/gallium/drivers/nvfx/nvfx_transfer.c index b2ef27cf579..9ff0a93d307 100644 --- a/src/gallium/drivers/nvfx/nvfx_transfer.c +++ b/src/gallium/drivers/nvfx/nvfx_transfer.c @@ -40,11 +40,13 @@ static unsigned nvfx_transfer_bind_flags( unsigned transfer_usage ) { unsigned bind = 0; +#if 0 if (transfer_usage & PIPE_TRANSFER_WRITE) bind |= PIPE_BIND_BLIT_SOURCE; if (transfer_usage & PIPE_TRANSFER_READ) bind |= PIPE_BIND_BLIT_DESTINATION; +#endif return bind; } @@ -128,7 +130,7 @@ nvfx_miptree_transfer_new(struct pipe_context *pipe, src = pscreen->get_tex_surface(pscreen, pt, sr.face, sr.level, box->z, - PIPE_BIND_BLIT_SOURCE); + 0 /*PIPE_BIND_BLIT_SOURCE*/); /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ /* TODO: Check if SIFM can un-swizzle */ @@ -160,7 +162,7 @@ nvfx_miptree_transfer_del(struct pipe_context *pipe, ptx->sr.face, ptx->sr.level, ptx->box.z, - PIPE_BIND_BLIT_DESTINATION); + 0 /*PIPE_BIND_BLIT_DESTINATION*/); /* TODO: Check if SIFM can deal with x,y,w,h when swizzling */ nvscreen->eng2d->copy(nvscreen->eng2d, diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 85c2c149016..2bf9317803e 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -117,25 +117,36 @@ static void r300_hw_copy(struct pipe_context* pipe, /* Copy a block of pixels from one surface to another. */ void r300_surface_copy(struct pipe_context* pipe, - struct pipe_surface* dst, - unsigned dstx, unsigned dsty, - struct pipe_surface* src, - unsigned srcx, unsigned srcy, + struct pipe_resource* dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource* src, + struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, unsigned width, unsigned height) { - enum pipe_format old_format = dst->texture->format; + struct pipe_screen *screen = pipe->screen; + enum pipe_format old_format = dst->format; enum pipe_format new_format = old_format; + struct pipe_surface *srcsurf, *dstsurf; + unsigned bind; - if (dst->texture->format != src->texture->format) { + if (util_format_is_depth_or_stencil(dst->format)) + bind = PIPE_BIND_DEPTH_STENCIL; + else + bind = PIPE_BIND_RENDER_TARGET; + + if (dst->format != src->format) { debug_printf("r300: Implementation error: Format mismatch in %s\n" " : src: %s dst: %s\n", __FUNCTION__, - util_format_short_name(src->texture->format), - util_format_short_name(dst->texture->format)); + util_format_short_name(src->format), + util_format_short_name(dst->format)); debug_assert(0); } if (!pipe->screen->is_format_supported(pipe->screen, - old_format, src->texture->target, + old_format, src->target, + src->nr_samples, PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW, 0) && util_format_is_plain(old_format)) { @@ -164,36 +175,64 @@ void r300_surface_copy(struct pipe_context* pipe, src->format = new_format; r300_texture_reinterpret_format(pipe->screen, - dst->texture, new_format); + dst, new_format); r300_texture_reinterpret_format(pipe->screen, - src->texture, new_format); + src, new_format); } - r300_hw_copy(pipe, dst, dstx, dsty, src, srcx, srcy, width, height); + srcsurf = screen->get_tex_surface(screen, src, + subsrc.face, subsrc.level, srcz, + PIPE_BIND_SAMPLER_VIEW); + + dstsurf = screen->get_tex_surface(screen, dst, + subdst.face, subdst.level, dstz, + bind); + + r300_hw_copy(pipe, dstsurf, dstx, dsty, srcsurf, srcx, srcy, width, height); + + pipe_surface_reference(&srcsurf, NULL); + pipe_surface_reference(&dstsurf, NULL); if (old_format != new_format) { dst->format = old_format; src->format = old_format; r300_texture_reinterpret_format(pipe->screen, - dst->texture, old_format); + dst, old_format); r300_texture_reinterpret_format(pipe->screen, - src->texture, old_format); + src, old_format); } } /* Fill a region of a surface with a constant value. */ void r300_surface_fill(struct pipe_context* pipe, - struct pipe_surface* dst, - unsigned dstx, unsigned dsty, + struct pipe_resource* dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, unsigned width, unsigned height, unsigned value) { + struct pipe_screen *screen = pipe->screen; struct r300_context* r300 = r300_context(pipe); + struct pipe_surface *dstsurf; + unsigned bind; + + if (util_format_is_depth_or_stencil(dst->format)) + bind = PIPE_BIND_DEPTH_STENCIL; + else + bind = PIPE_BIND_RENDER_TARGET; + + dstsurf = screen->get_tex_surface(screen, dst, + subdst.face, + subdst.level, + dstz, + bind); r300_blitter_save_states(r300); util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); util_blitter_fill(r300->blitter, - dst, dstx, dsty, width, height, value); + dstsurf, dstx, dsty, width, height, value); + + pipe_surface_reference(&dstsurf, NULL); } diff --git a/src/gallium/drivers/r300/r300_blit.h b/src/gallium/drivers/r300/r300_blit.h index 029e4f98e7d..c97872662aa 100644 --- a/src/gallium/drivers/r300/r300_blit.h +++ b/src/gallium/drivers/r300/r300_blit.h @@ -24,7 +24,8 @@ #define R300_BLIT_H struct pipe_context; -struct pipe_surface; +struct pipe_resource; +struct pipe_subresource; void r300_clear(struct pipe_context* pipe, unsigned buffers, @@ -33,15 +34,18 @@ void r300_clear(struct pipe_context* pipe, unsigned stencil); void r300_surface_copy(struct pipe_context* pipe, - struct pipe_surface* dst, - unsigned dstx, unsigned dsty, - struct pipe_surface* src, - unsigned srcx, unsigned srcy, + struct pipe_resource* dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource* src, + struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, unsigned width, unsigned height); void r300_surface_fill(struct pipe_context* pipe, - struct pipe_surface* dst, - unsigned dstx, unsigned dsty, + struct pipe_resource* dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, unsigned width, unsigned height, unsigned value); diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 9837deaa5e3..f771e10c64e 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -186,8 +186,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->context.destroy = r300_destroy_context; r300->context.clear = r300_clear; - r300->context.surface_copy = r300_surface_copy; - r300->context.surface_fill = r300_surface_fill; + r300->context.resource_copy_region = r300_surface_copy; + r300->context.resource_fill_region = r300_surface_fill; if (r300screen->caps.has_tcl) { r300->context.draw_arrays = r300_draw_arrays; diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 640b3d34688..ef0255066b7 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -241,6 +241,7 @@ static float r300_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param) static boolean r300_is_format_supported(struct pipe_screen* screen, enum pipe_format format, enum pipe_texture_target target, + unsigned sample_count, unsigned usage, unsigned geom_flags) { @@ -264,6 +265,9 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, return FALSE; } + if (sample_count > 1) + return FALSE; + /* Check sampler format support. */ if ((usage & PIPE_BIND_SAMPLER_VIEW) && /* Z24 cannot be sampled from on non-r5xx. */ diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 11c10e2f2a8..67e09362d8e 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -404,6 +404,13 @@ static void r300_set_clip_state(struct pipe_context* pipe, } } +static void +r300_set_sample_mask(struct pipe_context *pipe, + unsigned sample_mask) +{ +} + + /* Create a new depth, stencil, and alpha state based on the CSO dsa state. * * This contains the depth buffer, stencil buffer, alpha test, and such. @@ -1561,6 +1568,7 @@ void r300_init_state_functions(struct r300_context* r300) r300->context.set_blend_color = r300_set_blend_color; r300->context.set_clip_state = r300_set_clip_state; + r300->context.set_sample_mask = r300_set_sample_mask; r300->context.set_constant_buffer = r300_set_constant_buffer; diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index 14a9bfd8650..beb321cb238 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -56,63 +56,44 @@ r300_transfer(struct pipe_transfer* transfer) static void r300_copy_from_tiled_texture(struct pipe_context *ctx, struct r300_transfer *r300transfer) { - struct pipe_screen *screen = ctx->screen; struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer; struct pipe_resource *tex = transfer->resource; - struct pipe_surface *src, *dst; + struct pipe_subresource subdst; - src = screen->get_tex_surface(screen, tex, - transfer->sr.face, - transfer->sr.level, - transfer->box.z, - PIPE_BIND_BLIT_SOURCE); + subdst.face = 0; + subdst.level = 0; - dst = screen->get_tex_surface(screen, &r300transfer->detiled_texture->b.b, - 0, 0, 0, - PIPE_BIND_BLIT_DESTINATION); - - ctx->surface_copy(ctx, dst, 0, 0, src, - transfer->box.x, transfer->box.y, - transfer->box.width, transfer->box.height); - - pipe_surface_reference(&src, NULL); - pipe_surface_reference(&dst, NULL); + ctx->resource_copy_region(ctx, &r300transfer->detiled_texture->b.b, subdst, + 0, 0, 0, + tex, transfer->sr, + transfer->box.x, transfer->box.y, transfer->box.z, + transfer->box.width, transfer->box.height); } /* Copy a detiled texture to a tiled one. */ static void r300_copy_into_tiled_texture(struct pipe_context *ctx, struct r300_transfer *r300transfer) { - struct pipe_screen *screen = ctx->screen; struct pipe_transfer *transfer = (struct pipe_transfer*)r300transfer; struct pipe_resource *tex = transfer->resource; - struct pipe_surface *src, *dst; + struct pipe_subresource subsrc; - src = screen->get_tex_surface(screen, &r300transfer->detiled_texture->b.b, - 0, 0, 0, - PIPE_BIND_BLIT_SOURCE); - - dst = screen->get_tex_surface(screen, tex, - transfer->sr.face, - transfer->sr.level, - transfer->box.z, - PIPE_BIND_BLIT_DESTINATION); + subsrc.face = 0; + subsrc.level = 0; /* XXX this flush prevents the following DRM error from occuring: * [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation ! * Reproducible with perf/copytex. */ ctx->flush(ctx, 0, NULL); - ctx->surface_copy(ctx, dst, - transfer->box.x, transfer->box.y, - src, 0, 0, - transfer->box.width, transfer->box.height); + ctx->resource_copy_region(ctx, tex, transfer->sr, + transfer->box.x, transfer->box.y, transfer->box.z, + &r300transfer->detiled_texture->b.b, subsrc, + 0, 0, 0, + transfer->box.width, transfer->box.height); /* XXX this flush fixes a few piglit tests (e.g. glean/pixelFormats). */ ctx->flush(ctx, 0, NULL); - - pipe_surface_reference(&src, NULL); - pipe_surface_reference(&dst, NULL); } struct pipe_transfer* diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index fea3520fa56..2f10b46e989 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -254,6 +254,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.set_blend_color = softpipe_set_blend_color; softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref; softpipe->pipe.set_clip_state = softpipe_set_clip_state; + softpipe->pipe.set_sample_mask = softpipe_set_sample_mask; softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple; diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 8c33efa1987..73987c913e5 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -178,8 +178,9 @@ softpipe_get_paramf(struct pipe_screen *screen, enum pipe_cap param) */ static boolean softpipe_is_format_supported( struct pipe_screen *screen, - enum pipe_format format, + enum pipe_format format, enum pipe_texture_target target, + unsigned sample_count, unsigned bind, unsigned geom_flags ) { @@ -195,6 +196,9 @@ softpipe_is_format_supported( struct pipe_screen *screen, if (!format_desc) return FALSE; + if (sample_count > 1) + return FALSE; + if (bind & (PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED)) { diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index f97fc6eca8f..5b0faabeaef 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -148,6 +148,9 @@ void softpipe_set_stencil_ref( struct pipe_context *pipe, void softpipe_set_clip_state( struct pipe_context *, const struct pipe_clip_state * ); +void softpipe_set_sample_mask( struct pipe_context *, + unsigned sample_mask ); + void softpipe_set_constant_buffer(struct pipe_context *, uint shader, uint index, struct pipe_resource *buf); diff --git a/src/gallium/drivers/softpipe/sp_state_blend.c b/src/gallium/drivers/softpipe/sp_state_blend.c index c63a49e90b0..2a203f44e50 100644 --- a/src/gallium/drivers/softpipe/sp_state_blend.c +++ b/src/gallium/drivers/softpipe/sp_state_blend.c @@ -111,3 +111,10 @@ void softpipe_set_stencil_ref( struct pipe_context *pipe, softpipe->dirty |= SP_NEW_DEPTH_STENCIL_ALPHA; } + +void +softpipe_set_sample_mask(struct pipe_context *pipe, + unsigned sample_mask) +{ +} + diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c index 32cab06004f..0296c26ad26 100644 --- a/src/gallium/drivers/softpipe/sp_surface.c +++ b/src/gallium/drivers/softpipe/sp_surface.c @@ -29,22 +29,9 @@ #include "sp_context.h" #include "sp_surface.h" - -static void -sp_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, unsigned destx, unsigned desty, - struct pipe_surface *src, unsigned srcx, unsigned srcy, - unsigned width, unsigned height) -{ - util_surface_copy(pipe, FALSE, - dest, destx, desty, - src, srcx, srcy, - width, height); -} - void sp_init_surface_functions(struct softpipe_context *sp) { - sp->pipe.surface_copy = sp_surface_copy; - sp->pipe.surface_fill = util_surface_fill; + sp->pipe.resource_copy_region = util_resource_copy_region; + sp->pipe.resource_fill_region = util_resource_fill_region; } diff --git a/src/gallium/drivers/svga/svga_pipe_blit.c b/src/gallium/drivers/svga/svga_pipe_blit.c index 889da29e28b..2dd99b46316 100644 --- a/src/gallium/drivers/svga/svga_pipe_blit.c +++ b/src/gallium/drivers/svga/svga_pipe_blit.c @@ -28,33 +28,47 @@ #include "svga_debug.h" #include "svga_cmd.h" #include "svga_surface.h" +#include "util/u_surface.h" #define FILE_DEBUG_FLAG DEBUG_BLIT +/* XXX I got my doubts about this, should maybe use svga_texture_copy_handle directly? */ static void svga_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dest, - unsigned destx, unsigned desty, - struct pipe_surface *src, - unsigned srcx, unsigned srcy, + struct pipe_resource* dst_tex, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource* src_tex, + struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, unsigned width, unsigned height) { struct svga_context *svga = svga_context(pipe); + struct pipe_screen *screen = pipe->screen; SVGA3dCopyBox *box; enum pipe_error ret; + struct pipe_surface *srcsurf, *dstsurf; svga_hwtnl_flush_retry( svga ); + srcsurf = screen->get_tex_surface(screen, src_tex, + subsrc.face, subsrc.level, srcz, + PIPE_BIND_SAMPLER_VIEW); + + dstsurf = screen->get_tex_surface(screen, dst_tex, + subdst.face, subdst.level, dstz, + PIPE_BIND_RENDER_TARGET); + SVGA_DBG(DEBUG_DMA, "blit to sid %p (%d,%d), from sid %p (%d,%d) sz %dx%d\n", - svga_surface(dest)->handle, - destx, desty, - svga_surface(src)->handle, + svga_surface(dstsurf)->handle, + dstx, dsty, + svga_surface(srcsurf)->handle, srcx, srcy, width, height); ret = SVGA3D_BeginSurfaceCopy(svga->swc, - src, - dest, + srcsurf, + dstsurf, &box, 1); if(ret != PIPE_OK) { @@ -62,15 +76,15 @@ static void svga_surface_copy(struct pipe_context *pipe, svga_context_flush(svga, NULL); ret = SVGA3D_BeginSurfaceCopy(svga->swc, - src, - dest, + srcsurf, + dstsurf, &box, 1); assert(ret == PIPE_OK); } - box->x = destx; - box->y = desty; + box->x = dstx; + box->y = dsty; box->z = 0; box->w = width; box->h = height; @@ -81,13 +95,18 @@ static void svga_surface_copy(struct pipe_context *pipe, SVGA_FIFOCommitAll(svga->swc); - svga_surface(dest)->dirty = TRUE; - svga_propagate_surface(pipe, dest); + svga_surface(dstsurf)->dirty = TRUE; + svga_propagate_surface(pipe, dstsurf); + + pipe_surface_reference(&srcsurf, NULL); + pipe_surface_reference(&dstsurf, NULL); + } void svga_init_blit_functions(struct svga_context *svga) { - svga->pipe.surface_copy = svga_surface_copy; + svga->pipe.resource_copy_region = svga_surface_copy; + svga->pipe.resource_fill_region = util_resource_fill_region; } diff --git a/src/gallium/drivers/svga/svga_pipe_depthstencil.c b/src/gallium/drivers/svga/svga_pipe_depthstencil.c index c317bec6d57..c84615a1f3b 100644 --- a/src/gallium/drivers/svga/svga_pipe_depthstencil.c +++ b/src/gallium/drivers/svga/svga_pipe_depthstencil.c @@ -147,6 +147,12 @@ static void svga_set_stencil_ref( struct pipe_context *pipe, svga->dirty |= SVGA_NEW_STENCIL_REF; } +static void +svga_set_sample_mask(struct pipe_context *pipe, + unsigned sample_mask) +{ +} + void svga_init_depth_stencil_functions( struct svga_context *svga ) { @@ -155,6 +161,7 @@ void svga_init_depth_stencil_functions( struct svga_context *svga ) svga->pipe.delete_depth_stencil_alpha_state = svga_delete_depth_stencil_state; svga->pipe.set_stencil_ref = svga_set_stencil_ref; + svga->pipe.set_sample_mask = svga_set_sample_mask; } diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index bef22f41ae5..99b419178b0 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -290,17 +290,21 @@ svga_translate_format_cap(enum pipe_format format) static boolean svga_is_format_supported( struct pipe_screen *screen, - enum pipe_format format, + enum pipe_format format, enum pipe_texture_target target, - unsigned tex_usage, + unsigned sample_count, + unsigned tex_usage, unsigned geom_flags ) { struct svga_winsys_screen *sws = svga_screen(screen)->sws; SVGA3dDevCapIndex index; SVGA3dDevCapResult result; - + assert(tex_usage); + if (sample_count > 1) + return FALSE; + /* Override host capabilities */ if (tex_usage & PIPE_BIND_RENDER_TARGET) { switch(format) { diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 066fa6b9ac9..5cc244d4b77 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -764,6 +764,22 @@ trace_context_set_clip_state(struct pipe_context *_pipe, trace_dump_call_end(); } +static INLINE void +trace_context_set_sample_mask(struct pipe_context *_pipe, + unsigned sample_mask) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_sample_mask"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(uint, sample_mask); + + pipe->set_sample_mask(pipe, sample_mask); + + trace_dump_call_end(); +} static INLINE void trace_context_set_constant_buffer(struct pipe_context *_pipe, @@ -1029,61 +1045,72 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe, static INLINE void -trace_context_surface_copy(struct pipe_context *_pipe, - struct pipe_surface *dest, - unsigned destx, unsigned desty, - struct pipe_surface *src, - unsigned srcx, unsigned srcy, - unsigned width, unsigned height) +trace_context_resource_copy_region(struct pipe_context *_pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, + struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, + unsigned width, unsigned height) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - dest = trace_surface_unwrap(tr_ctx, dest); - src = trace_surface_unwrap(tr_ctx, src); + dst = trace_resource_unwrap(tr_ctx, dst); + src = trace_resource_unwrap(tr_ctx, src); - trace_dump_call_begin("pipe_context", "surface_copy"); + trace_dump_call_begin("pipe_context", "resource_copy_region"); trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, dest); - trace_dump_arg(uint, destx); - trace_dump_arg(uint, desty); + trace_dump_arg(ptr, dst); + trace_dump_arg_struct(subresource, subdst); + trace_dump_arg(uint, dstx); + trace_dump_arg(uint, dsty); + trace_dump_arg(uint, dstz); trace_dump_arg(ptr, src); + trace_dump_arg_struct(subresource, subsrc); trace_dump_arg(uint, srcx); trace_dump_arg(uint, srcy); + trace_dump_arg(uint, srcz); trace_dump_arg(uint, width); trace_dump_arg(uint, height); - pipe->surface_copy(pipe, - dest, destx, desty, - src, srcx, srcy, width, height); + pipe->resource_copy_region(pipe, + dst, subdst, dstx, dsty, dstz, + src, subsrc, srcx, srcy, srcz, width, height); trace_dump_call_end(); } static INLINE void -trace_context_surface_fill(struct pipe_context *_pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, - unsigned value) +trace_context_resource_fill_region(struct pipe_context *_pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + unsigned width, unsigned height, + unsigned value) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - dst = trace_surface_unwrap(tr_ctx, dst); + dst = trace_resource_unwrap(tr_ctx, dst); - trace_dump_call_begin("pipe_context", "surface_fill"); + trace_dump_call_begin("pipe_context", "resource_fill_region"); trace_dump_arg(ptr, pipe); trace_dump_arg(ptr, dst); + trace_dump_arg_struct(subresource, subdst); trace_dump_arg(uint, dstx); trace_dump_arg(uint, dsty); + trace_dump_arg(uint, dstz); trace_dump_arg(uint, width); trace_dump_arg(uint, height); + trace_dump_arg(uint, value); - pipe->surface_fill(pipe, dst, dstx, dsty, width, height, value); + pipe->resource_fill_region(pipe, dst, subdst, dstx, dsty, dstz, + width, height, value); trace_dump_call_end(); } @@ -1412,6 +1439,7 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.set_blend_color = trace_context_set_blend_color; tr_ctx->base.set_stencil_ref = trace_context_set_stencil_ref; tr_ctx->base.set_clip_state = trace_context_set_clip_state; + tr_ctx->base.set_sample_mask = trace_context_set_sample_mask; tr_ctx->base.set_constant_buffer = trace_context_set_constant_buffer; tr_ctx->base.set_framebuffer_state = trace_context_set_framebuffer_state; tr_ctx->base.set_polygon_stipple = trace_context_set_polygon_stipple; @@ -1422,10 +1450,8 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.create_sampler_view = trace_create_sampler_view; tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy; tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers; - if (pipe->surface_copy) - tr_ctx->base.surface_copy = trace_context_surface_copy; - if (pipe->surface_fill) - tr_ctx->base.surface_fill = trace_context_surface_fill; + tr_ctx->base.resource_copy_region = trace_context_resource_copy_region; + tr_ctx->base.resource_fill_region = trace_context_resource_fill_region; tr_ctx->base.clear = trace_context_clear; tr_ctx->base.flush = trace_context_flush; tr_ctx->base.is_resource_referenced = trace_is_resource_referenced; diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index ac0b9060001..32e519a68a0 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -133,6 +133,7 @@ static boolean trace_screen_is_format_supported(struct pipe_screen *_screen, enum pipe_format format, enum pipe_texture_target target, + unsigned sample_count, unsigned tex_usage, unsigned geom_flags) { @@ -145,10 +146,12 @@ trace_screen_is_format_supported(struct pipe_screen *_screen, trace_dump_arg(ptr, screen); trace_dump_arg(format, format); trace_dump_arg(int, target); + trace_dump_arg(uint, sample_count); trace_dump_arg(uint, tex_usage); trace_dump_arg(uint, geom_flags); - result = screen->is_format_supported(screen, format, target, tex_usage, geom_flags); + result = screen->is_format_supported(screen, format, target, sample_count, + tex_usage, geom_flags); trace_dump_ret(bool, result); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 6f47845f3b8..6b729831768 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -198,6 +198,9 @@ struct pipe_context { void (*set_stencil_ref)( struct pipe_context *, const struct pipe_stencil_ref * ); + void (*set_sample_mask)( struct pipe_context *, + unsigned sample_mask ); + void (*set_clip_state)( struct pipe_context *, const struct pipe_clip_state * ); @@ -233,32 +236,47 @@ struct pipe_context { /** - * Surface functions + * Resource functions for blit-like functionality * - * The pipe driver is allowed to set these functions to NULL, and in that - * case, they will not be available. + * If a driver supports multisampling, resource_resolve must be available. */ /*@{*/ /** - * Copy a block of pixels from one surface to another. - * The surfaces must be of the same format. + * Copy a block of pixels from one resource to another. + * The resource must be of the same format. + * Resources with nr_samples > 1 are not allowed. */ - void (*surface_copy)(struct pipe_context *pipe, - struct pipe_surface *dest, - unsigned destx, unsigned desty, - struct pipe_surface *src, - unsigned srcx, unsigned srcy, - unsigned width, unsigned height); + void (*resource_copy_region)(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, + struct pipe_subresource subsrc, + unsigned srcx, unsigned srcy, unsigned srcz, + unsigned width, unsigned height); /** - * Fill a region of a surface with a constant value. + * Fill a region of a resource with a constant value. + * Resources with nr_samples > 1 are not allowed. */ - void (*surface_fill)(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height, - unsigned value); + void (*resource_fill_region)(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned dstx, unsigned dsty, unsigned dstz, + unsigned width, unsigned height, + unsigned value); + + /** + * Resolve a multisampled resource into a non-multisampled one. + * Source and destination must have the same size and same format. + */ + void (*resource_resolve)(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + struct pipe_resource *src, + struct pipe_subresource subsrc); + /*@}*/ /** diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 8201c29ac76..b54a6ef8247 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -284,8 +284,6 @@ enum pipe_transfer_usage { #define PIPE_BIND_VERTEX_BUFFER (1 << 3) /* set_vertex_buffers */ #define PIPE_BIND_INDEX_BUFFER (1 << 4) /* draw_elements */ #define PIPE_BIND_CONSTANT_BUFFER (1 << 5) /* set_constant_buffer */ -#define PIPE_BIND_BLIT_SOURCE (1 << 6) /* surface_copy */ -#define PIPE_BIND_BLIT_DESTINATION (1 << 7) /* surface_copy, fill */ #define PIPE_BIND_DISPLAY_TARGET (1 << 8) /* flush_front_buffer */ #define PIPE_BIND_TRANSFER_WRITE (1 << 9) /* get_transfer */ #define PIPE_BIND_TRANSFER_READ (1 << 10) /* get_transfer */ diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 0d9de48c909..21f428ed4af 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -88,7 +88,7 @@ struct pipe_screen { struct pipe_context * (*context_create)( struct pipe_screen *, void *priv ); - + /** * Check if the given pipe_format is supported as a texture or * drawing surface. @@ -98,7 +98,8 @@ struct pipe_screen { boolean (*is_format_supported)( struct pipe_screen *, enum pipe_format format, enum pipe_texture_target target, - unsigned bindings, + unsigned sample_count, + unsigned bindings, unsigned geom_flags ); /** diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index a01698d7674..5255b2003f8 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -219,6 +219,8 @@ struct pipe_blend_state unsigned logicop_enable:1; unsigned logicop_func:4; /**< PIPE_LOGICOP_x */ unsigned dither:1; + unsigned alpha_to_coverage:1; + unsigned alpha_to_one:1; struct pipe_rt_blend_state rt[PIPE_MAX_COLOR_BUFS]; }; diff --git a/src/gallium/state_trackers/dri/common/dri1_helper.c b/src/gallium/state_trackers/dri/common/dri1_helper.c index f641b41ff8b..ad6c7d37504 100644 --- a/src/gallium/state_trackers/dri/common/dri1_helper.c +++ b/src/gallium/state_trackers/dri/common/dri1_helper.c @@ -93,7 +93,7 @@ dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_resource *ptex) pipe_surface_reference(&drawable->dri1_surface, NULL); drawable->dri1_surface = pipe_screen->get_tex_surface(pipe_screen, - ptex, 0, 0, 0, PIPE_BIND_BLIT_SOURCE); + ptex, 0, 0, 0, 0/* no bind flag???*/); psurf = drawable->dri1_surface; } diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c index 064c73f54c2..81523b82ba9 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.c +++ b/src/gallium/state_trackers/dri/common/dri_screen.c @@ -72,13 +72,13 @@ dri_fill_in_modes(struct dri_screen *screen, __DRIconfig **configs_r5g6b5 = NULL; __DRIconfig **configs_a8r8g8b8 = NULL; __DRIconfig **configs_x8r8g8b8 = NULL; - unsigned num_modes; uint8_t depth_bits_array[5]; uint8_t stencil_bits_array[5]; - uint8_t msaa_samples_array[2]; + uint8_t msaa_samples_array[5]; unsigned depth_buffer_factor; unsigned back_buffer_factor; unsigned msaa_samples_factor; + unsigned i; struct pipe_screen *p_screen = screen->base.screen; boolean pf_r5g6b5, pf_a8r8g8b8, pf_x8r8g8b8; boolean pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32; @@ -92,34 +92,34 @@ dri_fill_in_modes(struct dri_screen *screen, depth_buffer_factor = 1; pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0); pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0); pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0); pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0); pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0); pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0); pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0); /* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */ if (dri_with_format(screen->sPriv)) { pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0); pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0); } else { pf_z16 = FALSE; @@ -146,22 +146,39 @@ dri_fill_in_modes(struct dri_screen *screen, } msaa_samples_array[0] = 0; - msaa_samples_array[1] = 4; back_buffer_factor = 3; - msaa_samples_factor = 2; - num_modes = - depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4; + /* also test color for msaa 2/4/6/8 - just assume it'll work for all depth buffers */ + if (pf_r5g6b5) { + msaa_samples_factor = 1; + for (i = 1; i < 5; i++) { + if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, + PIPE_TEXTURE_2D, i*2, + PIPE_BIND_RENDER_TARGET, 0)) { + msaa_samples_array[msaa_samples_factor] = i * 2; + msaa_samples_factor++; + } + } - if (pf_r5g6b5) configs_r5g6b5 = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, depth_bits_array, stencil_bits_array, depth_buffer_factor, back_buffer_modes, back_buffer_factor, msaa_samples_array, msaa_samples_factor, GL_TRUE); + } + + if (pf_a8r8g8b8) { + msaa_samples_factor = 1; + for (i = 1; i < 5; i++) { + if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, + PIPE_TEXTURE_2D, i*2, + PIPE_BIND_RENDER_TARGET, 0)) { + msaa_samples_array[msaa_samples_factor] = i * 2; + msaa_samples_factor++; + } + } - if (pf_a8r8g8b8) configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, depth_bits_array, stencil_bits_array, @@ -171,8 +188,19 @@ dri_fill_in_modes(struct dri_screen *screen, msaa_samples_array, msaa_samples_factor, GL_TRUE); + } + + if (pf_x8r8g8b8) { + msaa_samples_factor = 1; + for (i = 1; i < 5; i++) { + if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, + PIPE_TEXTURE_2D, i*2, + PIPE_BIND_RENDER_TARGET, 0)) { + msaa_samples_array[msaa_samples_factor] = i * 2; + msaa_samples_factor++; + } + } - if (pf_x8r8g8b8) configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV, depth_bits_array, stencil_bits_array, @@ -182,6 +210,7 @@ dri_fill_in_modes(struct dri_screen *screen, msaa_samples_array, msaa_samples_factor, GL_TRUE); + } if (pixel_bits == 16) { configs = configs_r5g6b5; diff --git a/src/gallium/state_trackers/dri/drm/dri1.c b/src/gallium/state_trackers/dri/drm/dri1.c index 326ff8bcada..9f0b9257312 100644 --- a/src/gallium/state_trackers/dri/drm/dri1.c +++ b/src/gallium/state_trackers/dri/drm/dri1.c @@ -156,24 +156,22 @@ dri1_swap_copy(struct pipe_context *pipe, struct drm_clip_rect clip; struct drm_clip_rect *cur; int i; + struct pipe_subresource subdst, subsrc; + subsrc.face = 0; + subsrc.level = 0; + subdst.face = 0; + subdst.level = 0; cur = dPriv->pClipRects; for (i = 0; i < dPriv->numClipRects; ++i) { if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) { - if (pipe->surface_copy) { - pipe->surface_copy(pipe, dst, clip.x1, clip.y1, - src, - (int)clip.x1 - dPriv->x, - (int)clip.y1 - dPriv->y, - clip.x2 - clip.x1, clip.y2 - clip.y1); - } else { - util_surface_copy(pipe, FALSE, dst, clip.x1, clip.y1, - src, - (int)clip.x1 - dPriv->x, - (int)clip.y1 - dPriv->y, - clip.x2 - clip.x1, clip.y2 - clip.y1); - } + pipe->resource_copy_region(pipe, dst->texture, subdst, + clip.x1, clip.y1, 0, + src->texture, subsrc, + (int)clip.x1 - dPriv->x, + (int)clip.y1 - dPriv->y, 0, + clip.x2 - clip.x1, clip.y2 - clip.y1); } } } @@ -204,6 +202,8 @@ dri1_present_texture_locked(__DRIdrawable * dPriv, return; pipe = dri1_get_pipe_context(screen); + /* XXX should probably use resources instead of surfaces in the api + - we get surface but only use the texture from it it seems... */ psurf = dri1_get_pipe_surface(drawable, ptex); if (!pipe || !psurf) return; diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 5c6fe97922a..d63b81a1c59 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -351,7 +351,7 @@ egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy, /* pick the first supported format */ for (i = 0; i < n; i++) { if (screen->is_format_supported(screen, fmt[i], - PIPE_TEXTURE_2D, PIPE_BIND_DEPTH_STENCIL, 0)) { + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) { formats[count++] = fmt[i]; break; } diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c index 478516453ce..4615a5829a6 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c @@ -407,24 +407,16 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) /** * Get the pipe surface of the given attachment of the native surface. */ -static struct pipe_surface * -get_pipe_surface(struct native_display *ndpy, struct native_surface *nsurf, - enum native_attachment natt, - unsigned bind) +static struct pipe_resource * +get_pipe_resource(struct native_display *ndpy, struct native_surface *nsurf, + enum native_attachment natt) { struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS]; - struct pipe_surface *psurf; textures[natt] = NULL; nsurf->validate(nsurf, 1 << natt, NULL, textures, NULL, NULL); - if (!textures[natt]) - return NULL; - - psurf = ndpy->screen->get_tex_surface(ndpy->screen, textures[natt], - 0, 0, 0, bind); - pipe_resource_reference(&textures[natt], NULL); - return psurf; + return textures[natt]; } static EGLBoolean @@ -437,7 +429,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, struct egl_g3d_config *gconf; struct native_surface *nsurf; struct pipe_screen *screen = gdpy->native->screen; - struct pipe_surface *psurf; + struct pipe_resource *ptex; if (!gsurf->render_texture) return EGL_TRUE; @@ -466,22 +458,23 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, return EGL_FALSE; } - psurf = get_pipe_surface(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, - PIPE_BIND_BLIT_DESTINATION); - if (psurf) { + ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT); + if (ptex) { struct pipe_surface *psrc; + struct pipe_subresource subsrc, subdst; + subsrc.face = 0; + subsrc.level = 0; + subdst.face = 0; + subdst.level = 0; - psrc = screen->get_tex_surface(screen, gsurf->render_texture, - 0, 0, 0, PIPE_BIND_BLIT_SOURCE); if (psrc) { - gdpy->pipe->surface_copy(gdpy->pipe, psurf, 0, 0, - psrc, 0, 0, psurf->width, psurf->height); - pipe_surface_reference(&psrc, NULL); + gdpy->pipe->resource_copy_region(gdpy->pipe, ptex, subdst, 0, 0, 0, + gsurf->render_texture, subsrc, 0, 0, 0, ptex->width0, ptex->height0); nsurf->flush_frontbuffer(nsurf); } - pipe_surface_reference(&psurf, NULL); + pipe_resource_reference(&ptex, NULL); } nsurf->destroy(nsurf); diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c index cf7188dfdb7..d81178e5592 100644 --- a/src/gallium/state_trackers/egl/kms/native_kms.c +++ b/src/gallium/state_trackers/egl/kms/native_kms.c @@ -563,7 +563,7 @@ kms_display_is_format_supported(struct native_display *ndpy, enum pipe_format fmt, boolean is_color) { return ndpy->screen->is_format_supported(ndpy->screen, - fmt, PIPE_TEXTURE_2D, + fmt, PIPE_TEXTURE_2D, 0, (is_color) ? PIPE_BIND_RENDER_TARGET : PIPE_BIND_DEPTH_STENCIL, 0); } diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c index d37f66da07e..63877ed5e51 100644 --- a/src/gallium/state_trackers/egl/x11/native_dri2.c +++ b/src/gallium/state_trackers/egl/x11/native_dri2.c @@ -498,9 +498,9 @@ choose_color_format(const __GLcontextModes *mode, enum pipe_format formats[32]) static boolean is_format_supported(struct pipe_screen *screen, - enum pipe_format fmt, boolean is_color) + enum pipe_format fmt, unsigned sample_count, boolean is_color) { - return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, + return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, sample_count, (is_color) ? PIPE_BIND_RENDER_TARGET : PIPE_BIND_DEPTH_STENCIL, 0); } @@ -512,6 +512,7 @@ dri2_display_convert_config(struct native_display *ndpy, { enum pipe_format formats[32]; int num_formats, i; + int sample_count = 0; if (!(mode->renderType & GLX_RGBA_BIT) || !mode->rgbMode) return FALSE; @@ -536,7 +537,7 @@ dri2_display_convert_config(struct native_display *ndpy, /* choose color format */ num_formats = choose_color_format(mode, formats); for (i = 0; i < num_formats; i++) { - if (is_format_supported(ndpy->screen, formats[i], TRUE)) { + if (is_format_supported(ndpy->screen, formats[i], sample_count, TRUE)) { nconf->color_format = formats[i]; break; } diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index f3b0617f76b..a6f808bc964 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -342,6 +342,7 @@ choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil) const unsigned tex_usage = PIPE_BIND_DEPTH_STENCIL; const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE | PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO); + const unsigned sample_count = 0; enum pipe_format formats[8], fmt; int count, i; @@ -365,7 +366,8 @@ choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil) fmt = PIPE_FORMAT_NONE; for (i = 0; i < count; i++) { if (xmdpy->screen->is_format_supported(xmdpy->screen, formats[i], - target, tex_usage, geom_flags)) { + target, sample_count, + tex_usage, geom_flags)) { fmt = formats[i]; break; } diff --git a/src/gallium/state_trackers/glx/xlib/xm_st.c b/src/gallium/state_trackers/glx/xlib/xm_st.c index 1c678b4f760..c62eb8bfbd1 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_st.c +++ b/src/gallium/state_trackers/glx/xlib/xm_st.c @@ -96,7 +96,7 @@ xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi, struct xmesa_st_framebuffer *xstfb = xmesa_st_framebuffer(stfbi); struct pipe_resource *src_ptex = xstfb->textures[src_statt]; struct pipe_resource *dst_ptex = xstfb->textures[dst_statt]; - struct pipe_surface *src, *dst; + struct pipe_subresource subsrc, subdst; struct pipe_context *pipe; if (!src_ptex || !dst_ptex) @@ -110,16 +110,14 @@ xmesa_st_framebuffer_copy_textures(struct st_framebuffer_iface *stfbi, xstfb->display->pipe = pipe; } - src = xstfb->screen->get_tex_surface(xstfb->screen, - src_ptex, 0, 0, 0, PIPE_BIND_BLIT_SOURCE); - dst = xstfb->screen->get_tex_surface(xstfb->screen, - dst_ptex, 0, 0, 0, PIPE_BIND_BLIT_DESTINATION); + subsrc.face = 0; + subsrc.level = 0; + subdst.face = 0; + subdst.level = 0; - if (src && dst) - pipe->surface_copy(pipe, dst, x, y, src, x, y, width, height); - - pipe_surface_reference(&src, NULL); - pipe_surface_reference(&dst, NULL); + if (src_ptex && dst_ptex) + pipe->resource_copy_region(pipe, dst_ptex, subdst, x, y, 0, + src_ptex, subsrc, x, y, 0, width, height); } /** diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 3c5509cb5e4..3d7b640b472 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -413,16 +413,17 @@ error1: /* * Surface functions */ - + void surface_copy(struct st_surface *dst, unsigned destx, unsigned desty, struct st_surface *src, unsigned srcx, unsigned srcy, unsigned width, unsigned height) { +/* XXX struct pipe_surface *_dst = NULL; struct pipe_surface *_src = NULL; - + _dst = st_pipe_surface(dst, PIPE_BIND_BLIT_DESTINATION); if(!_dst) SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing"); @@ -430,12 +431,20 @@ error1: _src = st_pipe_surface(src, PIPE_BIND_BLIT_SOURCE); if(!_src) SWIG_exception(SWIG_ValueError, "couldn't acquire source surface for reading"); - + $self->pipe->surface_copy($self->pipe, _dst, destx, desty, _src, srcx, srcy, width, height); - + fail: pipe_surface_reference(&_src, NULL); pipe_surface_reference(&_dst, NULL); +*/ + struct pipe_subresource subdst, subsrc; + subsrc.face = src->face; + subsrc.level = src->level; + subdst.face = dst->face; + subdst.level = dst->level; + $self->pipe->resource_copy_region($self->pipe, dst->texture, subdst, destx, desty, dst->zslice, + src->texture, subsrc, srcx, srcy, src->zslice, width, height); } void surface_fill(struct st_surface *dst, @@ -443,16 +452,23 @@ error1: unsigned width, unsigned height, unsigned value) { +/* XXX struct pipe_surface *_dst = NULL; - - _dst = st_pipe_surface(dst, PIPE_BIND_BLIT_DESTINATION); + + _dst = st_pipe_surface(dst, PIPE_BIND_BLIT_DESTINATION); if(!_dst) SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing"); $self->pipe->surface_fill($self->pipe, _dst, x, y, width, height, value); - + fail: pipe_surface_reference(&_dst, NULL); +*/ + struct pipe_subresource subdst; + subdst.face = dst->face; + subdst.level = dst->level; + $self->pipe->resource_fill_region($self->pipe, dst->texture, subdst, x, y, dst->zslice, + width, height, value); } %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); diff --git a/src/gallium/state_trackers/python/p_device.i b/src/gallium/state_trackers/python/p_device.i index 959c13f54d9..d55086fefd5 100644 --- a/src/gallium/state_trackers/python/p_device.i +++ b/src/gallium/state_trackers/python/p_device.i @@ -85,16 +85,18 @@ struct st_device { */ int is_format_supported( enum pipe_format format, enum pipe_texture_target target, + unsigned sample_count, unsigned bind, unsigned geom_flags ) { /* We can't really display surfaces with the python statetracker so mask * out that usage */ bind &= ~PIPE_BIND_DISPLAY_TARGET; - return $self->screen->is_format_supported( $self->screen, - format, - target, - bind, + return $self->screen->is_format_supported( $self->screen, + format, + target, + sample_count, + bind, geom_flags ); } diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c index 9c323b1809c..7c421dfcd4e 100644 --- a/src/gallium/state_trackers/vega/image.c +++ b/src/gallium/state_trackers/vega/image.c @@ -270,7 +270,7 @@ struct vg_image * image_create(VGImageFormat format, image->sampler.normalized_coords = 1; assert(screen->is_format_supported(screen, pformat, PIPE_TEXTURE_2D, - PIPE_BIND_SAMPLER_VIEW, 0)); + 0, PIPE_BIND_SAMPLER_VIEW, 0)); memset(&pt, 0, sizeof(pt)); pt.target = PIPE_TEXTURE_2D; @@ -576,7 +576,7 @@ void image_set_pixels(VGint dx, VGint dy, pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); surf = screen->get_tex_surface(screen, image_texture(src), 0, 0, 0, - PIPE_BIND_BLIT_SOURCE); + 0 /* no bind flags as surf isn't actually used??? */); vg_copy_surface(ctx, strb->surface, dx, dy, surf, sx+src->x, sy+src->y, width, height); @@ -601,7 +601,7 @@ void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy, pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); surf = screen->get_tex_surface(screen, image_texture(dst), 0, 0, 0, - PIPE_BIND_BLIT_SOURCE); + 0 /* no bind flags as surf isn't actually used??? */); vg_copy_surface(ctx, surf, dst->x + dx, dst->y + dy, strb->surface, sx, sy, width, height); diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index e6aea482a76..fe0f166e885 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -308,7 +308,7 @@ void renderer_copy_texture(struct renderer *ctx, #endif assert(screen->is_format_supported(screen, dst_surf->format, PIPE_TEXTURE_2D, - PIPE_BIND_RENDER_TARGET, 0)); + 0, PIPE_BIND_RENDER_TARGET, 0)); /* save state (restored below) */ cso_save_blend(ctx->cso); @@ -415,7 +415,7 @@ void renderer_copy_surface(struct renderer *ctx, struct pipe_sampler_view view_templ; struct pipe_sampler_view *view; struct pipe_resource texTemp, *tex; - struct pipe_surface *texSurf; + struct pipe_subresource subsrc, subdst; struct pipe_framebuffer_state fb; struct st_framebuffer *stfb = ctx->owner->draw_buffer; const int srcW = abs(srcX1 - srcX0); @@ -441,11 +441,11 @@ void renderer_copy_surface(struct renderer *ctx, } assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, - PIPE_BIND_SAMPLER_VIEW, 0)); + 0, PIPE_BIND_SAMPLER_VIEW, 0)); assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, - PIPE_BIND_SAMPLER_VIEW, 0)); + 0, PIPE_BIND_SAMPLER_VIEW, 0)); assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, - PIPE_BIND_RENDER_TARGET, 0)); + 0, PIPE_BIND_RENDER_TARGET, 0)); /* * XXX for now we're always creating a temporary texture. @@ -460,6 +460,7 @@ void renderer_copy_surface(struct renderer *ctx, texTemp.width0 = srcW; texTemp.height0 = srcH; texTemp.depth0 = 1; + texTemp.bind = PIPE_BIND_SAMPLER_VIEW; tex = screen->resource_create(screen, &texTemp); if (!tex) @@ -471,24 +472,15 @@ void renderer_copy_surface(struct renderer *ctx, if (!view) return; - texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0, - PIPE_BIND_RENDER_TARGET); - - /* load temp texture */ - if (pipe->surface_copy) { - pipe->surface_copy(pipe, - texSurf, 0, 0, /* dest */ - src, srcLeft, srcTop, /* src */ - srcW, srcH); /* size */ - } else { - util_surface_copy(pipe, FALSE, - texSurf, 0, 0, /* dest */ - src, srcLeft, srcTop, /* src */ - srcW, srcH); /* size */ - } + subdst.face = 0; + subdst.level = 0; + subsrc.face = src->face; + subsrc.level = src->level; - /* free the surface, update the texture if necessary.*/ - screen->tex_surface_destroy(texSurf); + pipe->resource_copy_region(pipe, + tex, subdst, 0, 0, 0, /* dest */ + src->texture, subsrc, srcLeft, srcTop, src->zslice, /* src */ + srcW, srcH); /* size */ /* save state (restored below) */ cso_save_blend(ctx->cso); diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index f6b07f2109f..f02db8949df 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -457,8 +457,7 @@ void vg_prepare_blend_surface(struct vg_context *ctx) dest_surface = pipe->screen->get_tex_surface(pipe->screen, stfb->blend_texture_view->texture, 0, 0, 0, - PIPE_BIND_BLIT_DESTINATION | - PIPE_BIND_RENDER_TARGET); + PIPE_BIND_RENDER_TARGET); /* flip it, because we want to use it as a sampler */ util_blit_pixels_tex(ctx->blit, view, @@ -494,8 +493,7 @@ void vg_prepare_blend_surface_from_mask(struct vg_context *ctx) dest_surface = pipe->screen->get_tex_surface(pipe->screen, stfb->blend_texture_view->texture, 0, 0, 0, - PIPE_BIND_BLIT_DESTINATION | - PIPE_BIND_RENDER_TARGET); + PIPE_BIND_RENDER_TARGET); /* flip it, because we want to use it as a sampler */ util_blit_pixels_tex(ctx->blit, diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c index f1bc5787855..3b04816df04 100644 --- a/src/gallium/state_trackers/vega/vg_manager.c +++ b/src/gallium/state_trackers/vega/vg_manager.c @@ -124,28 +124,22 @@ setup_new_alpha_mask(struct vg_context *ctx, struct st_framebuffer *stfb) /* if we had an old surface copy it over */ if (old_sampler_view) { - struct pipe_surface *surface = pipe->screen->get_tex_surface( - pipe->screen, - stfb->alpha_mask_view->texture, - 0, 0, 0, - PIPE_BIND_RENDER_TARGET | - PIPE_BIND_BLIT_DESTINATION); - struct pipe_surface *old_surface = pipe->screen->get_tex_surface( - pipe->screen, - old_sampler_view->texture, - 0, 0, 0, - PIPE_BIND_BLIT_SOURCE); - pipe->surface_copy(pipe, - surface, - 0, 0, - old_surface, - 0, 0, - MIN2(old_surface->width, surface->width), - MIN2(old_surface->height, surface->height)); - if (surface) - pipe_surface_reference(&surface, NULL); - if (old_surface) - pipe_surface_reference(&old_surface, NULL); + struct pipe_subresource subsurf, subold_surf; + subsurf.face = 0; + subsurf.level = 0; + subold_surf.face = 0; + subold_surf.level = 0; + pipe->resource_copy_region(pipe, + stfb->alpha_mask_view->texture, + subsurf, + 0, 0, 0, + old_sampler_view->texture, + subold_surf, + 0, 0, 0, + MIN2(old_sampler_view->texture->width0, + stfb->alpha_mask_view->texture->width0), + MIN2(old_sampler_view->texture->height0, + stfb->alpha_mask_view->texture->height0)); } /* Free the old texture @@ -172,9 +166,7 @@ vg_context_update_depth_stencil_rb(struct vg_context * ctx, /* Probably need dedicated flags for surface usage too: */ - surface_usage = (PIPE_BIND_RENDER_TARGET | - PIPE_BIND_BLIT_SOURCE | - PIPE_BIND_BLIT_DESTINATION); + surface_usage = PIPE_BIND_DEPTH_STENCIL; /* XXX: was: RENDER_TARGET */ dsrb->texture = create_texture(pipe, dsrb->format, width, height); if (!dsrb->texture) @@ -216,9 +208,7 @@ vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt) strb->texture = pt; strb->surface = screen->get_tex_surface(screen, strb->texture, 0, 0, 0, - PIPE_BIND_RENDER_TARGET | - PIPE_BIND_BLIT_SOURCE | - PIPE_BIND_BLIT_DESTINATION); + PIPE_BIND_RENDER_TARGET); if (!strb->surface) { pipe_resource_reference(&strb->texture, NULL); return TRUE; diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c index 11e779d25f8..e606477e975 100644 --- a/src/gallium/state_trackers/wgl/stw_pixelformat.c +++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c @@ -225,8 +225,8 @@ stw_pixelformat_init( void ) for(j = 0; j < Elements(stw_pf_color); ++j) { const struct stw_pf_color_info *color = &stw_pf_color[j]; - if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D, - PIPE_BIND_RENDER_TARGET | + if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D, + 0, PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET, 0)) continue; @@ -237,7 +237,7 @@ stw_pixelformat_init( void ) const struct stw_pf_depth_info *depth = &stw_pf_depth_stencil[l]; if(!screen->is_format_supported(screen, depth->format, PIPE_TEXTURE_2D, - PIPE_BIND_DEPTH_STENCIL, 0)) + 0, PIPE_BIND_DEPTH_STENCIL, 0)) continue; stw_pixelformat_add( stw_dev, color, depth, 0, doublebuffer, samples ); diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 921b6900fcd..e719644d340 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -437,10 +437,12 @@ xorg_dri2_init(ScreenPtr pScreen) ms->d_depth_bits_last = ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24X8_UNORM, PIPE_TEXTURE_2D, + 0, PIPE_BIND_DEPTH_STENCIL, 0); ms->ds_depth_bits_last = ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_TEXTURE_2D, + 0, PIPE_BIND_DEPTH_STENCIL, 0); return DRI2ScreenInit(pScreen, &dri2info); diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 31140f13bb4..ee40bc8ccbd 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -347,7 +347,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) XORG_FALLBACK("not GXcopy"); if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, - priv->tex->target, + priv->tex->target, 0, PIPE_BIND_RENDER_TARGET, 0)) { XORG_FALLBACK("format %s", util_format_name(priv->tex->format)); } @@ -428,39 +428,26 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, XORG_FALLBACK("alu not GXcopy"); if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, - priv->tex->target, + priv->tex->target, 0, PIPE_BIND_RENDER_TARGET, 0)) XORG_FALLBACK("pDst format %s", util_format_name(priv->tex->format)); if (!exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format, - src_priv->tex->target, + src_priv->tex->target, 0, PIPE_BIND_SAMPLER_VIEW, 0)) XORG_FALLBACK("pSrc format %s", util_format_name(src_priv->tex->format)); exa->copy.src = src_priv; exa->copy.dst = priv; - /* For same-surface copies, the pipe->surface_copy path is clearly - * superior, providing it is implemented. In other cases it's not - * clear what the better path would be, and eventually we'd - * probably want to gather timings and choose dynamically. + /* XXX this used to use resource_copy_region for same-surface copies, + * but they were redefined to not allow overlaps (some of the util code + * always assumed this anyway). + * Drivers should implement accelerated resource_copy_region or it will + * be slow - disable for now. */ - if (exa->pipe->surface_copy && - exa->copy.src == exa->copy.dst) { - + if (0 && exa->copy.src != exa->copy.dst) { exa->copy.use_surface_copy = TRUE; - - exa->copy.src_surface = - exa->scrn->get_tex_surface( exa->scrn, - exa->copy.src->tex, - 0, 0, 0, - PIPE_BIND_BLIT_SOURCE); - - exa->copy.dst_surface = - exa->scrn->get_tex_surface( exa->scrn, - exa->copy.dst->tex, - 0, 0, 0, - PIPE_BIND_BLIT_DESTINATION ); } else { exa->copy.use_surface_copy = FALSE; @@ -476,7 +463,7 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, exa->scrn->get_tex_surface(exa->scrn, exa->copy.dst->tex, 0, 0, 0, - PIPE_BIND_BLIT_DESTINATION); + PIPE_BIND_RENDER_TARGET); renderer_copy_prepare(exa->renderer, @@ -506,14 +493,19 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, (void) priv; if (exa->copy.use_surface_copy) { - /* XXX: consider exposing >1 box in surface_copy interface. - */ - exa->pipe->surface_copy( exa->pipe, - exa->copy.dst_surface, - dstX, dstY, - exa->copy.src_surface, - srcX, srcY, - width, height ); + struct pipe_subresource subdst, subsrc; + subdst.face = 0; + subdst.level = 0; + subsrc.face = 0; + subsrc.level = 0; + exa->pipe->resource_copy_region( exa->pipe, + exa->copy.dst->tex, + subdst, + dstX, dstY, 0, + exa->copy.src->tex, + subsrc, + srcX, srcY, 0, + width, height ); } else { renderer_copy_pixmap(exa->renderer, @@ -540,7 +532,6 @@ ExaDoneCopy(PixmapPtr pPixmap) exa->copy.src = NULL; exa->copy.dst = NULL; - pipe_surface_reference(&exa->copy.src_surface, NULL); pipe_surface_reference(&exa->copy.dst_surface, NULL); pipe_resource_reference(&exa->copy.src_texture, NULL); } @@ -639,7 +630,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, XORG_FALLBACK("pDst %s", !priv ? "!priv" : "!priv->tex"); if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, - priv->tex->target, + priv->tex->target, 0, PIPE_BIND_RENDER_TARGET, 0)) XORG_FALLBACK("pDst format: %s", util_format_name(priv->tex->format)); @@ -654,7 +645,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, XORG_FALLBACK("pSrc %s", !priv ? "!priv" : "!priv->tex"); if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, - priv->tex->target, + priv->tex->target, 0, PIPE_BIND_SAMPLER_VIEW, 0)) XORG_FALLBACK("pSrc format: %s", util_format_name(priv->tex->format)); @@ -671,7 +662,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, XORG_FALLBACK("pMask %s", !priv ? "!priv" : "!priv->tex"); if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, - priv->tex->target, + priv->tex->target, 0, PIPE_BIND_SAMPLER_VIEW, 0)) XORG_FALLBACK("pMask format: %s", util_format_name(priv->tex->format)); @@ -890,23 +881,19 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, texture = exa->scrn->resource_create(exa->scrn, &template); if (priv->tex) { - struct pipe_surface *dst_surf; + struct pipe_subresource subdst, subsrc; struct pipe_surface *src_surf; - dst_surf = exa->scrn->get_tex_surface( - exa->scrn, texture, 0, 0, 0, PIPE_BIND_BLIT_DESTINATION); - src_surf = xorg_gpu_surface(exa->pipe->screen, priv); - if (exa->pipe->surface_copy) { - exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf, - 0, 0, min(width, texture->width0), - min(height, texture->height0)); - } else { - util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf, - 0, 0, min(width, texture->width0), - min(height, texture->height0)); - } - exa->scrn->tex_surface_destroy(dst_surf); - exa->scrn->tex_surface_destroy(src_surf); + subdst.face = 0; + subdst.level = 0; + subsrc.face = 0; + subsrc.level = 0; + exa->pipe->resource_copy_region(exa->pipe, texture, + subdst, 0, 0, 0, + priv->tex, + subsrc, 0, 0, 0, + min(width, texture->width0), + min(height, texture->height0)); } pipe_resource_reference(&priv->tex, texture); @@ -1076,11 +1063,7 @@ out_err: struct pipe_surface * xorg_gpu_surface(struct pipe_screen *scrn, struct exa_pixmap_priv *priv) { - - /* seems to get called both for blits and render target usage */ return scrn->get_tex_surface(scrn, priv->tex, 0, 0, 0, - PIPE_BIND_BLIT_SOURCE | - PIPE_BIND_BLIT_DESTINATION | PIPE_BIND_RENDER_TARGET); } diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h index a35e9a5c901..86a1afc06e6 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.h +++ b/src/gallium/state_trackers/xorg/xorg_exa.h @@ -40,7 +40,6 @@ struct exa_context struct exa_pixmap_priv *src; struct exa_pixmap_priv *dst; - struct pipe_surface *src_surface; struct pipe_surface *dst_surface; struct pipe_resource *src_texture; diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c index a9610a86780..e5def3e2edd 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.c +++ b/src/gallium/state_trackers/xorg/xorg_renderer.c @@ -448,7 +448,7 @@ void renderer_copy_prepare(struct xorg_renderer *r, struct xorg_shader shader; assert(screen->is_format_supported(screen, dst_surface->format, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0)); (void) screen; @@ -524,7 +524,7 @@ renderer_clone_texture(struct xorg_renderer *r, /* the coming in texture should already have that invariance */ debug_assert(screen->is_format_supported(screen, src->format, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0)); format = src->format; @@ -547,25 +547,19 @@ renderer_clone_texture(struct xorg_renderer *r, { /* copy source framebuffer surface into texture */ - struct pipe_surface *ps_read = screen->get_tex_surface( - screen, src, 0, 0, 0, PIPE_BIND_BLIT_SOURCE); - struct pipe_surface *ps_tex = screen->get_tex_surface( - screen, pt, 0, 0, 0, PIPE_BIND_BLIT_DESTINATION ); - if (pipe->surface_copy) { - pipe->surface_copy(pipe, - ps_tex, /* dest */ - 0, 0, /* destx/y */ - ps_read, - 0, 0, src->width0, src->height0); - } else { - util_surface_copy(pipe, FALSE, - ps_tex, /* dest */ - 0, 0, /* destx/y */ - ps_read, - 0, 0, src->width0, src->height0); - } - pipe_surface_reference(&ps_read, NULL); - pipe_surface_reference(&ps_tex, NULL); + struct pipe_subresource subsrc, subdst; + subsrc.face = 0; + subsrc.level = 0; + subdst.face = 0; + subdst.level = 0; + pipe->resource_copy_region(pipe, + pt, /* dest */ + subdst, + 0, 0, 0, /* destx/y/z */ + src, + subsrc, + 0, 0, 0, + src->width0, src->height0); } return pt; diff --git a/src/gallium/tests/python/retrace/interpreter.py b/src/gallium/tests/python/retrace/interpreter.py index e58a69322ea..4599d68d7d5 100755 --- a/src/gallium/tests/python/retrace/interpreter.py +++ b/src/gallium/tests/python/retrace/interpreter.py @@ -230,8 +230,8 @@ class Screen(Object): context = self.real.context_create() return Context(self.interpreter, context) - def is_format_supported(self, format, target, bind, geom_flags): - return self.real.is_format_supported(format, target, bind, geom_flags) + def is_format_supported(self, format, target, sample_count, bind, geom_flags): + return self.real.is_format_supported(format, target, sample_count, bind, geom_flags) def resource_create(self, templat): return self.real.resource_create( diff --git a/src/gallium/tests/python/tests/surface_copy.py b/src/gallium/tests/python/tests/surface_copy.py index 8d841644035..7a6ede38044 100755 --- a/src/gallium/tests/python/tests/surface_copy.py +++ b/src/gallium/tests/python/tests/surface_copy.py @@ -70,13 +70,14 @@ class TextureTest(TestCase): face = self.face level = self.level zslice = self.zslice - + bind = PIPE_BIND_SAMPLER_VIEW geom_flags = 0 - if not dev.is_format_supported(format, target, bind, geom_flags): + sample_count = 0 + if not dev.is_format_supported(format, target, sample_count, bind, geom_flags): raise TestSkip - if not dev.is_format_supported(format, target, bind, geom_flags): + if not dev.is_format_supported(format, target, sample_count, bind, geom_flags): raise TestSkip # textures diff --git a/src/gallium/tests/python/tests/texture_blit.py b/src/gallium/tests/python/tests/texture_blit.py index 77f006ea04e..58706dab93d 100755 --- a/src/gallium/tests/python/tests/texture_blit.py +++ b/src/gallium/tests/python/tests/texture_blit.py @@ -130,17 +130,18 @@ class TextureColorSampleTest(TestCase): zslice = self.zslice minz = 0.0 maxz = 1.0 - + bind = PIPE_BIND_SAMPLER_VIEW geom_flags = 0 + sample_count = 0 if width != height: geom_flags |= PIPE_TEXTURE_GEOM_NON_SQUARE if not is_pot(width) or not is_pot(height) or not is_pot(depth): geom_flags |= PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO - - if not dev.is_format_supported(format, target, bind, geom_flags): + + if not dev.is_format_supported(format, target, sample_count, bind, geom_flags): raise TestSkip - + # disabled blending/masking blend = Blend() blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE @@ -348,17 +349,18 @@ class TextureDepthSampleTest(TestCase): zslice = self.zslice minz = 0.0 maxz = 1.0 - + bind = PIPE_BIND_SAMPLER_VIEW geom_flags = 0 + sample_count = 0 if width != height: geom_flags |= PIPE_TEXTURE_GEOM_NON_SQUARE if not is_pot(width) or not is_pot(height) or not is_pot(depth): geom_flags |= PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO - - if not dev.is_format_supported(format, target, bind, geom_flags): + + if not dev.is_format_supported(format, target, sample_count, bind, geom_flags): raise TestSkip - + # disabled blending/masking blend = Blend() blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE diff --git a/src/gallium/tests/python/tests/texture_transfer.py b/src/gallium/tests/python/tests/texture_transfer.py index 4aa3d6c709b..65c919bc64d 100755 --- a/src/gallium/tests/python/tests/texture_transfer.py +++ b/src/gallium/tests/python/tests/texture_transfer.py @@ -71,12 +71,13 @@ class TextureTest(TestCase): face = self.face level = self.level zslice = self.zslice - + bind = PIPE_BIND_SAMPLER_VIEW geom_flags = 0 - if not dev.is_format_supported(format, target, bind, geom_flags): + sample_count = 0 + if not dev.is_format_supported(format, target, sample_count, bind, geom_flags): raise TestSkip - + # textures texture = dev.resource_create( target = target, diff --git a/src/mesa/SConscript b/src/mesa/SConscript index 9408e2d2f69..b553804fcdc 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -151,6 +151,7 @@ if env['platform'] != 'winddk': 'state_tracker/st_atom_constbuf.c', 'state_tracker/st_atom_depth.c', 'state_tracker/st_atom_framebuffer.c', + 'state_tracker/st_atom_msaa.c', 'state_tracker/st_atom_pixeltransfer.c', 'state_tracker/st_atom_sampler.c', 'state_tracker/st_atom_scissor.c', diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak index af125d79aa0..74563bcf96e 100644 --- a/src/mesa/sources.mak +++ b/src/mesa/sources.mak @@ -182,6 +182,7 @@ STATETRACKER_SOURCES = \ state_tracker/st_atom_constbuf.c \ state_tracker/st_atom_depth.c \ state_tracker/st_atom_framebuffer.c \ + state_tracker/st_atom_msaa.c \ state_tracker/st_atom_pixeltransfer.c \ state_tracker/st_atom_sampler.c \ state_tracker/st_atom_scissor.c \ diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index cf391f1f91f..6f293128d3a 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -57,6 +57,7 @@ static const struct st_tracked_state *atoms[] = &st_update_sampler, &st_update_texture, &st_update_framebuffer, + &st_update_msaa, &st_update_vs_constants, &st_update_fs_constants, &st_update_pixel_transfer diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h index f34b49203b2..0c25269e0a4 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -54,6 +54,7 @@ extern const struct st_tracked_state st_update_polygon_stipple; extern const struct st_tracked_state st_update_viewport; extern const struct st_tracked_state st_update_scissor; extern const struct st_tracked_state st_update_blend; +extern const struct st_tracked_state st_update_msaa; extern const struct st_tracked_state st_update_sampler; extern const struct st_tracked_state st_update_texture; extern const struct st_tracked_state st_finalize_textures; diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index 1511b88dd1f..21403605805 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -257,6 +257,15 @@ update_blend( struct st_context *st ) if (st->ctx->Color.DitherFlag) blend->dither = 1; + if (st->ctx->Multisample.Enabled) { + /* unlike in gallium/d3d10 these operations are only performed + if msaa is enabled */ + if (st->ctx->Multisample.SampleAlphaToCoverage) + blend->alpha_to_coverage = 1; + if (st->ctx->Multisample.SampleAlphaToOne) + blend->alpha_to_one = 1; + } + cso_set_blend(st->cso_context, blend); { @@ -270,7 +279,7 @@ update_blend( struct st_context *st ) const struct st_tracked_state st_update_blend = { "st_update_blend", /* name */ { /* dirty */ - (_NEW_COLOR), /* XXX _NEW_BLEND someday? */ /* mesa */ + (_NEW_COLOR | _NEW_MULTISAMPLE), /* XXX _NEW_BLEND someday? */ /* mesa */ 0, /* st */ }, update_blend, /* update */ diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c b/src/mesa/state_tracker/st_atom_framebuffer.c index 52c507da3b3..036bc60049a 100644 --- a/src/mesa/state_tracker/st_atom_framebuffer.c +++ b/src/mesa/state_tracker/st_atom_framebuffer.c @@ -73,9 +73,7 @@ update_renderbuffer_surface(struct st_context *st, strb->rtt_face, level, strb->rtt_slice, - PIPE_BIND_RENDER_TARGET | - PIPE_BIND_BLIT_SOURCE | - PIPE_BIND_BLIT_DESTINATION ); + PIPE_BIND_RENDER_TARGET); #if 0 printf("-- alloc new surface %d x %d into tex %p\n", strb->surface->width, strb->surface->height, diff --git a/src/mesa/state_tracker/st_atom_msaa.c b/src/mesa/state_tracker/st_atom_msaa.c new file mode 100644 index 00000000000..ea9eb9a6d15 --- /dev/null +++ b/src/mesa/state_tracker/st_atom_msaa.c @@ -0,0 +1,83 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +#include "st_context.h" +#include "pipe/p_context.h" +#include "st_atom.h" + +#include "cso_cache/cso_context.h" + + +/* Second state atom for user clip planes: + */ +static void update_sample_mask( struct st_context *st ) +{ + unsigned sample_mask = 0xffffffff; + unsigned sample_count = 1; + struct pipe_framebuffer_state *framebuffer = &st->state.framebuffer; + + /* dependency here on bound surface (or rather, sample count) is worrying */ + if (framebuffer->zsbuf) + sample_count = framebuffer->zsbuf->texture->nr_samples; + else if (framebuffer->cbufs[0]) + sample_count = framebuffer->cbufs[0]->texture->nr_samples; + + if (st->ctx->Multisample.Enabled && sample_count > 1) { + /* unlike in gallium/d3d10 the mask is only active if msaa is enabled */ + if (st->ctx->Multisample.SampleCoverage) { + unsigned nr_bits; + nr_bits = st->ctx->Multisample.SampleCoverageValue * (float)sample_count; + /* there's lot of ways how to do this. We just use first few bits, + since we have no knowledge of sample positions here. When + app-supplied mask though is used too might need to be smarter. + Also, there's a interface restriction here in theory it is + encouraged this mask not be the same at each pixel. */ + sample_mask = (1 << nr_bits) - 1; + if (st->ctx->Multisample.SampleCoverageInvert) + sample_mask = ~sample_mask; + } + /* TODO merge with app-supplied sample mask */ + } + + /* mask off unused bits or don't care? */ + + if (sample_mask != st->state.sample_mask) { + st->state.sample_mask = sample_mask; + cso_set_sample_mask(st->cso_context, sample_mask); + } +} + + +const struct st_tracked_state st_update_msaa = { + "st_update_msaa", /* name */ + { /* dirty */ + (_NEW_MULTISAMPLE | _NEW_BUFFERS), /* mesa */ + ST_NEW_FRAMEBUFFER, /* st */ + }, + update_sample_mask /* update */ +}; diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 14865e601a0..b8644faaf83 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -123,7 +123,7 @@ create_color_map_texture(GLcontext *ctx) /* find an RGBA texture format */ format = st_choose_format(pipe->screen, GL_RGBA, - PIPE_TEXTURE_2D, PIPE_BIND_SAMPLER_VIEW); + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); /* create texture for color map/table */ pt = st_texture_create(st, PIPE_TEXTURE_2D, format, 0, diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 3e3076f7219..5aca1105eeb 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -807,15 +807,15 @@ st_init_bitmap(struct st_context *st) st->bitmap.rasterizer.gl_rasterization_rules = 1; /* find a usable texture format */ - if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM, PIPE_TEXTURE_2D, + if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0)) { st->bitmap.tex_format = PIPE_FORMAT_I8_UNORM; } - else if (screen->is_format_supported(screen, PIPE_FORMAT_A8_UNORM, PIPE_TEXTURE_2D, + else if (screen->is_format_supported(screen, PIPE_FORMAT_A8_UNORM, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0)) { st->bitmap.tex_format = PIPE_FORMAT_A8_UNORM; } - else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM, PIPE_TEXTURE_2D, + else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0)) { st->bitmap.tex_format = PIPE_FORMAT_L8_UNORM; } diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c index 97b19b20c35..fb7b48a7bf6 100644 --- a/src/mesa/state_tracker/st_cb_blit.c +++ b/src/mesa/state_tracker/st_cb_blit.c @@ -113,33 +113,23 @@ st_BlitFramebuffer(GLcontext *ctx, &readFB->Attachment[readFB->_ColorReadBufferIndex]; if(srcAtt->Type == GL_TEXTURE) { - struct pipe_screen *screen = pipe->screen; struct st_texture_object *srcObj = st_texture_object(srcAtt->Texture); struct st_renderbuffer *dstRb = st_renderbuffer(drawFB->_ColorDrawBuffers[0]); - struct pipe_surface *srcSurf; + struct pipe_subresource srcSub; struct pipe_surface *dstSurf = dstRb->surface; if (!srcObj->pt) return; - srcSurf = screen->get_tex_surface(screen, - srcObj->pt, - srcAtt->CubeMapFace, - srcAtt->TextureLevel, - srcAtt->Zoffset, - PIPE_BIND_BLIT_SOURCE); - if(!srcSurf) - return; + srcSub.face = srcAtt->CubeMapFace; + srcSub.level = srcAtt->TextureLevel; - util_blit_pixels(st->blit, - srcSurf, st_get_texture_sampler_view(srcObj, pipe), - srcX0, srcY0, srcX1, srcY1, + util_blit_pixels(st->blit, srcObj->pt, srcSub, + srcX0, srcY0, srcX1, srcY1, srcAtt->Zoffset, dstSurf, dstX0, dstY0, dstX1, dstY1, 0.0, pFilter); - - pipe_surface_reference(&srcSurf, NULL); } else { struct st_renderbuffer *srcRb = @@ -147,11 +137,15 @@ st_BlitFramebuffer(GLcontext *ctx, struct st_renderbuffer *dstRb = st_renderbuffer(drawFB->_ColorDrawBuffers[0]); struct pipe_surface *srcSurf = srcRb->surface; - struct pipe_sampler_view *srcView = st_get_renderbuffer_sampler_view(srcRb, pipe); struct pipe_surface *dstSurf = dstRb->surface; + struct pipe_subresource srcSub; + + srcSub.face = srcSurf->face; + srcSub.level = srcSurf->level; util_blit_pixels(st->blit, - srcSurf, srcView, srcX0, srcY0, srcX1, srcY1, + srcRb->texture, srcSub, srcX0, srcY0, srcX1, srcY1, + srcSurf->zslice, dstSurf, dstX0, dstY0, dstX1, dstY1, 0.0, pFilter); } @@ -183,13 +177,17 @@ st_BlitFramebuffer(GLcontext *ctx, if ((mask & depthStencil) == depthStencil && srcDepthSurf == srcStencilSurf && dstDepthSurf == dstStencilSurf) { - struct pipe_sampler_view *srcView = st_get_renderbuffer_sampler_view(srcDepthRb, pipe); + struct pipe_subresource srcSub; + + srcSub.face = srcDepthRb->surface->face; + srcSub.level = srcDepthRb->surface->level; /* Blitting depth and stencil values between combined * depth/stencil buffers. This is the ideal case for such buffers. */ util_blit_pixels(st->blit, - srcDepthSurf, srcView, srcX0, srcY0, srcX1, srcY1, + srcDepthRb->texture, srcSub, srcX0, srcY0, srcX1, srcY1, + srcDepthRb->surface->zslice, dstDepthSurf, dstX0, dstY0, dstX1, dstY1, 0.0, pFilter); } diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 900deaf46de..7991a93a1e6 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -179,9 +179,7 @@ st_bufferobj_data(GLcontext *ctx, switch(target) { case GL_PIXEL_PACK_BUFFER_ARB: case GL_PIXEL_UNPACK_BUFFER_ARB: - buffer_usage = (PIPE_BIND_RENDER_TARGET | - PIPE_BIND_BLIT_SOURCE | - PIPE_BIND_BLIT_DESTINATION); + buffer_usage = PIPE_BIND_RENDER_TARGET; break; case GL_ARRAY_BUFFER_ARB: buffer_usage = PIPE_BIND_VERTEX_BUFFER; diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 932e8edb250..f74d8cd42d0 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -969,6 +969,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, enum pipe_format srcFormat, texFormat; GLboolean invertTex = GL_FALSE; GLint readX, readY, readW, readH; + GLuint sample_count; struct gl_pixelstore_attrib pack = ctx->DefaultPacking; st_validate_state(st); @@ -993,9 +994,15 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); } + sample_count = rbRead->texture->nr_samples; + /* I believe this would be legal, presumably would need to do a resolve + for color, and for depth/stencil spec says to just use one of the + depth/stencil samples per pixel? Need some transfer clarifications. */ + assert(sample_count < 2); + srcFormat = rbRead->texture->format; - if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE_2D, + if (screen->is_format_supported(screen, srcFormat, PIPE_TEXTURE_2D, sample_count, PIPE_BIND_SAMPLER_VIEW, 0)) { texFormat = srcFormat; } @@ -1003,14 +1010,14 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, /* srcFormat can't be used as a texture format */ if (type == GL_DEPTH) { texFormat = st_choose_format(screen, GL_DEPTH_COMPONENT, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, sample_count, PIPE_BIND_DEPTH_STENCIL); assert(texFormat != PIPE_FORMAT_NONE); } else { /* default color format */ texFormat = st_choose_format(screen, GL_RGBA, PIPE_TEXTURE_2D, - PIPE_BIND_SAMPLER_VIEW); + sample_count, PIPE_BIND_SAMPLER_VIEW); assert(texFormat != PIPE_FORMAT_NONE); } } @@ -1049,27 +1056,20 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, /* Make temporary texture which is a copy of the src region. */ if (srcFormat == texFormat) { + struct pipe_subresource srcsub, dstsub; + srcsub.face = 0; + srcsub.level = 0; + dstsub.face = 0; + dstsub.level = 0; /* copy source framebuffer surface into mipmap/texture */ - struct pipe_surface *psRead = screen->get_tex_surface(screen, - rbRead->texture, 0, 0, 0, - PIPE_BIND_BLIT_SOURCE); - struct pipe_surface *psTex = screen->get_tex_surface(screen, pt, 0, 0, 0, - PIPE_BIND_RENDER_TARGET | - PIPE_BIND_BLIT_DESTINATION); - pipe->surface_copy(pipe, - psTex, /* dest surf */ - pack.SkipPixels, pack.SkipRows, /* dest pos */ - psRead, /* src surf */ - readX, readY, readW, readH); /* src region */ - - if (0) { - /* debug */ - debug_dump_surface(pipe, "copypixsrcsurf", psRead); - debug_dump_surface(pipe, "copypixtemptex", psTex); - } + pipe->resource_copy_region(pipe, + pt, /* dest tex */ + dstsub, + pack.SkipPixels, pack.SkipRows, 0, /* dest pos */ + rbRead->texture, /* src tex */ + srcsub, + readX, readY, 0, readW, readH); /* src region */ - pipe_surface_reference(&psRead, NULL); - pipe_surface_reference(&psTex, NULL); } else { /* CPU-based fallback/conversion */ diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index 00861a6ff36..4aaf91d5a19 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -79,7 +79,7 @@ st_egl_image_target_renderbuffer_storage(GLcontext *ctx, struct pipe_surface *ps; unsigned usage; - usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_BLIT_SOURCE | PIPE_BIND_BLIT_DESTINATION; + usage = PIPE_BIND_RENDER_TARGET; ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage); if (ps) { strb->Base.Width = ps->width; @@ -146,7 +146,7 @@ st_egl_image_target_texture_2d(GLcontext *ctx, GLenum target, struct pipe_surface *ps; unsigned usage; - usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_BLIT_DESTINATION | PIPE_BIND_BLIT_SOURCE; + usage = PIPE_BIND_SAMPLER_VIEW; ps = st_manager_get_egl_image_surface(st, (void *) image_handle, usage); if (ps) { st_bind_surface(ctx, target, texObj, texImage, ps); diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index c02121fbd1a..46f27ced6c3 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -72,7 +72,7 @@ st_renderbuffer_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, if (strb->format != PIPE_FORMAT_NONE) format = strb->format; else - format = st_choose_renderbuffer_format(screen, internalFormat); + format = st_choose_renderbuffer_format(screen, internalFormat, rb->NumSamples); /* init renderbuffer fields */ strb->Base.Width = width; @@ -442,7 +442,8 @@ st_validate_attachment(struct pipe_screen *screen, return GL_FALSE; return screen->is_format_supported(screen, stObj->pt->format, - PIPE_TEXTURE_2D, bindings, 0); + PIPE_TEXTURE_2D, + stObj->pt->nr_samples, bindings, 0); } @@ -545,6 +546,7 @@ void st_init_fbo_functions(struct dd_function_table *functions) functions->ReadBuffer = st_ReadBuffer; } +/* XXX unused ? */ struct pipe_sampler_view * st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb, struct pipe_context *pipe) diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index beb26ab4da1..43b6c1e75f4 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -73,6 +73,7 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw); extern void st_init_fbo_functions(struct dd_function_table *functions); +/* XXX unused ? */ extern struct pipe_sampler_view * st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb, struct pipe_context *pipe); diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index e34fd09dcb7..647898ef7c9 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -221,7 +221,7 @@ default_bindings(struct st_context *st, enum pipe_format format) else bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; - if (screen->is_format_supported(screen, format, target, bindings, geom)) + if (screen->is_format_supported(screen, format, target, 0, bindings, geom)) return bindings; else return PIPE_BIND_SAMPLER_VIEW; @@ -433,7 +433,7 @@ compress_with_blit(GLcontext * ctx, /* get destination surface (in the compressed texture) */ dst_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face, stImage->level, 0, - PIPE_BIND_BLIT_DESTINATION); + 0 /* flags */); if (!dst_surface) { /* can't render into this format (or other problem) */ return GL_FALSE; @@ -655,7 +655,7 @@ st_TexImage(GLcontext * ctx, _mesa_is_format_compressed(texImage->TexFormat) && screen->is_format_supported(screen, stImage->pt->format, - stImage->pt->target, + stImage->pt->target, 0, PIPE_BIND_RENDER_TARGET, 0)) { if (!pixels) goto done; @@ -851,8 +851,7 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level, struct pipe_surface *dst_surface; struct pipe_resource *dst_texture; struct pipe_transfer *tex_xfer; - unsigned bind = (PIPE_BIND_BLIT_DESTINATION | - PIPE_BIND_RENDER_TARGET | /* util_blit may choose to render */ + unsigned bind = (PIPE_BIND_RENDER_TARGET | /* util_blit may choose to render */ PIPE_BIND_TRANSFER_READ); /* create temp / dest surface */ @@ -1078,7 +1077,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level, _mesa_is_format_compressed(texImage->TexFormat) && screen->is_format_supported(screen, stImage->pt->format, - stImage->pt->target, + stImage->pt->target, 0, PIPE_BIND_RENDER_TARGET, 0)) { if (compress_with_blit(ctx, target, level, xoffset, yoffset, zoffset, @@ -1496,7 +1495,7 @@ st_copy_texsubimage(GLcontext *ctx, enum pipe_format dest_format, src_format; GLboolean use_fallback = GL_TRUE; GLboolean matching_base_formats; - GLuint format_writemask; + GLuint format_writemask, sample_count; struct pipe_surface *dest_surface = NULL; GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP); @@ -1519,6 +1518,12 @@ st_copy_texsubimage(GLcontext *ctx, return; } + sample_count = strb->surface->texture->nr_samples; + /* I believe this would be legal, presumably would need to do a resolve + for color, and for depth/stencil spec says to just use one of the + depth/stencil samples per pixel? Need some transfer clarifications. */ + assert(sample_count < 2); + if (srcX < 0) { width -= -srcX; destX += -srcX; @@ -1574,42 +1579,45 @@ st_copy_texsubimage(GLcontext *ctx, !do_flip) { /* use surface_copy() / blit */ - - dest_surface = screen->get_tex_surface(screen, stImage->pt, - stImage->face, stImage->level, - destZ, - PIPE_BIND_BLIT_DESTINATION); - - /* for surface_copy(), y=0=top, always */ - pipe->surface_copy(pipe, - /* dest */ - dest_surface, - destX, destY, - /* src */ - strb->surface, - srcX, srcY, - /* size */ - width, height); + struct pipe_subresource subdst, subsrc; + subdst.face = stImage->face; + subdst.level = stImage->level; + subsrc.face = strb->surface->face; + subsrc.level = strb->surface->level; + + /* for resource_copy_region(), y=0=top, always */ + pipe->resource_copy_region(pipe, + /* dest */ + stImage->pt, + subdst, + destX, destY, destZ, + /* src */ + strb->texture, + subsrc, + srcX, srcY, strb->surface->zslice, + /* size */ + width, height); use_fallback = GL_FALSE; } else if (format_writemask && texBaseFormat != GL_DEPTH_COMPONENT && texBaseFormat != GL_DEPTH_STENCIL && screen->is_format_supported(screen, src_format, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, sample_count, PIPE_BIND_SAMPLER_VIEW, 0) && screen->is_format_supported(screen, dest_format, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0)) { /* draw textured quad to do the copy */ GLint srcY0, srcY1; + struct pipe_subresource subsrc; dest_surface = screen->get_tex_surface(screen, stImage->pt, stImage->face, stImage->level, destZ, - PIPE_BIND_BLIT_DESTINATION); + PIPE_BIND_RENDER_TARGET); if (do_flip) { srcY1 = strb->Base.Height - srcY - height; @@ -1619,11 +1627,15 @@ st_copy_texsubimage(GLcontext *ctx, srcY0 = srcY; srcY1 = srcY0 + height; } + subsrc.face = strb->surface->face; + subsrc.level = strb->surface->level; + util_blit_pixels_writemask(st->blit, - strb->surface, - st_get_renderbuffer_sampler_view(strb, pipe), + strb->texture, + subsrc, srcX, srcY0, srcX + width, srcY1, + strb->surface->zslice, dest_surface, destX, destY, destX + width, destY + height, diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 21d0fa96e16..2070f14a5a6 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -93,19 +93,6 @@ st_get_msaa(void) } -/** Default method for pipe_context::surface_copy() */ -static void -st_surface_copy(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned dst_x, unsigned dst_y, - struct pipe_surface *src, - unsigned src_x, unsigned src_y, - unsigned w, unsigned h) -{ - util_surface_copy(pipe, FALSE, dst, dst_x, dst_y, src, src_x, src_y, w, h); -} - - static struct st_context * st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe ) { @@ -163,10 +150,6 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe ) st_init_limits(st); st_init_extensions(st); - /* plug in helper driver functions if needed */ - if (!pipe->surface_copy) - pipe->surface_copy = st_surface_copy; - return st; } diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 3637f6e75f0..987516f2482 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -94,6 +94,7 @@ struct st_context struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; + unsigned sample_mask; GLuint num_samplers; GLuint num_textures; diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 459e924cca3..810a0635b50 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -311,39 +311,39 @@ void st_init_extensions(struct st_context *st) * a depth/stencil buffer and texture from depth/stencil source. */ if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0) && screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0)) { ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE; } else if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0) && screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0)) { ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE; } /* sRGB support */ if (screen->is_format_supported(screen, PIPE_FORMAT_A8B8G8R8_SRGB, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0) || screen->is_format_supported(screen, PIPE_FORMAT_B8G8R8A8_SRGB, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0)) { ctx->Extensions.EXT_texture_sRGB = GL_TRUE; } /* s3tc support */ if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0) && (ctx->Mesa_DXTn || screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0))) { ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE; ctx->Extensions.S3_s3tc = GL_TRUE; @@ -351,10 +351,10 @@ void st_init_extensions(struct st_context *st) /* ycbcr support */ if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0) || screen->is_format_supported(screen, PIPE_FORMAT_YUYV, - PIPE_TEXTURE_2D, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0)) { ctx->Extensions.MESA_ycbcr_texture = GL_TRUE; } diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index d7d2be6d454..f7b10ea243a 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -311,13 +311,14 @@ find_supported_format(struct pipe_screen *screen, const enum pipe_format formats[], uint num_formats, enum pipe_texture_target target, - unsigned tex_usage, + unsigned sample_count, + unsigned tex_usage, unsigned geom_flags) { uint i; for (i = 0; i < num_formats; i++) { if (screen->is_format_supported(screen, formats[i], target, - tex_usage, geom_flags)) { + sample_count, tex_usage, geom_flags)) { return formats[i]; } } @@ -331,7 +332,8 @@ find_supported_format(struct pipe_screen *screen, static enum pipe_format default_rgba_format(struct pipe_screen *screen, enum pipe_texture_target target, - unsigned tex_usage, + unsigned sample_count, + unsigned tex_usage, unsigned geom_flags) { static const enum pipe_format colorFormats[] = { @@ -341,7 +343,7 @@ default_rgba_format(struct pipe_screen *screen, PIPE_FORMAT_B5G6R5_UNORM }; return find_supported_format(screen, colorFormats, Elements(colorFormats), - target, tex_usage, geom_flags); + target, sample_count, tex_usage, geom_flags); } @@ -351,7 +353,8 @@ default_rgba_format(struct pipe_screen *screen, static enum pipe_format default_rgb_format(struct pipe_screen *screen, enum pipe_texture_target target, - unsigned tex_usage, + unsigned sample_count, + unsigned tex_usage, unsigned geom_flags) { static const enum pipe_format colorFormats[] = { @@ -364,7 +367,7 @@ default_rgb_format(struct pipe_screen *screen, PIPE_FORMAT_B5G6R5_UNORM }; return find_supported_format(screen, colorFormats, Elements(colorFormats), - target, tex_usage, geom_flags); + target, sample_count, tex_usage, geom_flags); } /** @@ -373,7 +376,8 @@ default_rgb_format(struct pipe_screen *screen, static enum pipe_format default_srgba_format(struct pipe_screen *screen, enum pipe_texture_target target, - unsigned tex_usage, + unsigned sample_count, + unsigned tex_usage, unsigned geom_flags) { static const enum pipe_format colorFormats[] = { @@ -382,7 +386,7 @@ default_srgba_format(struct pipe_screen *screen, PIPE_FORMAT_A8B8G8R8_SRGB, }; return find_supported_format(screen, colorFormats, Elements(colorFormats), - target, tex_usage, geom_flags); + target, sample_count, tex_usage, geom_flags); } @@ -401,7 +405,8 @@ default_srgba_format(struct pipe_screen *screen, */ enum pipe_format st_choose_format(struct pipe_screen *screen, GLenum internalFormat, - enum pipe_texture_target target, unsigned bindings) + enum pipe_texture_target target, unsigned sample_count, + unsigned bindings) { unsigned geom_flags = 0; /* we don't care about POT vs. NPOT here, yet */ @@ -411,42 +416,53 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: - return default_rgba_format( screen, target, bindings, geom_flags ); + return default_rgba_format( screen, target, sample_count, bindings, + geom_flags ); case 3: case GL_RGB: - return default_rgb_format( screen, target, bindings, geom_flags ); + return default_rgb_format( screen, target, sample_count, bindings, + geom_flags ); case GL_RGBA16: - return default_rgba_format( screen, target, bindings, geom_flags ); + return default_rgba_format( screen, target, sample_count, bindings, + geom_flags ); case GL_RGBA4: case GL_RGBA2: if (screen->is_format_supported( screen, PIPE_FORMAT_B4G4R4A4_UNORM, - target, bindings, geom_flags )) + target, sample_count, bindings, + geom_flags )) return PIPE_FORMAT_B4G4R4A4_UNORM; - return default_rgba_format( screen, target, bindings, geom_flags ); + return default_rgba_format( screen, target, sample_count, bindings, + geom_flags ); case GL_RGB5_A1: if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM, - target, bindings, geom_flags )) + target, sample_count, bindings, + geom_flags )) return PIPE_FORMAT_B5G5R5A1_UNORM; - return default_rgba_format( screen, target, bindings, geom_flags ); + return default_rgba_format( screen, target, sample_count, bindings, + geom_flags ); case GL_RGB8: case GL_RGB10: case GL_RGB12: case GL_RGB16: - return default_rgb_format( screen, target, bindings, geom_flags ); + return default_rgb_format( screen, target, sample_count, bindings, + geom_flags ); case GL_RGB5: case GL_RGB4: case GL_R3_G3_B2: if (screen->is_format_supported( screen, PIPE_FORMAT_B5G6R5_UNORM, - target, bindings, geom_flags )) + target, sample_count, bindings, + geom_flags )) return PIPE_FORMAT_B5G6R5_UNORM; if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM, - target, bindings, geom_flags )) + target, sample_count, bindings, + geom_flags )) return PIPE_FORMAT_B5G5R5A1_UNORM; - return default_rgba_format( screen, target, bindings, geom_flags ); + return default_rgba_format( screen, target, sample_count, bindings, + geom_flags ); case GL_ALPHA: case GL_ALPHA4: @@ -455,9 +471,10 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case GL_ALPHA16: case GL_COMPRESSED_ALPHA: if (screen->is_format_supported( screen, PIPE_FORMAT_A8_UNORM, target, - bindings, geom_flags )) + sample_count, bindings, geom_flags )) return PIPE_FORMAT_A8_UNORM; - return default_rgba_format( screen, target, bindings, geom_flags ); + return default_rgba_format( screen, target, sample_count, bindings, + geom_flags ); case 1: case GL_LUMINANCE: @@ -467,9 +484,10 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case GL_LUMINANCE16: case GL_COMPRESSED_LUMINANCE: if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target, - bindings, geom_flags )) + sample_count, bindings, geom_flags )) return PIPE_FORMAT_L8_UNORM; - return default_rgba_format( screen, target, bindings, geom_flags ); + return default_rgba_format( screen, target, sample_count, bindings, + geom_flags ); case 2: case GL_LUMINANCE_ALPHA: @@ -481,9 +499,10 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case GL_LUMINANCE16_ALPHA16: case GL_COMPRESSED_LUMINANCE_ALPHA: if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target, - bindings, geom_flags )) + sample_count, bindings, geom_flags )) return PIPE_FORMAT_L8A8_UNORM; - return default_rgba_format( screen, target, bindings, geom_flags ); + return default_rgba_format( screen, target, sample_count, bindings, + geom_flags ); case GL_INTENSITY: case GL_INTENSITY4: @@ -492,17 +511,18 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case GL_INTENSITY16: case GL_COMPRESSED_INTENSITY: if (screen->is_format_supported( screen, PIPE_FORMAT_I8_UNORM, target, - bindings, geom_flags )) + sample_count, bindings, geom_flags )) return PIPE_FORMAT_I8_UNORM; - return default_rgba_format( screen, target, bindings, geom_flags ); + return default_rgba_format( screen, target, sample_count, bindings, + geom_flags ); case GL_YCBCR_MESA: - if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, - target, bindings, geom_flags)) { + if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, target, + sample_count, bindings, geom_flags)) { return PIPE_FORMAT_UYVY; } - if (screen->is_format_supported(screen, PIPE_FORMAT_YUYV, - target, bindings, geom_flags)) { + if (screen->is_format_supported(screen, PIPE_FORMAT_YUYV, target, + sample_count, bindings, geom_flags)) { return PIPE_FORMAT_YUYV; } return PIPE_FORMAT_NONE; @@ -512,33 +532,39 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, if (bindings & ~PIPE_BIND_SAMPLER_VIEW) return PIPE_FORMAT_NONE; else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB, - target, bindings, geom_flags)) + target, sample_count, bindings, + geom_flags)) return PIPE_FORMAT_DXT1_RGB; else - return default_rgb_format(screen, target, bindings, geom_flags); + return default_rgb_format(screen, target, sample_count, bindings, + geom_flags); case GL_COMPRESSED_RGBA: /* can only sample from compressed formats */ if (bindings & ~PIPE_BIND_SAMPLER_VIEW) return PIPE_FORMAT_NONE; else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA, - target, bindings, geom_flags)) + target, sample_count, bindings, + geom_flags)) return PIPE_FORMAT_DXT3_RGBA; else - return default_rgba_format(screen, target, bindings, geom_flags); + return default_rgba_format(screen, target, sample_count, bindings, + geom_flags); case GL_RGB_S3TC: case GL_RGB4_S3TC: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB, - target, bindings, geom_flags)) + target, sample_count, bindings, + geom_flags)) return PIPE_FORMAT_DXT1_RGB; else return PIPE_FORMAT_NONE; case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGBA, - target, bindings, geom_flags)) + target, sample_count, bindings, + geom_flags)) return PIPE_FORMAT_DXT1_RGBA; else return PIPE_FORMAT_NONE; @@ -547,14 +573,16 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case GL_RGBA4_S3TC: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA, - target, bindings, geom_flags)) + target, sample_count, bindings, + geom_flags)) return PIPE_FORMAT_DXT3_RGBA; else return PIPE_FORMAT_NONE; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA, - target, bindings, geom_flags)) + target, sample_count, bindings, + geom_flags)) return PIPE_FORMAT_DXT5_RGBA; else return PIPE_FORMAT_NONE; @@ -568,20 +596,20 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case GL_DEPTH_COMPONENT16: if (screen->is_format_supported(screen, PIPE_FORMAT_Z16_UNORM, target, - bindings, geom_flags)) + sample_count, bindings, geom_flags)) return PIPE_FORMAT_Z16_UNORM; /* fall-through */ case GL_DEPTH_COMPONENT24: if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, - target, bindings, geom_flags)) + target, sample_count, bindings, geom_flags)) return PIPE_FORMAT_Z24_UNORM_S8_USCALED; if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, - target, bindings, geom_flags)) + target, sample_count, bindings, geom_flags)) return PIPE_FORMAT_S8_USCALED_Z24_UNORM; /* fall-through */ case GL_DEPTH_COMPONENT32: - if (screen->is_format_supported(screen, PIPE_FORMAT_Z32_UNORM, - target, bindings, geom_flags)) + if (screen->is_format_supported(screen, PIPE_FORMAT_Z32_UNORM, target, + sample_count, bindings, geom_flags)) return PIPE_FORMAT_Z32_UNORM; /* fall-through */ case GL_DEPTH_COMPONENT: @@ -593,7 +621,7 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, PIPE_FORMAT_S8_USCALED_Z24_UNORM }; return find_supported_format(screen, formats, Elements(formats), - target, bindings, geom_flags); + target, sample_count, bindings, geom_flags); } case GL_STENCIL_INDEX: @@ -608,7 +636,7 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, PIPE_FORMAT_S8_USCALED_Z24_UNORM }; return find_supported_format(screen, formats, Elements(formats), - target, bindings, geom_flags); + target, sample_count, bindings, geom_flags); } case GL_DEPTH_STENCIL_EXT: @@ -619,7 +647,7 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, PIPE_FORMAT_S8_USCALED_Z24_UNORM }; return find_supported_format(screen, formats, Elements(formats), - target, bindings, geom_flags); + target, sample_count, bindings, geom_flags); } case GL_SRGB_EXT: @@ -628,7 +656,8 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case GL_COMPRESSED_SRGB_ALPHA_EXT: case GL_SRGB_ALPHA_EXT: case GL_SRGB8_ALPHA8_EXT: - return default_srgba_format( screen, target, bindings, geom_flags ); + return default_srgba_format( screen, target, sample_count, bindings, + geom_flags ); case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: return PIPE_FORMAT_DXT1_SRGB; case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: @@ -642,17 +671,19 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, case GL_SLUMINANCE8_ALPHA8_EXT: case GL_COMPRESSED_SLUMINANCE_EXT: case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_SRGB, - target, bindings, geom_flags)) + if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_SRGB, target, + sample_count, bindings, geom_flags)) return PIPE_FORMAT_L8A8_SRGB; - return default_srgba_format( screen, target, bindings, geom_flags ); + return default_srgba_format( screen, target, sample_count, bindings, + geom_flags ); case GL_SLUMINANCE_EXT: case GL_SLUMINANCE8_EXT: - if (screen->is_format_supported(screen, PIPE_FORMAT_L8_SRGB, - target, bindings, geom_flags)) + if (screen->is_format_supported(screen, PIPE_FORMAT_L8_SRGB, target, + sample_count, bindings, geom_flags)) return PIPE_FORMAT_L8_SRGB; - return default_srgba_format( screen, target, bindings, geom_flags ); + return default_srgba_format( screen, target, sample_count, bindings, + geom_flags ); default: return PIPE_FORMAT_NONE; @@ -665,14 +696,15 @@ st_choose_format(struct pipe_screen *screen, GLenum internalFormat, */ enum pipe_format st_choose_renderbuffer_format(struct pipe_screen *screen, - GLenum internalFormat) + GLenum internalFormat, unsigned sample_count) { uint usage; if (_mesa_is_depth_or_stencil_format(internalFormat)) usage = PIPE_BIND_DEPTH_STENCIL; else usage = PIPE_BIND_RENDER_TARGET; - return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D, usage); + return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D, + sample_count, usage); } @@ -700,12 +732,12 @@ st_ChooseTextureFormat(GLcontext *ctx, GLint internalFormat, bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; pFormat = st_choose_format(screen, internalFormat, - PIPE_TEXTURE_2D, bindings); + PIPE_TEXTURE_2D, 0, bindings); if (pFormat == PIPE_FORMAT_NONE) { /* try choosing format again, this time without render target bindings */ pFormat = st_choose_format(screen, internalFormat, - PIPE_TEXTURE_2D, PIPE_BIND_SAMPLER_VIEW); + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW); } if (pFormat == PIPE_FORMAT_NONE) { diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index a6cf7025a92..3288225d5d4 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -46,11 +46,12 @@ st_pipe_format_to_mesa_format(enum pipe_format pipeFormat); extern enum pipe_format st_choose_format(struct pipe_screen *screen, GLenum internalFormat, - enum pipe_texture_target target, unsigned tex_usage); + enum pipe_texture_target target, unsigned sample_count, + unsigned tex_usage); extern enum pipe_format st_choose_renderbuffer_format(struct pipe_screen *screen, - GLenum internalFormat); + GLenum internalFormat, unsigned sample_count); extern gl_format diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index e656908bede..2d587df6055 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -83,7 +83,7 @@ st_render_mipmap(struct st_context *st, assert(target != GL_TEXTURE_3D); /* not done yet */ /* check if we can render in the texture's format */ - if (!screen->is_format_supported(screen, psv->format, psv->texture->target, + if (!screen->is_format_supported(screen, psv->format, psv->texture->target, 0, PIPE_BIND_RENDER_TARGET, 0)) { return FALSE; } @@ -324,7 +324,11 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, if (!pt) return; - /* find expected last mipmap level to generate */ + /* not sure if this ultimately actually should work, + but we're not supporting multisampled textures yet. */ + assert(pt->nr_samples < 2); + + /* find expected last mipmap level to generate*/ lastLevel = compute_num_levels(ctx, texObj, target) - 1; if (lastLevel == 0) diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index 2d364737cb0..dbdf1ea1ad0 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -74,7 +74,7 @@ st_texture_create(struct st_context *st, _mesa_lookup_enum_by_nr(format), last_level); assert(format); - assert(screen->is_format_supported(screen, format, target, + assert(screen->is_format_supported(screen, format, target, 0, PIPE_BIND_SAMPLER_VIEW, 0)); memset(&pt, 0, sizeof(pt)); @@ -282,18 +282,20 @@ st_texture_image_copy(struct pipe_context *pipe, struct pipe_resource *src, GLuint srcLevel, GLuint face) { - struct pipe_screen *screen = pipe->screen; GLuint width = u_minify(dst->width0, dstLevel); GLuint height = u_minify(dst->height0, dstLevel); GLuint depth = u_minify(dst->depth0, dstLevel); - struct pipe_surface *src_surface; - struct pipe_surface *dst_surface; + struct pipe_subresource dstsub, srcsub; GLuint i; assert(u_minify(src->width0, srcLevel) == width); assert(u_minify(src->height0, srcLevel) == height); assert(u_minify(src->depth0, srcLevel) == depth); + dstsub.face = face; + dstsub.level = dstLevel; + srcsub.face = face; + srcsub.level = srcLevel; /* Loop over 3D image slices */ for (i = 0; i < depth; i++) { @@ -301,21 +303,14 @@ st_texture_image_copy(struct pipe_context *pipe, print_center_pixel(pipe, src); } - dst_surface = screen->get_tex_surface(screen, dst, face, dstLevel, i, - PIPE_BIND_BLIT_DESTINATION); - - src_surface = screen->get_tex_surface(screen, src, face, srcLevel, i, - PIPE_BIND_BLIT_SOURCE); - - pipe->surface_copy(pipe, - dst_surface, - 0, 0, /* destX, Y */ - src_surface, - 0, 0, /* srcX, Y */ - width, height); - - pipe_surface_reference(&src_surface, NULL); - pipe_surface_reference(&dst_surface, NULL); + pipe->resource_copy_region(pipe, + dst, + dstsub, + 0, 0, i,/* destX, Y, Z */ + src, + srcsub, + 0, 0, i,/* srcX, Y, Z */ + width, height); } } |