From 825b45366d5308fd3e8e71c0c1943cb6ca8f69ea Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Wed, 25 Jul 2012 12:38:22 +0200 Subject: [PATCH] gallium/u_blitter: implement blitting multisample resources It can blit only one sample at a time (it should be called in a loop). --- src/gallium/auxiliary/util/u_blit.c | 8 +- src/gallium/auxiliary/util/u_blitter.c | 250 +++++++++++------- src/gallium/auxiliary/util/u_blitter.h | 10 +- src/gallium/auxiliary/util/u_inlines.h | 20 +- src/gallium/auxiliary/util/u_simple_shaders.c | 133 ++++++++++ src/gallium/auxiliary/util/u_simple_shaders.h | 20 ++ src/gallium/drivers/i915/i915_surface.c | 4 +- src/gallium/drivers/r300/r300_blit.c | 4 +- src/gallium/drivers/r600/r600_blit.c | 4 +- 9 files changed, 348 insertions(+), 105 deletions(-) diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 7ec4aa3a4dc..bf1c392cd41 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -203,7 +203,7 @@ set_fragment_shader(struct blit_state *ctx, uint writemask, enum pipe_texture_target pipe_tex) { if (!ctx->fs[pipe_tex][writemask]) { - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex); + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); ctx->fs[pipe_tex][writemask] = util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex, @@ -223,7 +223,7 @@ set_depthstencil_fragment_shader(struct blit_state *ctx, enum pipe_texture_target pipe_tex) { if (!ctx->fs_depthstencil[pipe_tex]) { - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex); + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); ctx->fs_depthstencil[pipe_tex] = util_make_fragment_tex_shader_writedepthstencil(ctx->pipe, tgsi_tex, @@ -242,7 +242,7 @@ set_depth_fragment_shader(struct blit_state *ctx, enum pipe_texture_target pipe_tex) { if (!ctx->fs_depth[pipe_tex]) { - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex); + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); ctx->fs_depth[pipe_tex] = util_make_fragment_tex_shader_writedepth(ctx->pipe, tgsi_tex, @@ -261,7 +261,7 @@ set_stencil_fragment_shader(struct blit_state *ctx, enum pipe_texture_target pipe_tex) { if (!ctx->fs_stencil[pipe_tex]) { - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex); + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); ctx->fs_stencil[pipe_tex] = util_make_fragment_tex_shader_writestencil(ctx->pipe, tgsi_tex, diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index fa71f25ea75..7283a14f549 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -81,6 +81,12 @@ struct blitter_context_priv void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES]; void *fs_texfetch_stencil[PIPE_MAX_TEXTURE_TYPES]; + /* FS which outputs one sample from a multisample texture. */ + void *fs_texfetch_col_msaa[PIPE_MAX_TEXTURE_TYPES]; + void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES]; + void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES]; + void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES]; + /* Blend state. */ void *blend_write_color; /**< blend state with writemask of RGBA */ void *blend_keep_color; /**< blend state with writemask of 0 */ @@ -559,7 +565,8 @@ static void get_texcoords(struct pipe_sampler_view *src, { struct pipe_resource *tex = src->texture; unsigned level = src->u.tex.first_level; - boolean normalized = tex->target != PIPE_TEXTURE_RECT; + boolean normalized = tex->target != PIPE_TEXTURE_RECT && + tex->nr_samples <= 1; if (normalized) { out[0] = x1 / (float)u_minify(src_width0, level); @@ -593,7 +600,7 @@ static void set_texcoords_in_vertices(const float coord[4], static void blitter_set_texcoords(struct blitter_context_priv *ctx, struct pipe_sampler_view *src, unsigned src_width0, unsigned src_height0, - unsigned layer, + unsigned layer, unsigned sample, unsigned x1, unsigned y1, unsigned x2, unsigned y2) { @@ -630,8 +637,16 @@ static void blitter_set_texcoords(struct blitter_context_priv *ctx, break; case PIPE_TEXTURE_2D_ARRAY: - for (i = 0; i < 4; i++) - ctx->vertices[i][1][2] = layer; /*r*/ + for (i = 0; i < 4; i++) { + ctx->vertices[i][1][2] = layer; /*r*/ + ctx->vertices[i][1][3] = sample; /*q*/ + } + break; + + case PIPE_TEXTURE_2D: + for (i = 0; i < 4; i++) { + ctx->vertices[i][1][2] = sample; /*r*/ + } break; default:; @@ -672,81 +687,149 @@ void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs, static INLINE void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, - unsigned tex_target) + struct pipe_resource *tex) { struct pipe_context *pipe = ctx->base.pipe; - assert(tex_target < PIPE_MAX_TEXTURE_TYPES); + assert(tex->target < PIPE_MAX_TEXTURE_TYPES); - /* Create the fragment shader on-demand. */ - if (!ctx->fs_texfetch_col[tex_target]) { - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex_target); + if (tex->nr_samples > 1) { + void **shader = &ctx->fs_texfetch_col_msaa[tex->target]; - ctx->fs_texfetch_col[tex_target] = - util_make_fragment_tex_shader(pipe, tgsi_tex, TGSI_INTERPOLATE_LINEAR); - } + /* Create the fragment shader on-demand. */ + if (!*shader) { + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, + tex->nr_samples); + + *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex); + } + + return *shader; + } else { + void **shader = &ctx->fs_texfetch_col[tex->target]; - return ctx->fs_texfetch_col[tex_target]; + /* Create the fragment shader on-demand. */ + if (!*shader) { + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0); + + *shader = + util_make_fragment_tex_shader(pipe, tgsi_tex, + TGSI_INTERPOLATE_LINEAR); + } + + return *shader; + } } static INLINE void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx, - unsigned tex_target) + struct pipe_resource *tex) { struct pipe_context *pipe = ctx->base.pipe; - assert(tex_target < PIPE_MAX_TEXTURE_TYPES); + assert(tex->target < PIPE_MAX_TEXTURE_TYPES); - /* Create the fragment shader on-demand. */ - if (!ctx->fs_texfetch_depth[tex_target]) { - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex_target); + if (tex->nr_samples > 1) { + void **shader = &ctx->fs_texfetch_depth_msaa[tex->target]; - ctx->fs_texfetch_depth[tex_target] = - util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex, - TGSI_INTERPOLATE_LINEAR); - } + /* Create the fragment shader on-demand. */ + if (!*shader) { + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, + tex->nr_samples); + + *shader = + util_make_fs_blit_msaa_depth(pipe, tgsi_tex); + } - return ctx->fs_texfetch_depth[tex_target]; + return *shader; + } else { + void **shader = &ctx->fs_texfetch_depth[tex->target]; + + /* Create the fragment shader on-demand. */ + if (!*shader) { + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0); + + *shader = + util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex, + TGSI_INTERPOLATE_LINEAR); + } + + return *shader; + } } static INLINE void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx, - unsigned tex_target) + struct pipe_resource *tex) { struct pipe_context *pipe = ctx->base.pipe; - assert(tex_target < PIPE_MAX_TEXTURE_TYPES); + assert(tex->target < PIPE_MAX_TEXTURE_TYPES); - /* Create the fragment shader on-demand. */ - if (!ctx->fs_texfetch_depthstencil[tex_target]) { - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex_target); + if (tex->nr_samples > 1) { + void **shader = &ctx->fs_texfetch_depthstencil_msaa[tex->target]; - ctx->fs_texfetch_depthstencil[tex_target] = - util_make_fragment_tex_shader_writedepthstencil(pipe, tgsi_tex, - TGSI_INTERPOLATE_LINEAR); - } + /* Create the fragment shader on-demand. */ + if (!*shader) { + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, + tex->nr_samples); + + *shader = + util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex); + } - return ctx->fs_texfetch_depthstencil[tex_target]; + return *shader; + } else { + void **shader = &ctx->fs_texfetch_depthstencil[tex->target]; + + /* Create the fragment shader on-demand. */ + if (!*shader) { + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0); + + *shader = + util_make_fragment_tex_shader_writedepthstencil(pipe, tgsi_tex, + TGSI_INTERPOLATE_LINEAR); + } + + return *shader; + } } static INLINE void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx, - unsigned tex_target) + struct pipe_resource *tex) { struct pipe_context *pipe = ctx->base.pipe; - assert(tex_target < PIPE_MAX_TEXTURE_TYPES); + assert(tex->target < PIPE_MAX_TEXTURE_TYPES); - /* Create the fragment shader on-demand. */ - if (!ctx->fs_texfetch_stencil[tex_target]) { - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex_target); + if (tex->nr_samples > 1) { + void **shader = &ctx->fs_texfetch_stencil_msaa[tex->target]; - ctx->fs_texfetch_stencil[tex_target] = - util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex, - TGSI_INTERPOLATE_LINEAR); - } + /* Create the fragment shader on-demand. */ + if (!*shader) { + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, + tex->nr_samples); - return ctx->fs_texfetch_stencil[tex_target]; + *shader = + util_make_fs_blit_msaa_stencil(pipe, tgsi_tex); + } + + return *shader; + } else { + void **shader = &ctx->fs_texfetch_stencil[tex->target]; + + /* Create the fragment shader on-demand. */ + if (!*shader) { + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0); + + *shader = + util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex, + TGSI_INTERPOLATE_LINEAR); + } + + return *shader; + } } static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx) @@ -989,10 +1072,10 @@ boolean util_blitter_is_copy_supported(struct blitter_context *blitter, void util_blitter_copy_texture(struct blitter_context *blitter, struct pipe_resource *dst, - unsigned dst_level, + unsigned dst_level, unsigned dst_sample_mask, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, - unsigned src_level, + unsigned src_level, unsigned src_sample, const struct pipe_box *srcbox) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; @@ -1012,9 +1095,9 @@ void util_blitter_copy_texture(struct blitter_context *blitter, src_view = pipe->create_sampler_view(pipe, src, &src_templ); /* Copy. */ - util_blitter_copy_texture_view(blitter, dst_view, dstx, dsty, src_view, - srcbox, src->width0, src->height0, - PIPE_MASK_RGBAZS); + util_blitter_copy_texture_view(blitter, dst_view, dst_sample_mask, dstx, + dsty, src_view, src_sample, srcbox, + src->width0, src->height0, PIPE_MASK_RGBAZS); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); @@ -1022,8 +1105,10 @@ void util_blitter_copy_texture(struct blitter_context *blitter, void util_blitter_copy_texture_view(struct blitter_context *blitter, struct pipe_surface *dst, + unsigned dst_sample_mask, unsigned dstx, unsigned dsty, struct pipe_sampler_view *src, + unsigned src_sample, const struct pipe_box *srcbox, unsigned src_width0, unsigned src_height0, unsigned mask) @@ -1077,17 +1162,17 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter, pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); pipe->bind_fs_state(pipe, - blitter_get_fs_texfetch_depthstencil(ctx, src_target)); + blitter_get_fs_texfetch_depthstencil(ctx, src->texture)); } else if (blit_depth) { pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); pipe->bind_fs_state(pipe, - blitter_get_fs_texfetch_depth(ctx, src_target)); + blitter_get_fs_texfetch_depth(ctx, src->texture)); } else { /* is_stencil */ pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); pipe->bind_fs_state(pipe, - blitter_get_fs_texfetch_stencil(ctx, src_target)); + blitter_get_fs_texfetch_stencil(ctx, src->texture)); } fb_state.nr_cbufs = 0; @@ -1096,7 +1181,7 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter, pipe->bind_blend_state(pipe, ctx->blend_write_color); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); pipe->bind_fs_state(pipe, - blitter_get_fs_texfetch_col(ctx, src_target)); + blitter_get_fs_texfetch_col(ctx, src->texture)); fb_state.nr_cbufs = 1; fb_state.cbufs[0] = dst; @@ -1127,51 +1212,36 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter, pipe->bind_vertex_elements_state(pipe, ctx->velem_state); pipe->set_framebuffer_state(pipe, &fb_state); - pipe->set_sample_mask(pipe, ~0); + pipe->set_sample_mask(pipe, dst_sample_mask); blitter_set_common_draw_rect_state(ctx); blitter_set_dst_dimensions(ctx, dst->width, dst->height); - switch (src_target) { + if ((src_target == PIPE_TEXTURE_1D || + src_target == PIPE_TEXTURE_2D || + src_target == PIPE_TEXTURE_RECT) && + src->texture->nr_samples <= 1) { /* Draw the quad with the draw_rectangle callback. */ - case PIPE_TEXTURE_1D: - case PIPE_TEXTURE_2D: - case PIPE_TEXTURE_RECT: - { - /* Set texture coordinates. - use a pipe color union - * for interface purposes. - * XXX pipe_color_union is a wrong name since we use that to set - * texture coordinates too. - */ - union pipe_color_union coord; - get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y, - srcbox->x+width, srcbox->y+height, coord.f); - - /* Draw. */ - blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, - UTIL_BLITTER_ATTRIB_TEXCOORD, &coord); - } - break; + /* Set texture coordinates. - use a pipe color union + * for interface purposes. + * XXX pipe_color_union is a wrong name since we use that to set + * texture coordinates too. + */ + union pipe_color_union coord; + get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y, + srcbox->x+width, srcbox->y+height, coord.f); + + /* Draw. */ + blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, + UTIL_BLITTER_ATTRIB_TEXCOORD, &coord); + } else { /* Draw the quad with the generic codepath. */ - default: - /* Set texture coordinates. */ - switch (src_target) { - case PIPE_TEXTURE_1D_ARRAY: - case PIPE_TEXTURE_2D_ARRAY: - case PIPE_TEXTURE_3D: - case PIPE_TEXTURE_CUBE: - blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z, - srcbox->y, srcbox->x, - srcbox->x + width, srcbox->y + height); - break; - - default: - assert(0); - } - - blitter_draw(ctx, dstx, dsty, dstx+width, dsty+height, 0); - break; + blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z, + src_sample, + srcbox->x, srcbox->y, + srcbox->x + width, srcbox->y + height); + blitter_draw(ctx, dstx, dsty, dstx+width, dsty+height, 0); } blitter_restore_vertex_states(ctx); diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index 7600391c511..cccdc061e08 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -178,6 +178,10 @@ boolean util_blitter_is_copy_supported(struct blitter_context *blitter, * a software fallback path is taken and both surfaces must be of the same * format. * + * Only one sample of a multisample texture can be copied and is specified by + * src_sample. If the destination is a multisample resource, dst_sample_mask + * specifies the sample mask. For single-sample resources, set dst_sample_mask + * to ~0. * * These states must be saved in the blitter in addition to the state objects * already required to be saved: @@ -190,10 +194,10 @@ boolean util_blitter_is_copy_supported(struct blitter_context *blitter, */ void util_blitter_copy_texture(struct blitter_context *blitter, struct pipe_resource *dst, - unsigned dst_level, + unsigned dst_level, unsigned dst_sample_mask, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, - unsigned src_level, + unsigned src_level, unsigned src_sample, const struct pipe_box *srcbox); /** @@ -218,8 +222,10 @@ void util_blitter_copy_texture(struct blitter_context *blitter, */ void util_blitter_copy_texture_view(struct blitter_context *blitter, struct pipe_surface *dst, + unsigned dst_sample_mask, unsigned dstx, unsigned dsty, struct pipe_sampler_view *src, + unsigned src_sample, const struct pipe_box *srcbox, unsigned src_width0, unsigned src_height0, unsigned mask); diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 2d603e4ddf6..a1ece415f46 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -548,23 +548,37 @@ util_query_clear_result(union pipe_query_result *result, unsigned type) /** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */ static INLINE unsigned -util_pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target) +util_pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target, + unsigned nr_samples) { switch (pipe_tex_target) { case PIPE_TEXTURE_1D: + assert(nr_samples <= 1); return TGSI_TEXTURE_1D; + case PIPE_TEXTURE_2D: - return TGSI_TEXTURE_2D; + return nr_samples > 1 ? TGSI_TEXTURE_2D_MSAA : TGSI_TEXTURE_2D; + case PIPE_TEXTURE_RECT: + assert(nr_samples <= 1); return TGSI_TEXTURE_RECT; + case PIPE_TEXTURE_3D: + assert(nr_samples <= 1); return TGSI_TEXTURE_3D; + case PIPE_TEXTURE_CUBE: + assert(nr_samples <= 1); return TGSI_TEXTURE_CUBE; + case PIPE_TEXTURE_1D_ARRAY: + assert(nr_samples <= 1); return TGSI_TEXTURE_1D_ARRAY; + case PIPE_TEXTURE_2D_ARRAY: - return TGSI_TEXTURE_2D_ARRAY; + return nr_samples > 1 ? TGSI_TEXTURE_2D_ARRAY_MSAA : + TGSI_TEXTURE_2D_ARRAY; + default: assert(0 && "unexpected texture target"); return TGSI_TEXTURE_UNKNOWN; diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c index 3476b6ce0ca..5f0134d7014 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/src/gallium/auxiliary/util/u_simple_shaders.c @@ -40,7 +40,12 @@ #include "pipe/p_state.h" #include "util/u_simple_shaders.h" #include "util/u_debug.h" +#include "util/u_memory.h" +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_strings.h" #include "tgsi/tgsi_ureg.h" +#include "tgsi/tgsi_text.h" +#include /* include last */ @@ -353,3 +358,131 @@ util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, return ureg_create_shader_and_destroy( ureg, pipe ); } + + +static void * +util_make_fs_blit_msaa_gen(struct pipe_context *pipe, + unsigned tgsi_tex, + const char *output_semantic, + const char *output_mask) +{ + static const char shader_templ[] = + "FRAG\n" + "DCL IN[0], GENERIC[0], LINEAR\n" + "DCL SAMP[0]\n" + "DCL OUT[0], %s\n" + "DCL TEMP[0]\n" + + "F2U TEMP[0], IN[0]\n" + "TXF OUT[0]%s, TEMP[0].xyzz, SAMP[0], %s\n" + "END\n"; + + const char *type = tgsi_texture_names[tgsi_tex]; + char text[sizeof(shader_templ)+100]; + struct tgsi_token tokens[1000]; + struct pipe_shader_state state = {tokens}; + + assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA || + tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA); + + sprintf(text, shader_templ, output_semantic, output_mask, type); + + if (!tgsi_text_translate(text, tokens, Elements(tokens))) { + puts(text); + assert(0); + return NULL; + } +#if 0 + tgsi_dump(state.tokens, 0); +#endif + + return pipe->create_fs_state(pipe, &state); +} + + +/** + * Make a fragment shader that sets the output color to a color + * fetched from a multisample texture. + * \param tex_target one of PIPE_TEXTURE_x + */ +void * +util_make_fs_blit_msaa_color(struct pipe_context *pipe, + unsigned tgsi_tex) +{ + return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, + "COLOR[0]", ""); +} + + +/** + * Make a fragment shader that sets the output depth to a depth value + * fetched from a multisample texture. + * \param tex_target one of PIPE_TEXTURE_x + */ +void * +util_make_fs_blit_msaa_depth(struct pipe_context *pipe, + unsigned tgsi_tex) +{ + return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, + "POSITION", ".z"); +} + + +/** + * Make a fragment shader that sets the output stencil to a stencil value + * fetched from a multisample texture. + * \param tex_target one of PIPE_TEXTURE_x + */ +void * +util_make_fs_blit_msaa_stencil(struct pipe_context *pipe, + unsigned tgsi_tex) +{ + return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, + "STENCIL", ".y"); +} + + +/** + * Make a fragment shader that sets the output depth and stencil to depth + * and stencil values fetched from two multisample textures / samplers. + * The sizes of both textures should match (it should be one depth-stencil + * texture). + * \param tex_target one of PIPE_TEXTURE_x + */ +void * +util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe, + unsigned tgsi_tex) +{ + static const char shader_templ[] = + "FRAG\n" + "DCL IN[0], GENERIC[0], LINEAR\n" + "DCL SAMP[0..1]\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], STENCIL\n" + "DCL TEMP[0]\n" + + "F2U TEMP[0], IN[0]\n" + "TXF OUT[0].z, TEMP[0], SAMP[0], %s\n" + "TXF OUT[1].y, TEMP[0], SAMP[1], %s\n" + "END\n"; + + const char *type = tgsi_texture_names[tgsi_tex]; + char text[sizeof(shader_templ)+100]; + struct tgsi_token tokens[1000]; + struct pipe_shader_state state = {tokens}; + + assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA || + tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA); + + sprintf(text, shader_templ, type, type); + + if (!tgsi_text_translate(text, tokens, Elements(tokens))) { + assert(0); + return NULL; + } +#if 0 + tgsi_dump(state.tokens, 0); +#endif + + return pipe->create_fs_state(pipe, &state); +} diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h index 0764998a338..e4ffde6521e 100644 --- a/src/gallium/auxiliary/util/u_simple_shaders.h +++ b/src/gallium/auxiliary/util/u_simple_shaders.h @@ -95,6 +95,26 @@ util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, int input_semantic, int input_interpolate); + +extern void * +util_make_fs_blit_msaa_color(struct pipe_context *pipe, + unsigned tgsi_tex); + + +extern void * +util_make_fs_blit_msaa_depth(struct pipe_context *pipe, + unsigned tgsi_tex); + + +extern void * +util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe, + unsigned tgsi_tex); + + +void * +util_make_fs_blit_msaa_stencil(struct pipe_context *pipe, + unsigned tgsi_tex); + #ifdef __cplusplus } #endif diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c index a25676efeca..5f0783f0305 100644 --- a/src/gallium/drivers/i915/i915_surface.c +++ b/src/gallium/drivers/i915/i915_surface.c @@ -86,8 +86,8 @@ i915_surface_copy_render(struct pipe_context *pipe, i915->saved_nr_sampler_views, i915->saved_sampler_views); - util_blitter_copy_texture(i915->blitter, dst, dst_level, dstx, dsty, dstz, - src, src_level, src_box); + util_blitter_copy_texture(i915->blitter, dst, dst_level, ~0, dstx, dsty, dstz, + src, src_level, 0, src_box); } static void diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 0bfafd93398..1053706ad57 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -577,8 +577,8 @@ static void r300_resource_copy_region(struct pipe_context *pipe, src_view = r300_create_sampler_view_custom(pipe, src, &src_templ, src_width0, src_height0); r300_blitter_begin(r300, R300_COPY); - util_blitter_copy_texture_view(r300->blitter, dst_view, dstx, dsty, - src_view, src_box, + util_blitter_copy_texture_view(r300->blitter, dst_view, ~0, dstx, dsty, + src_view, 0, src_box, src_width0, src_height0, PIPE_MASK_RGBAZS); r300_blitter_end(r300); diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 3121bb197ad..42fec3f3f0d 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -434,8 +434,8 @@ static void r600_resource_copy_region(struct pipe_context *ctx, } r600_blitter_begin(ctx, R600_COPY_TEXTURE); - util_blitter_copy_texture(rctx->blitter, dst, dst_level, dstx, dsty, dstz, - src, src_level, psbox); + util_blitter_copy_texture(rctx->blitter, dst, dst_level, ~0, dstx, dsty, dstz, + src, src_level, 0, psbox); r600_blitter_end(ctx); if (restore_orig[0]) -- 2.30.2