diff options
Diffstat (limited to 'mesalib/src/gallium/auxiliary')
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blit.c | 10 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blitter.c | 344 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blitter.h | 36 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_inlines.h | 20 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_simple_shaders.c | 133 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_simple_shaders.h | 20 |
6 files changed, 451 insertions, 112 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_blit.c b/mesalib/src/gallium/auxiliary/util/u_blit.c index 3887e65fb..bf1c392cd 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blit.c +++ b/mesalib/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, @@ -464,7 +464,7 @@ util_blit_pixels(struct blit_state *ctx, dstX0, dstY0, dstX1, dstY1); src_format = util_format_linear(src_tex->format); - dst_format = util_format_linear(dst->format); + dst_format = util_format_linear(dst->texture->format); /* See whether we will blit depth or stencil. */ is_depth = util_format_has_depth(src_desc); diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c index fa71f25ea..a95e1b535 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.c +++ b/mesalib/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 ctx->fs_texfetch_col[tex_target]; + return *shader; + } else { + void **shader = &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 *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 ctx->fs_texfetch_depth[tex_target]; + 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 *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); - return ctx->fs_texfetch_depthstencil[tex_target]; + *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); + + *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 ctx->fs_texfetch_stencil[tex_target]; + return *shader; + } } static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx) @@ -879,7 +962,7 @@ void util_blitter_clear(struct blitter_context *blitter, NULL, NULL); } -void util_blitter_clear_depth_custom(struct blitter_context *blitter, +void util_blitter_custom_clear_depth(struct blitter_context *blitter, unsigned width, unsigned height, double depth, void *custom_dsa) { @@ -889,10 +972,26 @@ void util_blitter_clear_depth_custom(struct blitter_context *blitter, } static -boolean is_overlap(unsigned sx1, unsigned sx2, unsigned sy1, unsigned sy2, - unsigned dx1, unsigned dx2, unsigned dy1, unsigned dy2) +boolean is_overlap(unsigned dstx, unsigned dsty, unsigned dstz, + const struct pipe_box *srcbox) { - return sx1 < dx2 && sx2 > dx1 && sy1 < dy2 && sy2 > dy1; + struct pipe_box src = *srcbox; + + if (src.width < 0) { + src.x += src.width; + src.width = -src.width; + } + if (src.height < 0) { + src.y += src.height; + src.height = -src.height; + } + if (src.depth < 0) { + src.z += src.depth; + src.depth = -src.depth; + } + return src.x < dstx+src.width && src.x+src.width > dstx && + src.y < dsty+src.height && src.y+src.height > dsty && + src.z < dstz+src.depth && src.z+src.depth > dstz; } void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, @@ -989,10 +1088,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 +1111,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 +1121,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) @@ -1032,8 +1133,8 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter, struct pipe_context *pipe = ctx->base.pipe; struct pipe_framebuffer_state fb_state; enum pipe_texture_target src_target = src->texture->target; - unsigned width = srcbox->width; - unsigned height = srcbox->height; + int abs_width = abs(srcbox->width); + int abs_height = abs(srcbox->height); boolean blit_stencil, blit_depth; const struct util_format_description *src_desc = util_format_description(src->format); @@ -1053,8 +1154,7 @@ void util_blitter_copy_texture_view(struct blitter_context *blitter, /* Sanity checks. */ if (dst->texture == src->texture && dst->u.tex.level == src->u.tex.first_level) { - assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height, - dstx, dstx + width, dsty, dsty + height)); + assert(!is_overlap(dstx, dsty, 0, srcbox)); } /* XXX should handle 3d regions */ assert(srcbox->depth == 1); @@ -1077,17 +1177,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 +1196,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 +1227,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+srcbox->width, srcbox->y+srcbox->height, coord.f); + + /* Draw. */ + blitter->draw_rectangle(blitter, dstx, dsty, dstx+abs_width, dsty+abs_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 + srcbox->width, srcbox->y + srcbox->height); + blitter_draw(ctx, dstx, dsty, dstx+abs_width, dsty+abs_height, 0); } blitter_restore_vertex_states(ctx); @@ -1298,6 +1383,7 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter, void util_blitter_custom_depth_stencil(struct blitter_context *blitter, struct pipe_surface *zsurf, struct pipe_surface *cbsurf, + unsigned sample_mask, void *dsa_stage, float depth) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; @@ -1333,6 +1419,7 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter, } fb_state.zsbuf = zsurf; pipe->set_framebuffer_state(pipe, &fb_state); + pipe->set_sample_mask(pipe, sample_mask); blitter_set_common_draw_rect_state(ctx); blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height); @@ -1404,3 +1491,64 @@ void util_blitter_copy_buffer(struct blitter_context *blitter, blitter_unset_running_flag(ctx); pipe_so_target_reference(&so_target, NULL); } + +/* probably radeon specific */ +void util_blitter_custom_resolve_color(struct blitter_context *blitter, + struct pipe_resource *dst, + unsigned dst_level, + unsigned dst_layer, + struct pipe_resource *src, + unsigned src_layer, + void *custom_blend) +{ + struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; + struct pipe_context *pipe = ctx->base.pipe; + struct pipe_framebuffer_state fb_state; + struct pipe_surface *srcsurf, *dstsurf, surf_tmpl; + + blitter_set_running_flag(ctx); + blitter_check_saved_vertex_states(ctx); + blitter_check_saved_fragment_states(ctx); + + /* bind states */ + pipe->bind_blend_state(pipe, custom_blend); + pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); + pipe->bind_vertex_elements_state(pipe, ctx->velem_state); + pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE)); + + memset(&surf_tmpl, 0, sizeof(surf_tmpl)); + surf_tmpl.format = dst->format; + surf_tmpl.u.tex.level = dst_level; + surf_tmpl.u.tex.first_layer = dst_layer; + surf_tmpl.u.tex.last_layer = dst_layer; + surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; + + dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl); + + surf_tmpl.u.tex.level = 0; + surf_tmpl.u.tex.first_layer = src_layer; + surf_tmpl.u.tex.last_layer = src_layer; + + srcsurf = pipe->create_surface(pipe, src, &surf_tmpl); + + /* set a framebuffer state */ + fb_state.width = src->width0; + fb_state.height = src->height0; + fb_state.nr_cbufs = 2; + fb_state.cbufs[0] = srcsurf; + fb_state.cbufs[1] = dstsurf; + fb_state.zsbuf = NULL; + pipe->set_framebuffer_state(pipe, &fb_state); + + blitter_set_common_draw_rect_state(ctx); + blitter_set_dst_dimensions(ctx, src->width0, src->height0); + blitter->draw_rectangle(blitter, 0, 0, src->width0, src->height0, + 0, 0, NULL); + blitter_restore_fb_state(ctx); + blitter_restore_vertex_states(ctx); + blitter_restore_fragment_states(ctx); + blitter_unset_running_flag(ctx); + + pipe_surface_reference(&srcsurf, NULL); + pipe_surface_reference(&dstsurf, NULL); +} diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.h b/mesalib/src/gallium/auxiliary/util/u_blitter.h index 7600391c5..f227902c1 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.h +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.h @@ -156,10 +156,6 @@ void util_blitter_clear(struct blitter_context *blitter, const union pipe_color_union *color, double depth, unsigned stencil); -void util_blitter_clear_depth_custom(struct blitter_context *blitter, - unsigned width, unsigned height, - double depth, void *custom_dsa); - /** * Check if the blitter (with the help of the driver) can blit between * the two resources. @@ -178,6 +174,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 +190,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 +218,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); @@ -288,11 +290,33 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter, unsigned dstx, unsigned dsty, unsigned width, unsigned height); +/* The following functions are customized variants of the clear functions. + * Some drivers use them internally to do things like MSAA resolve + * and resource decompression. It usually consists of rendering a full-screen + * quad with a special blend or DSA state. + */ + +/* Used by r300g for depth decompression. */ +void util_blitter_custom_clear_depth(struct blitter_context *blitter, + unsigned width, unsigned height, + double depth, void *custom_dsa); + +/* Used by r600g for depth decompression. */ void util_blitter_custom_depth_stencil(struct blitter_context *blitter, struct pipe_surface *zsurf, struct pipe_surface *cbsurf, + unsigned sample_mask, void *dsa_stage, float depth); +/* Used by r600g for MSAA color resolve. */ +void util_blitter_custom_resolve_color(struct blitter_context *blitter, + struct pipe_resource *dst, + unsigned dst_level, + unsigned dst_layer, + struct pipe_resource *src, + unsigned src_layer, + void *custom_blend); + /* The functions below should be used to save currently bound constant state * objects inside a driver. The objects are automatically restored at the end * of the util_blitter_{clear, copy_region, fill_region} functions and then diff --git a/mesalib/src/gallium/auxiliary/util/u_inlines.h b/mesalib/src/gallium/auxiliary/util/u_inlines.h index 2d603e4dd..a1ece415f 100644 --- a/mesalib/src/gallium/auxiliary/util/u_inlines.h +++ b/mesalib/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/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c index 3476b6ce0..5f0134d70 100644 --- a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/mesalib/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 <stdio.h> /* 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/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h index 0764998a3..e4ffde652 100644 --- a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h +++ b/mesalib/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 |