diff options
author | marha <marha@users.sourceforge.net> | 2013-12-22 12:51:45 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2013-12-22 12:51:45 +0100 |
commit | c81020559f329a516191927222b3698ba7370aca (patch) | |
tree | 6f004f5723ca41881b2ba703ed619a92faebfe16 /mesalib/src/gallium | |
parent | c043f97a8572e1f509251288d8bcd70d0fb96770 (diff) | |
download | vcxsrv-c81020559f329a516191927222b3698ba7370aca.tar.gz vcxsrv-c81020559f329a516191927222b3698ba7370aca.tar.bz2 vcxsrv-c81020559f329a516191927222b3698ba7370aca.zip |
libxtrans fontconfig glproto libX11 libxcb xcbproto mesa xserver pixman xkeyboard-config git update 22 Dec 2013
xserver commit a68df147421da21528b5be2d34678383922fa352
libxcb commit f653464554469b5767f1c99abced25a76bace047
libxcb/xcb-proto commit 4087fc682c5ceb849b74442e17a6b73176e5eecb
xkeyboard-config commit a224a636139d22e1dc7ca7d23782cd656e87bcf5
libX11 commit 3d69b0a83e62f8f6fbdd952fc49cdbdf8825e1e6
libXdmcp commit 089081dca4ba3598c6f9bf401c029378943b5854
libXext commit bb24f2970f2e425f4df90c9b73d078ad15a73fbb
libfontenc commit 3acba630d8b57084f7e92c15732408711ed5137a
libXinerama commit edd95182b26eb5d576d4878c559e0f17dddaa909
libXau commit 304a11be4727c5a7feeb2501e8e001466f8ce84e
xkbcomp commit e3e6e938535532bfad175c1635256ab7fb3ac943
pixman commit 945ab7a6f3eb6241f07e8f094dc0e647d1f10d9d
xextproto commit 3f355f138d6df57e067458a20f47307883048adb
randrproto commit e7526e6b5fe0966929cda10b2ded0258413744db
glproto commit f84853d97d5749308992412a215fa518b6536eb3
mkfontscale commit 880a0c4733e62e54e6a0f1238c7430727d23657b
xwininfo commit ba0d1b0da21d2dbdd81098ed5778f3792b472e13
libXft commit 4acfdaf95adb0a05c2a25550bdde036c865902f4
libXmu commit 22d9c590901e121936f50dee97dc60c4f7defb63
libxtrans commit 2c0a7840a28ae696e80e73157856d7a049fdf6c7
fontconfig commit 5c725f2f5829238d16116f782d00d8bb0defaf08
mesa commit 2efe7927d38983029784825fc4897e9b77aa237e
Diffstat (limited to 'mesalib/src/gallium')
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blitter.c | 286 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_blitter.h | 13 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_clear.h | 7 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_framebuffer.c | 24 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_framebuffer.h | 5 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_simple_shaders.c | 180 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_simple_shaders.h | 14 |
7 files changed, 448 insertions, 81 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c index b95cbab12..9246bd722 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.c +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c @@ -51,6 +51,12 @@ #define INVALID_PTR ((void*)~0) +#define GET_CLEAR_BLEND_STATE_IDX(clear_buffers) \ + ((clear_buffers) / PIPE_CLEAR_COLOR0) + +#define NUM_RESOLVE_FRAG_SHADERS 5 /* MSAA 2x, 4x, 8x, 16x, 32x */ +#define GET_MSAA_RESOLVE_FS_IDX(nr_samples) (util_logbase2(nr_samples)-1) + struct blitter_context_priv { struct blitter_context base; @@ -65,6 +71,7 @@ struct blitter_context_priv /* Vertex shaders. */ void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/ void *vs_pos_only; /**< Vertex shader which passes pos to the output.*/ + void *vs_layered; /**< Vertex shader which sets LAYER = INSTANCEID. */ /* Fragment shaders. */ void *fs_empty; @@ -87,8 +94,14 @@ struct blitter_context_priv void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES]; void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES]; + /* FS which outputs an average of all samples. */ + void *fs_resolve[PIPE_MAX_TEXTURE_TYPES][NUM_RESOLVE_FRAG_SHADERS][2]; + void *fs_resolve_sint[PIPE_MAX_TEXTURE_TYPES][NUM_RESOLVE_FRAG_SHADERS][2]; + void *fs_resolve_uint[PIPE_MAX_TEXTURE_TYPES][NUM_RESOLVE_FRAG_SHADERS][2]; + /* Blend state. */ void *blend[PIPE_MASK_RGBA+1]; /**< blend state with writemask */ + void *blend_clear[GET_CLEAR_BLEND_STATE_IDX(PIPE_CLEAR_COLOR)+1]; /* Depth stencil alpha state. */ void *dsa_write_depth_stencil; @@ -295,6 +308,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) util_make_vertex_passthrough_shader(pipe, 2, semantic_names, semantic_indices); } + if (ctx->has_stream_out) { struct pipe_stream_output_info so; const uint semantic_names[] = { TGSI_SEMANTIC_POSITION }; @@ -310,6 +324,11 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) semantic_indices, &so); } + if (pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) && + pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) { + ctx->vs_layered = util_make_layered_clear_vertex_shader(pipe); + } + /* set invariant vertex coordinates */ for (i = 0; i < 4; i++) ctx->vertices[i][0][3] = 1; /*v.w*/ @@ -323,11 +342,15 @@ void util_blitter_destroy(struct blitter_context *blitter) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = blitter->pipe; - int i; + int i, j, f; for (i = 0; i <= PIPE_MASK_RGBA; i++) { pipe->delete_blend_state(pipe, ctx->blend[i]); } + for (i = 0; i < Elements(ctx->blend_clear); i++) { + if (ctx->blend_clear[i]) + pipe->delete_blend_state(pipe, ctx->blend_clear[i]); + } pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); @@ -357,7 +380,23 @@ void util_blitter_destroy(struct blitter_context *blitter) ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i]); if (ctx->fs_texfetch_stencil[i]) ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i]); + + for (j = 0; j< Elements(ctx->fs_resolve[i]); j++) + for (f = 0; f < 2; f++) + if (ctx->fs_resolve[i][j][f]) + ctx->delete_fs_state(pipe, ctx->fs_resolve[i][j][f]); + + for (j = 0; j< Elements(ctx->fs_resolve_sint[i]); j++) + for (f = 0; f < 2; f++) + if (ctx->fs_resolve_sint[i][j][f]) + ctx->delete_fs_state(pipe, ctx->fs_resolve_sint[i][j][f]); + + for (j = 0; j< Elements(ctx->fs_resolve_uint[i]); j++) + for (f = 0; f < 2; f++) + if (ctx->fs_resolve_uint[i][j][f]) + ctx->delete_fs_state(pipe, ctx->fs_resolve_uint[i][j][f]); } + ctx->delete_fs_state(pipe, ctx->fs_empty); ctx->delete_fs_state(pipe, ctx->fs_write_one_cbuf); ctx->delete_fs_state(pipe, ctx->fs_write_all_cbufs); @@ -711,22 +750,60 @@ static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx, } static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, + enum pipe_format format, enum pipe_texture_target target, - unsigned nr_samples) + unsigned src_nr_samples, + unsigned dst_nr_samples, + unsigned filter) { struct pipe_context *pipe = ctx->base.pipe; + unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, src_nr_samples); assert(target < PIPE_MAX_TEXTURE_TYPES); - if (nr_samples > 1) { - void **shader = &ctx->fs_texfetch_col_msaa[target]; + if (src_nr_samples > 1) { + void **shader; - /* Create the fragment shader on-demand. */ - if (!*shader) { - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, - nr_samples); + if (dst_nr_samples <= 1) { + /* The destination has one sample, so we'll do color resolve. */ + boolean is_uint, is_sint; + unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples); - *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex); + is_uint = util_format_is_pure_uint(format); + is_sint = util_format_is_pure_sint(format); + + assert(filter < 2); + + if (is_uint) + shader = &ctx->fs_resolve_uint[target][index][filter]; + else if (is_sint) + shader = &ctx->fs_resolve_sint[target][index][filter]; + else + shader = &ctx->fs_resolve[target][index][filter]; + + if (!*shader) { + if (filter == PIPE_TEX_FILTER_LINEAR) { + *shader = util_make_fs_msaa_resolve_bilinear(pipe, tgsi_tex, + src_nr_samples, + is_uint, is_sint); + } + else { + *shader = util_make_fs_msaa_resolve(pipe, tgsi_tex, + src_nr_samples, + is_uint, is_sint); + } + } + } + else { + /* The destination has multiple samples, we'll do + * an MSAA->MSAA copy. + */ + shader = &ctx->fs_texfetch_col_msaa[target]; + + /* Create the fragment shader on-demand. */ + if (!*shader) { + *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex); + } } return *shader; @@ -735,11 +812,8 @@ static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, /* Create the fragment shader on-demand. */ if (!*shader) { - unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); - - *shader = - util_make_fragment_tex_shader(pipe, tgsi_tex, - TGSI_INTERPOLATE_LINEAR); + *shader = util_make_fragment_tex_shader(pipe, tgsi_tex, + TGSI_INTERPOLATE_LINEAR); } return *shader; @@ -864,7 +938,7 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_screen *screen = blitter->pipe->screen; - unsigned i, target, max_samples; + unsigned samples, j, f, target, max_samples; boolean has_arraytex, has_cubearraytex; max_samples = ctx->has_texture_multisample ? 2 : 1; @@ -874,7 +948,7 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter) PIPE_CAP_CUBE_MAP_ARRAY) != 0; /* It only matters if i <= 1 or > 1. */ - for (i = 1; i <= max_samples; i++) { + for (samples = 1; samples <= max_samples; samples++) { for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) { if (!has_arraytex && (target == PIPE_TEXTURE_1D_ARRAY || @@ -885,29 +959,55 @@ void util_blitter_cache_all_shaders(struct blitter_context *blitter) (target == PIPE_TEXTURE_CUBE_ARRAY)) continue; - if (i > 1 && + if (samples > 1 && (target != PIPE_TEXTURE_2D && target != PIPE_TEXTURE_2D_ARRAY)) continue; - blitter_get_fs_texfetch_col(ctx, target, i); - blitter_get_fs_texfetch_depth(ctx, target, i); + /* If samples == 1, the shaders read one texel. If samples >= 1, + * they read one sample. + */ + blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT, target, + samples, samples, 0); + blitter_get_fs_texfetch_depth(ctx, target, samples); if (ctx->has_stencil_export) { - blitter_get_fs_texfetch_depthstencil(ctx, target, i); - blitter_get_fs_texfetch_stencil(ctx, target, i); + blitter_get_fs_texfetch_depthstencil(ctx, target, samples); + blitter_get_fs_texfetch_stencil(ctx, target, samples); + } + + if (samples == 1) + continue; + + /* MSAA resolve shaders. */ + for (j = 2; j < 32; j++) { + if (!screen->is_format_supported(screen, PIPE_FORMAT_R32_FLOAT, + target, j, + PIPE_BIND_SAMPLER_VIEW)) { + continue; + } + + for (f = 0; f < 2; f++) { + blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT, target, + j, 1, f); + blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT, target, + j, 1, f); + blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT, target, + j, 1, f); + } } } } } static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx, - boolean scissor) + boolean scissor, + boolean vs_layered) { struct pipe_context *pipe = ctx->base.pipe; pipe->bind_rasterizer_state(pipe, scissor ? ctx->rs_state_scissor : ctx->rs_state); - pipe->bind_vs_state(pipe, ctx->vs); + pipe->bind_vs_state(pipe, vs_layered ? ctx->vs_layered : ctx->vs); if (ctx->has_geometry_shader) pipe->bind_gs_state(pipe, NULL); if (ctx->has_stream_out) @@ -915,19 +1015,24 @@ static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx, } static void blitter_draw(struct blitter_context_priv *ctx, - int x1, int y1, int x2, int y2, float depth) + int x1, int y1, int x2, int y2, float depth, + unsigned num_instances) { - struct pipe_resource *buf = NULL; - unsigned offset = 0; + struct pipe_context *pipe = ctx->base.pipe; + struct pipe_vertex_buffer vb = {0}; blitter_set_rectangle(ctx, x1, y1, x2, y2, depth); + vb.stride = 8 * sizeof(float); + u_upload_data(ctx->upload, 0, sizeof(ctx->vertices), ctx->vertices, - &offset, &buf); + &vb.buffer_offset, &vb.buffer); u_upload_unmap(ctx->upload); - util_draw_vertex_buffer(ctx->base.pipe, NULL, buf, ctx->base.vb_slot, - offset, PIPE_PRIM_TRIANGLE_FAN, 4, 2); - pipe_resource_reference(&buf, NULL); + + pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb); + util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4, + 0, num_instances); + pipe_resource_reference(&vb.buffer, NULL); } void util_blitter_draw_rectangle(struct blitter_context *blitter, @@ -949,11 +1054,47 @@ void util_blitter_draw_rectangle(struct blitter_context *blitter, default:; } - blitter_draw(ctx, x1, y1, x2, y2, depth); + blitter_draw(ctx, x1, y1, x2, y2, depth, 1); +} + +static void *get_clear_blend_state(struct blitter_context_priv *ctx, + unsigned clear_buffers) +{ + struct pipe_context *pipe = ctx->base.pipe; + int index; + + clear_buffers &= PIPE_CLEAR_COLOR; + + /* Return an existing blend state. */ + if (!clear_buffers) + return ctx->blend[0]; + + index = GET_CLEAR_BLEND_STATE_IDX(clear_buffers); + + if (ctx->blend_clear[index]) + return ctx->blend_clear[index]; + + /* Create a new one. */ + { + struct pipe_blend_state blend = {0}; + unsigned i; + + blend.independent_blend_enable = 1; + + for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { + if (clear_buffers & (PIPE_CLEAR_COLOR0 << i)) { + blend.rt[i].colormask = PIPE_MASK_RGBA; + } + } + + ctx->blend_clear[index] = pipe->create_blend_state(pipe, &blend); + } + return ctx->blend_clear[index]; } static void util_blitter_clear_custom(struct blitter_context *blitter, unsigned width, unsigned height, + unsigned num_layers, unsigned clear_buffers, const union pipe_color_union *color, double depth, unsigned stencil, @@ -963,6 +1104,8 @@ static void util_blitter_clear_custom(struct blitter_context *blitter, struct pipe_context *pipe = ctx->base.pipe; struct pipe_stencil_ref sr = { { 0 } }; + assert(ctx->vs_layered || num_layers <= 1); + blitter_set_running_flag(ctx); blitter_check_saved_vertex_states(ctx); blitter_check_saved_fragment_states(ctx); @@ -971,10 +1114,8 @@ static void util_blitter_clear_custom(struct blitter_context *blitter, /* bind states */ if (custom_blend) { pipe->bind_blend_state(pipe, custom_blend); - } else if (clear_buffers & PIPE_CLEAR_COLOR) { - pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]); } else { - pipe->bind_blend_state(pipe, ctx->blend[0]); + pipe->bind_blend_state(pipe, get_clear_blend_state(ctx, clear_buffers)); } if (custom_dsa) { @@ -996,10 +1137,18 @@ static void util_blitter_clear_custom(struct blitter_context *blitter, ctx->bind_fs_state(pipe, ctx->fs_write_all_cbufs); pipe->set_sample_mask(pipe, ~0); - blitter_set_common_draw_rect_state(ctx, FALSE); blitter_set_dst_dimensions(ctx, width, height); - blitter->draw_rectangle(blitter, 0, 0, width, height, (float) depth, - UTIL_BLITTER_ATTRIB_COLOR, color); + + if (num_layers > 1 && ctx->vs_layered) { + blitter_set_common_draw_rect_state(ctx, FALSE, TRUE); + blitter_set_clear_color(ctx, color); + blitter_draw(ctx, 0, 0, width, height, depth, num_layers); + } + else { + blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); + blitter->draw_rectangle(blitter, 0, 0, width, height, (float) depth, + UTIL_BLITTER_ATTRIB_COLOR, color); + } blitter_restore_vertex_states(ctx); blitter_restore_fragment_states(ctx); @@ -1008,12 +1157,12 @@ static void util_blitter_clear_custom(struct blitter_context *blitter, } void util_blitter_clear(struct blitter_context *blitter, - unsigned width, unsigned height, + unsigned width, unsigned height, unsigned num_layers, unsigned clear_buffers, const union pipe_color_union *color, double depth, unsigned stencil) { - util_blitter_clear_custom(blitter, width, height, + util_blitter_clear_custom(blitter, width, height, num_layers, clear_buffers, color, depth, stencil, NULL, NULL); } @@ -1023,7 +1172,7 @@ void util_blitter_custom_clear_depth(struct blitter_context *blitter, double depth, void *custom_dsa) { static const union pipe_color_union color; - util_blitter_clear_custom(blitter, width, height, 0, &color, depth, 0, + util_blitter_clear_custom(blitter, width, height, 0, 0, &color, depth, 0, NULL, custom_dsa); } @@ -1137,11 +1286,10 @@ static boolean is_blit_generic_supported(struct blitter_context *blitter, boolean util_blitter_is_copy_supported(struct blitter_context *blitter, const struct pipe_resource *dst, - const struct pipe_resource *src, - unsigned mask) + const struct pipe_resource *src) { return is_blit_generic_supported(blitter, dst, dst->format, - src, src->format, mask); + src, src->format, PIPE_MASK_RGBAZS); } boolean util_blitter_is_blit_supported(struct blitter_context *blitter, @@ -1159,8 +1307,7 @@ void util_blitter_copy_texture(struct blitter_context *blitter, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, - const struct pipe_box *srcbox, unsigned mask, - boolean copy_all_samples) + const struct pipe_box *srcbox) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx->base.pipe; @@ -1185,8 +1332,7 @@ void util_blitter_copy_texture(struct blitter_context *blitter, /* Copy. */ util_blitter_blit_generic(blitter, dst_view, &dstbox, src_view, srcbox, src->width0, src->height0, - mask, PIPE_TEX_FILTER_NEAREST, NULL, - copy_all_samples); + PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); @@ -1199,14 +1345,14 @@ void util_blitter_blit_generic(struct blitter_context *blitter, const struct pipe_box *srcbox, unsigned src_width0, unsigned src_height0, unsigned mask, unsigned filter, - const struct pipe_scissor_state *scissor, - boolean copy_all_samples) + const struct pipe_scissor_state *scissor) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx->base.pipe; struct pipe_framebuffer_state fb_state; enum pipe_texture_target src_target = src->texture->target; unsigned src_samples = src->texture->nr_samples; + unsigned dst_samples = dst->texture->nr_samples; boolean has_depth, has_stencil, has_color; boolean blit_stencil, blit_depth, blit_color; void *sampler_state; @@ -1231,6 +1377,12 @@ void util_blitter_blit_generic(struct blitter_context *blitter, return; } + if (blit_stencil || + (dstbox->width == abs(srcbox->width) && + dstbox->height == abs(srcbox->height))) { + filter = PIPE_TEX_FILTER_NEAREST; + } + /* Check whether the states are properly saved. */ blitter_set_running_flag(ctx); blitter_check_saved_vertex_states(ctx); @@ -1273,16 +1425,12 @@ void util_blitter_blit_generic(struct blitter_context *blitter, pipe->bind_blend_state(pipe, ctx->blend[mask & PIPE_MASK_RGBA]); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); ctx->bind_fs_state(pipe, - blitter_get_fs_texfetch_col(ctx, src_target, - src_samples)); + blitter_get_fs_texfetch_col(ctx, src->format, src_target, + src_samples, dst_samples, filter)); } /* Set the linear filter only for scaled color non-MSAA blits. */ - if (filter == PIPE_TEX_FILTER_LINEAR && - !blit_depth && !blit_stencil && - src_samples <= 1 && - (dstbox->width != abs(srcbox->width) || - dstbox->height != abs(srcbox->height))) { + if (filter == PIPE_TEX_FILTER_LINEAR) { if (src_target == PIPE_TEXTURE_RECT) { sampler_state = ctx->sampler_state_rect_linear; } else { @@ -1341,7 +1489,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter, pipe->set_scissor_states(pipe, 0, 1, scissor); } - blitter_set_common_draw_rect_state(ctx, scissor != NULL); + blitter_set_common_draw_rect_state(ctx, scissor != NULL, FALSE); blitter_set_dst_dimensions(ctx, dst->width, dst->height); if ((src_target == PIPE_TEXTURE_1D || @@ -1388,10 +1536,9 @@ void util_blitter_blit_generic(struct blitter_context *blitter, pipe->set_framebuffer_state(pipe, &fb_state); /* See if we need to blit a multisample or singlesample buffer. */ - if (copy_all_samples && - src_samples == dst->texture->nr_samples && - dst->texture->nr_samples > 1) { - unsigned i, max_sample = MAX2(dst->texture->nr_samples, 1) - 1; + if (src_samples == dst_samples && dst_samples > 1) { + /* MSAA copy. */ + unsigned i, max_sample = dst_samples - 1; for (i = 0; i <= max_sample; i++) { pipe->set_sample_mask(pipe, 1 << i); @@ -1402,9 +1549,10 @@ void util_blitter_blit_generic(struct blitter_context *blitter, srcbox->y + srcbox->height); blitter_draw(ctx, dstbox->x, dstbox->y, dstbox->x + dstbox->width, - dstbox->y + dstbox->height, 0); + dstbox->y + dstbox->height, 0, 1); } } else { + /* Normal copy, MSAA upsampling, or MSAA resolve. */ pipe->set_sample_mask(pipe, ~0); blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z + z, 0, @@ -1413,7 +1561,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter, srcbox->y + srcbox->height); blitter_draw(ctx, dstbox->x, dstbox->y, dstbox->x + dstbox->width, - dstbox->y + dstbox->height, 0); + dstbox->y + dstbox->height, 0, 1); } /* Get the next surface or (if this is the last iteration) @@ -1465,7 +1613,7 @@ util_blitter_blit(struct blitter_context *blitter, util_blitter_blit_generic(blitter, dst_view, &info->dst.box, src_view, &info->src.box, src->width0, src->height0, info->mask, info->filter, - info->scissor_enable ? &info->scissor : NULL, TRUE); + info->scissor_enable ? &info->scissor : NULL); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); @@ -1508,7 +1656,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter, pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); - blitter_set_common_draw_rect_state(ctx, FALSE); + blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, UTIL_BLITTER_ATTRIB_COLOR, color); @@ -1576,7 +1724,7 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter, pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); - blitter_set_common_draw_rect_state(ctx, FALSE); + blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, (float) depth, @@ -1633,7 +1781,7 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter, pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, sample_mask); - blitter_set_common_draw_rect_state(ctx, FALSE); + blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height); blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth, UTIL_BLITTER_ATTRIB_NONE, NULL); @@ -1818,7 +1966,7 @@ void util_blitter_custom_resolve_color(struct blitter_context *blitter, fb_state.zsbuf = NULL; pipe->set_framebuffer_state(pipe, &fb_state); - blitter_set_common_draw_rect_state(ctx, FALSE); + blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter_set_dst_dimensions(ctx, src->width0, src->height0); blitter->draw_rectangle(blitter, 0, 0, src->width0, src->height0, 0, 0, NULL); @@ -1868,7 +2016,7 @@ void util_blitter_custom_color(struct blitter_context *blitter, pipe->set_framebuffer_state(pipe, &fb_state); pipe->set_sample_mask(pipe, ~0); - blitter_set_common_draw_rect_state(ctx, FALSE); + blitter_set_common_draw_rect_state(ctx, FALSE, FALSE); blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height, 0, 0, NULL); diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.h b/mesalib/src/gallium/auxiliary/util/u_blitter.h index d9cefde50..a30cdc36a 100644 --- a/mesalib/src/gallium/auxiliary/util/u_blitter.h +++ b/mesalib/src/gallium/auxiliary/util/u_blitter.h @@ -183,7 +183,7 @@ void util_blitter_draw_rectangle(struct blitter_context *blitter, * - blend state */ void util_blitter_clear(struct blitter_context *blitter, - unsigned width, unsigned height, + unsigned width, unsigned height, unsigned num_layers, unsigned clear_buffers, const union pipe_color_union *color, double depth, unsigned stencil); @@ -191,13 +191,10 @@ void util_blitter_clear(struct blitter_context *blitter, /** * Check if the blitter (with the help of the driver) can blit between * the two resources. - * The mask is a combination of the PIPE_MASK_* flags. - * Set to PIPE_MASK_RGBAZS if unsure. */ boolean util_blitter_is_copy_supported(struct blitter_context *blitter, const struct pipe_resource *dst, - const struct pipe_resource *src, - unsigned mask); + const struct pipe_resource *src); boolean util_blitter_is_blit_supported(struct blitter_context *blitter, const struct pipe_blit_info *info); @@ -221,8 +218,7 @@ void util_blitter_copy_texture(struct blitter_context *blitter, unsigned dstx, unsigned dsty, unsigned dstz, struct pipe_resource *src, unsigned src_level, - const struct pipe_box *srcbox, unsigned mask, - boolean copy_all_samples); + const struct pipe_box *srcbox); /** * This is a generic implementation of pipe->blit, which accepts @@ -250,8 +246,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter, const struct pipe_box *srcbox, unsigned src_width0, unsigned src_height0, unsigned mask, unsigned filter, - const struct pipe_scissor_state *scissor, - boolean copy_all_samples); + const struct pipe_scissor_state *scissor); void util_blitter_blit(struct blitter_context *blitter, const struct pipe_blit_info *info); diff --git a/mesalib/src/gallium/auxiliary/util/u_clear.h b/mesalib/src/gallium/auxiliary/util/u_clear.h index e9fd874b1..75047c16b 100644 --- a/mesalib/src/gallium/auxiliary/util/u_clear.h +++ b/mesalib/src/gallium/auxiliary/util/u_clear.h @@ -42,9 +42,10 @@ util_clear(struct pipe_context *pipe, struct pipe_framebuffer_state *framebuffer, unsigned buffers, const union pipe_color_union *color, double depth, unsigned stencil) { - if (buffers & PIPE_CLEAR_COLOR) { - unsigned i; - for (i = 0; i < framebuffer->nr_cbufs; i++) { + unsigned i; + + for (i = 0; i < framebuffer->nr_cbufs; i++) { + if (buffers & (PIPE_CLEAR_COLOR0 << i)) { struct pipe_surface *ps = framebuffer->cbufs[i]; pipe->clear_render_target(pipe, ps, color, 0, 0, ps->width, ps->height); } diff --git a/mesalib/src/gallium/auxiliary/util/u_framebuffer.c b/mesalib/src/gallium/auxiliary/util/u_framebuffer.c index f84485d1f..683967237 100644 --- a/mesalib/src/gallium/auxiliary/util/u_framebuffer.c +++ b/mesalib/src/gallium/auxiliary/util/u_framebuffer.c @@ -147,3 +147,27 @@ util_framebuffer_min_size(const struct pipe_framebuffer_state *fb, return TRUE; } } + + +/** + * Return the number of layers set in the framebuffer state. + */ +unsigned +util_framebuffer_get_num_layers(const struct pipe_framebuffer_state *fb) +{ + unsigned i, num_layers = 0; + + for (i = 0; i < fb->nr_cbufs; i++) { + if (fb->cbufs[i]) { + unsigned num = fb->cbufs[i]->u.tex.last_layer - + fb->cbufs[i]->u.tex.first_layer + 1; + num_layers = MAX2(num_layers, num); + } + } + if (fb->zsbuf) { + unsigned num = fb->zsbuf->u.tex.last_layer - + fb->zsbuf->u.tex.first_layer + 1; + num_layers = MAX2(num_layers, num); + } + return num_layers; +} diff --git a/mesalib/src/gallium/auxiliary/util/u_framebuffer.h b/mesalib/src/gallium/auxiliary/util/u_framebuffer.h index a89066230..0e6c98363 100644 --- a/mesalib/src/gallium/auxiliary/util/u_framebuffer.h +++ b/mesalib/src/gallium/auxiliary/util/u_framebuffer.h @@ -55,6 +55,11 @@ util_framebuffer_min_size(const struct pipe_framebuffer_state *fb, unsigned *width, unsigned *height); + +extern unsigned +util_framebuffer_get_num_layers(const struct pipe_framebuffer_state *fb); + + #ifdef __cplusplus } #endif diff --git a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c index c93d75469..82f23ebec 100644 --- a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c +++ b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.c @@ -99,6 +99,32 @@ util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, } +void *util_make_layered_clear_vertex_shader(struct pipe_context *pipe) +{ + static const char text[] = + "VERT\n" + "DCL IN[0]\n" + "DCL IN[1]\n" + "DCL SV[0], INSTANCEID\n" + "DCL OUT[0], POSITION\n" + "DCL OUT[1], GENERIC[0]\n" + "DCL OUT[2], LAYER\n" + + "MOV OUT[0], IN[0]\n" + "MOV OUT[1], IN[1]\n" + "MOV OUT[2], SV[0]\n" + "END\n"; + struct tgsi_token tokens[1000]; + struct pipe_shader_state state = {tokens}; + + if (!tgsi_text_translate(text, tokens, Elements(tokens))) { + assert(0); + return NULL; + } + return pipe->create_vs_state(pipe, &state); +} + + /** * Make simple fragment texture shader: * IMM {0,0,0,1} // (if writemask != 0xf) @@ -527,3 +553,157 @@ util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe, return pipe->create_fs_state(pipe, &state); } + + +void * +util_make_fs_msaa_resolve(struct pipe_context *pipe, + unsigned tgsi_tex, unsigned nr_samples, + boolean is_uint, boolean is_sint) +{ + struct ureg_program *ureg; + struct ureg_src sampler, coord; + struct ureg_dst out, tmp_sum, tmp_coord, tmp; + int i; + + ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); + if (!ureg) + return NULL; + + /* Declarations. */ + sampler = ureg_DECL_sampler(ureg, 0); + coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, + TGSI_INTERPOLATE_LINEAR); + out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); + tmp_sum = ureg_DECL_temporary(ureg); + tmp_coord = ureg_DECL_temporary(ureg); + tmp = ureg_DECL_temporary(ureg); + + /* Instructions. */ + ureg_MOV(ureg, tmp_sum, ureg_imm1f(ureg, 0)); + ureg_F2U(ureg, tmp_coord, coord); + + for (i = 0; i < nr_samples; i++) { + /* Read one sample. */ + ureg_MOV(ureg, ureg_writemask(tmp_coord, TGSI_WRITEMASK_W), + ureg_imm1u(ureg, i)); + ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord), sampler); + + if (is_uint) + ureg_U2F(ureg, tmp, ureg_src(tmp)); + else if (is_sint) + ureg_I2F(ureg, tmp, ureg_src(tmp)); + + /* Add it to the sum.*/ + ureg_ADD(ureg, tmp_sum, ureg_src(tmp_sum), ureg_src(tmp)); + } + + /* Calculate the average and return. */ + ureg_MUL(ureg, tmp_sum, ureg_src(tmp_sum), + ureg_imm1f(ureg, 1.0 / nr_samples)); + + if (is_uint) + ureg_F2U(ureg, out, ureg_src(tmp_sum)); + else if (is_sint) + ureg_F2I(ureg, out, ureg_src(tmp_sum)); + else + ureg_MOV(ureg, out, ureg_src(tmp_sum)); + + ureg_END(ureg); + + return ureg_create_shader_and_destroy(ureg, pipe); +} + + +void * +util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe, + unsigned tgsi_tex, unsigned nr_samples, + boolean is_uint, boolean is_sint) +{ + struct ureg_program *ureg; + struct ureg_src sampler, coord; + struct ureg_dst out, tmp, top, bottom; + struct ureg_dst tmp_coord[4], tmp_sum[4]; + int i, c; + + ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); + if (!ureg) + return NULL; + + /* Declarations. */ + sampler = ureg_DECL_sampler(ureg, 0); + coord = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_GENERIC, 0, + TGSI_INTERPOLATE_LINEAR); + out = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); + for (c = 0; c < 4; c++) + tmp_sum[c] = ureg_DECL_temporary(ureg); + for (c = 0; c < 4; c++) + tmp_coord[c] = ureg_DECL_temporary(ureg); + tmp = ureg_DECL_temporary(ureg); + top = ureg_DECL_temporary(ureg); + bottom = ureg_DECL_temporary(ureg); + + /* Instructions. */ + for (c = 0; c < 4; c++) + ureg_MOV(ureg, tmp_sum[c], ureg_imm1f(ureg, 0)); + + /* Get 4 texture coordinates for the bilinear filter. */ + ureg_F2U(ureg, tmp_coord[0], coord); /* top-left */ + ureg_UADD(ureg, tmp_coord[1], ureg_src(tmp_coord[0]), + ureg_imm4u(ureg, 1, 0, 0, 0)); /* top-right */ + ureg_UADD(ureg, tmp_coord[2], ureg_src(tmp_coord[0]), + ureg_imm4u(ureg, 0, 1, 0, 0)); /* bottom-left */ + ureg_UADD(ureg, tmp_coord[3], ureg_src(tmp_coord[0]), + ureg_imm4u(ureg, 1, 1, 0, 0)); /* bottom-right */ + + for (i = 0; i < nr_samples; i++) { + for (c = 0; c < 4; c++) { + /* Read one sample. */ + ureg_MOV(ureg, ureg_writemask(tmp_coord[c], TGSI_WRITEMASK_W), + ureg_imm1u(ureg, i)); + ureg_TXF(ureg, tmp, tgsi_tex, ureg_src(tmp_coord[c]), sampler); + + if (is_uint) + ureg_U2F(ureg, tmp, ureg_src(tmp)); + else if (is_sint) + ureg_I2F(ureg, tmp, ureg_src(tmp)); + + /* Add it to the sum.*/ + ureg_ADD(ureg, tmp_sum[c], ureg_src(tmp_sum[c]), ureg_src(tmp)); + } + } + + /* Calculate the average. */ + for (c = 0; c < 4; c++) + ureg_MUL(ureg, tmp_sum[c], ureg_src(tmp_sum[c]), + ureg_imm1f(ureg, 1.0 / nr_samples)); + + /* Take the 4 average values and apply a standard bilinear filter. */ + ureg_FRC(ureg, tmp, coord); + + ureg_LRP(ureg, top, + ureg_scalar(ureg_src(tmp), 0), + ureg_src(tmp_sum[1]), + ureg_src(tmp_sum[0])); + + ureg_LRP(ureg, bottom, + ureg_scalar(ureg_src(tmp), 0), + ureg_src(tmp_sum[3]), + ureg_src(tmp_sum[2])); + + ureg_LRP(ureg, tmp, + ureg_scalar(ureg_src(tmp), 1), + ureg_src(bottom), + ureg_src(top)); + + /* Convert to the texture format and return. */ + if (is_uint) + ureg_F2U(ureg, out, ureg_src(tmp)); + else if (is_sint) + ureg_F2I(ureg, out, ureg_src(tmp)); + else + ureg_MOV(ureg, out, ureg_src(tmp)); + + ureg_END(ureg); + + return ureg_create_shader_and_destroy(ureg, pipe); +} diff --git a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h index 016664d1b..e81d99414 100644 --- a/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h +++ b/mesalib/src/gallium/auxiliary/util/u_simple_shaders.h @@ -56,6 +56,8 @@ util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, const uint *semantic_indexes, const struct pipe_stream_output_info *so); +extern void * +util_make_layered_clear_vertex_shader(struct pipe_context *pipe); extern void * util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, @@ -122,6 +124,18 @@ void * util_make_fs_blit_msaa_stencil(struct pipe_context *pipe, unsigned tgsi_tex); + +void * +util_make_fs_msaa_resolve(struct pipe_context *pipe, + unsigned tgsi_tex, unsigned nr_samples, + boolean is_uint, boolean is_sint); + + +void * +util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe, + unsigned tgsi_tex, unsigned nr_samples, + boolean is_uint, boolean is_sint); + #ifdef __cplusplus } #endif |