X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Futil%2Fu_blitter.c;h=183ffe5670ff01dcbd0fab4b6f9e3567f43f0ad2;hb=992382762a74fd834926fd2c3cd9e14a186e2dd5;hp=1f3246208bace7079955e9821e615873f6fc3076;hpb=16d1fb30a91bde0f283a60ce07bf3b3477f1e5fe;p=mesa.git diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 1f3246208ba..183ffe5670f 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, resource_copy_region, - * and resource_fill_region functions. + * Blitter utility to facilitate acceleration of the clear, clear_render_target, clear_depth_stencil + * resource_copy_region functions. * * @author Marek Olšák */ @@ -88,6 +88,7 @@ struct blitter_context_priv void *dsa_write_depth_stencil; void *dsa_write_depth_keep_stencil; void *dsa_keep_depth_stencil; + void *dsa_keep_depth_write_stencil; void *velem_state; @@ -161,8 +162,12 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) dsa.stencil[0].writemask = 0xff; ctx->dsa_write_depth_stencil = pipe->create_depth_stencil_alpha_state(pipe, &dsa); - /* The DSA state objects which write depth and stencil are created - * on-demand. */ + + + dsa.depth.enabled = 0; + dsa.depth.writemask = 0; + ctx->dsa_keep_depth_write_stencil = + pipe->create_depth_stencil_alpha_state(pipe, &dsa); /* sampler state */ sampler_state = &ctx->template_sampler_state; @@ -234,6 +239,7 @@ void util_blitter_destroy(struct blitter_context *blitter) pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); + pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); pipe->delete_rasterizer_state(pipe, ctx->rs_state); pipe->delete_vs_state(pipe, ctx->vs_col); @@ -516,6 +522,26 @@ void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs) return ctx->fs_col[num_cbufs]; } +/** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */ +static unsigned +pipe_tex_to_tgsi_tex(unsigned pipe_tex_target) +{ + switch (pipe_tex_target) { + case PIPE_TEXTURE_1D: + return TGSI_TEXTURE_1D; + case PIPE_TEXTURE_2D: + return TGSI_TEXTURE_2D; + case PIPE_TEXTURE_3D: + return TGSI_TEXTURE_3D; + case PIPE_TEXTURE_CUBE: + return TGSI_TEXTURE_CUBE; + default: + assert(0 && "unexpected texture target"); + return TGSI_TEXTURE_UNKNOWN; + } +} + + static INLINE void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, unsigned tex_target) @@ -526,25 +552,10 @@ void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, /* Create the fragment shader on-demand. */ if (!ctx->fs_texfetch_col[tex_target]) { - switch (tex_target) { - case PIPE_TEXTURE_2D: - ctx->fs_texfetch_col[PIPE_TEXTURE_2D] = - util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D); - break; - case PIPE_TEXTURE_3D: - ctx->fs_texfetch_col[PIPE_TEXTURE_3D] = - util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D); - break; - case PIPE_TEXTURE_CUBE: - ctx->fs_texfetch_col[PIPE_TEXTURE_CUBE] = - util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE); - break; - case PIPE_TEXTURE_1D: - default: - ctx->fs_texfetch_col[PIPE_TEXTURE_1D] = - util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D); - tex_target = PIPE_TEXTURE_1D; /* for the default case */ - } + unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target); + + ctx->fs_texfetch_col[tex_target] = + util_make_fragment_tex_shader(pipe, tgsi_tex, TGSI_INTERPOLATE_LINEAR); } return ctx->fs_texfetch_col[tex_target]; @@ -560,25 +571,11 @@ void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx, /* Create the fragment shader on-demand. */ if (!ctx->fs_texfetch_depth[tex_target]) { - switch (tex_target) { - case PIPE_TEXTURE_2D: - ctx->fs_texfetch_depth[PIPE_TEXTURE_2D] = - util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_2D); - break; - case PIPE_TEXTURE_3D: - ctx->fs_texfetch_depth[PIPE_TEXTURE_3D] = - util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_3D); - break; - case PIPE_TEXTURE_CUBE: - ctx->fs_texfetch_depth[PIPE_TEXTURE_CUBE] = - util_make_fragment_tex_shader_writedepth(pipe,TGSI_TEXTURE_CUBE); - break; - case PIPE_TEXTURE_1D: - default: - ctx->fs_texfetch_depth[PIPE_TEXTURE_1D] = - util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_1D); - tex_target = PIPE_TEXTURE_1D; /* for the default case */ - } + unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target); + + ctx->fs_texfetch_depth[tex_target] = + util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex, + TGSI_INTERPOLATE_LINEAR); } return ctx->fs_texfetch_depth[tex_target]; @@ -605,11 +602,19 @@ void util_blitter_clear(struct blitter_context *blitter, else pipe->bind_blend_state(pipe, ctx->blend_keep_color); - if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) { + if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { sr.ref_value[0] = stencil & 0xff; pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); pipe->set_stencil_ref(pipe, &sr); } + else if (clear_buffers & PIPE_CLEAR_DEPTH) { + pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); + } + else if (clear_buffers & PIPE_CLEAR_STENCIL) { + sr.ref_value[0] = stencil & 0xff; + pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); + pipe->set_stencil_ref(pipe, &sr); + } else pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); @@ -766,48 +771,21 @@ void util_blitter_copy_region(struct blitter_context *blitter, pipe_surface_reference(&dstsurf, NULL); } -/* Fill a region of a surface with a constant value. */ -void util_blitter_fill_region(struct blitter_context *blitter, - struct pipe_resource *dst, - struct pipe_subresource subdst, - unsigned dstx, unsigned dsty, unsigned dstz, - unsigned width, unsigned height, - unsigned value) +/* Clear a region of a color surface to a constant value. */ +void util_blitter_clear_render_target(struct blitter_context *blitter, + struct pipe_surface *dstsurf, + const float *rgba, + unsigned dstx, unsigned dsty, + 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_surface *dstsurf; struct pipe_framebuffer_state fb_state; - float rgba[4]; - ubyte ub_rgba[4] = {0}; - union util_color color; - int i; - assert(dst); - if (!dst) + assert(dstsurf->texture); + if (!dstsurf->texture) return; - /* 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->target, - dst->nr_samples, - PIPE_BIND_RENDER_TARGET, 0)) { - util_resource_fill_region(pipe, dst, subdst, dstx, dsty, dstz, - width, height, value); - return; - } - - dstsurf = screen->get_tex_surface(screen, dst, subdst.face, subdst.level, - dstz, PIPE_BIND_RENDER_TARGET); - - /* unpack the color */ - color.ui = value; - util_unpack_color_ub(dst->format, &color, - ub_rgba, ub_rgba+1, ub_rgba+2, ub_rgba+3); - for (i = 0; i < 4; i++) - rgba[i] = ubyte_to_float(ub_rgba[i]); - /* check the saved state */ blitter_check_saved_CSOs(ctx); assert(blitter->saved_fb_state.nr_cbufs != ~0); @@ -832,6 +810,63 @@ void util_blitter_fill_region(struct blitter_context *blitter, blitter_set_rectangle(ctx, 0, 0, width, height, dstsurf->width, dstsurf->height, 0); blitter_draw_quad(ctx); blitter_restore_CSOs(ctx); +} - pipe_surface_reference(&dstsurf, NULL); +/* Clear a region of a depth stencil surface. */ +void util_blitter_clear_depth_stencil(struct blitter_context *blitter, + struct pipe_surface *dstsurf, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) +{ + struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; + struct pipe_context *pipe = ctx->pipe; + struct pipe_framebuffer_state fb_state; + struct pipe_stencil_ref sr = { { 0 } }; + + assert(dstsurf->texture); + if (!dstsurf->texture) + return; + + /* check the saved state */ + blitter_check_saved_CSOs(ctx); + assert(blitter->saved_fb_state.nr_cbufs != ~0); + + /* bind CSOs */ + pipe->bind_blend_state(pipe, ctx->blend_keep_color); + if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { + sr.ref_value[0] = stencil & 0xff; + pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); + pipe->set_stencil_ref(pipe, &sr); + } + else if (clear_flags & PIPE_CLEAR_DEPTH) { + pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); + } + else if (clear_flags & PIPE_CLEAR_STENCIL) { + sr.ref_value[0] = stencil & 0xff; + pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); + pipe->set_stencil_ref(pipe, &sr); + } + else + /* hmm that should be illegal probably, or make it a no-op somewhere */ + pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); + + pipe->bind_rasterizer_state(pipe, ctx->rs_state); + pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0)); + pipe->bind_vs_state(pipe, ctx->vs_col); + pipe->bind_vertex_elements_state(pipe, ctx->velem_state); + + /* set a framebuffer state */ + fb_state.width = dstsurf->width; + fb_state.height = dstsurf->height; + fb_state.nr_cbufs = 0; + fb_state.cbufs[0] = 0; + fb_state.zsbuf = dstsurf; + pipe->set_framebuffer_state(pipe, &fb_state); + + blitter_set_rectangle(ctx, 0, 0, width, height, dstsurf->width, dstsurf->height, depth); + blitter_draw_quad(ctx); + blitter_restore_CSOs(ctx); }