aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/gallium/auxiliary
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/gallium/auxiliary')
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.c286
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.h13
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_clear.h7
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_framebuffer.c24
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_framebuffer.h5
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_simple_shaders.c180
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_simple_shaders.h14
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