aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src')
-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
-rw-r--r--mesalib/src/glsl/ast.h1
-rw-r--r--mesalib/src/glsl/ast_array_index.cpp8
-rw-r--r--mesalib/src/glsl/ast_function.cpp86
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp298
-rw-r--r--mesalib/src/glsl/ast_type.cpp3
-rw-r--r--mesalib/src/glsl/builtin_functions.cpp37
-rw-r--r--mesalib/src/glsl/builtin_variables.cpp50
-rw-r--r--mesalib/src/glsl/glsl_lexer.ll2
-rw-r--r--mesalib/src/glsl/glsl_parser.yy17
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp24
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.h14
-rw-r--r--mesalib/src/glsl/glsl_types.cpp5
-rw-r--r--mesalib/src/glsl/glsl_types.h6
-rw-r--r--mesalib/src/glsl/ir.cpp65
-rw-r--r--mesalib/src/glsl/ir.h373
-rw-r--r--mesalib/src/glsl/ir_clone.cpp35
-rw-r--r--mesalib/src/glsl/ir_constant_expression.cpp2
-rw-r--r--mesalib/src/glsl/ir_function.cpp2
-rw-r--r--mesalib/src/glsl/ir_hv_accept.cpp20
-rw-r--r--mesalib/src/glsl/ir_print_visitor.cpp27
-rw-r--r--mesalib/src/glsl/ir_reader.cpp42
-rw-r--r--mesalib/src/glsl/ir_set_program_inouts.cpp35
-rw-r--r--mesalib/src/glsl/ir_validate.cpp47
-rw-r--r--mesalib/src/glsl/link_atomics.cpp20
-rw-r--r--mesalib/src/glsl/link_functions.cpp10
-rw-r--r--mesalib/src/glsl/link_interface_blocks.cpp12
-rw-r--r--mesalib/src/glsl/link_uniform_initializers.cpp6
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp20
-rw-r--r--mesalib/src/glsl/link_varyings.cpp98
-rw-r--r--mesalib/src/glsl/linker.cpp173
-rw-r--r--mesalib/src/glsl/loop_analysis.cpp196
-rw-r--r--mesalib/src/glsl/loop_analysis.h93
-rw-r--r--mesalib/src/glsl/loop_controls.cpp127
-rw-r--r--mesalib/src/glsl/loop_unroll.cpp318
-rw-r--r--mesalib/src/glsl/lower_clip_distance.cpp18
-rw-r--r--mesalib/src/glsl/lower_instructions.cpp4
-rw-r--r--mesalib/src/glsl/lower_named_interface_blocks.cpp21
-rw-r--r--mesalib/src/glsl/lower_output_reads.cpp2
-rw-r--r--mesalib/src/glsl/lower_packed_varyings.cpp21
-rw-r--r--mesalib/src/glsl/lower_ubo_reference.cpp2
-rw-r--r--mesalib/src/glsl/lower_variable_index_to_cond_assign.cpp2
-rw-r--r--mesalib/src/glsl/opt_array_splitting.cpp4
-rw-r--r--mesalib/src/glsl/opt_constant_folding.cpp4
-rw-r--r--mesalib/src/glsl/opt_constant_propagation.cpp4
-rw-r--r--mesalib/src/glsl/opt_constant_variable.cpp4
-rw-r--r--mesalib/src/glsl/opt_copy_propagation.cpp4
-rw-r--r--mesalib/src/glsl/opt_copy_propagation_elements.cpp4
-rw-r--r--mesalib/src/glsl/opt_cse.cpp2
-rw-r--r--mesalib/src/glsl/opt_dead_builtin_varyings.cpp22
-rw-r--r--mesalib/src/glsl/opt_dead_code.cpp8
-rw-r--r--mesalib/src/glsl/opt_dead_code_local.cpp2
-rw-r--r--mesalib/src/glsl/opt_flip_matrices.cpp4
-rw-r--r--mesalib/src/glsl/opt_function_inlining.cpp14
-rw-r--r--mesalib/src/glsl/opt_structure_splitting.cpp4
-rw-r--r--mesalib/src/glsl/opt_tree_grafting.cpp10
-rw-r--r--mesalib/src/glsl/standalone_scaffolding.h2
-rw-r--r--mesalib/src/mapi/glapi/gen/ARB_clear_buffer_object.xml50
-rw-r--r--mesalib/src/mapi/glapi/gen/ARB_texture_view.xml23
-rw-r--r--mesalib/src/mapi/glapi/gen/Makefile.am1
-rw-r--r--mesalib/src/mapi/glapi/gen/gl_API.xml8
-rw-r--r--mesalib/src/mapi/glapi/gen/gl_genexec.py1
-rw-r--r--mesalib/src/mapi/glapi/gen/gl_gentable.py2
-rw-r--r--mesalib/src/mesa/Makefile.am6
-rw-r--r--mesalib/src/mesa/Makefile.sources1
-rw-r--r--mesalib/src/mesa/SConscript1
-rw-r--r--mesalib/src/mesa/drivers/common/driverfuncs.c3
-rw-r--r--mesalib/src/mesa/drivers/dri/common/dri_util.c26
-rw-r--r--mesalib/src/mesa/drivers/dri/common/dri_util.h8
-rw-r--r--mesalib/src/mesa/drivers/dri/common/megadriver_stub.c126
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/swrast.c39
-rw-r--r--mesalib/src/mesa/main/attrib.c326
-rw-r--r--mesalib/src/mesa/main/bufferobj.c406
-rw-r--r--mesalib/src/mesa/main/bufferobj.h59
-rw-r--r--mesalib/src/mesa/main/clear.c31
-rw-r--r--mesalib/src/mesa/main/colortab.c20
-rw-r--r--mesalib/src/mesa/main/condrender.c4
-rw-r--r--mesalib/src/mesa/main/context.c1
-rw-r--r--mesalib/src/mesa/main/convolve.c24
-rw-r--r--mesalib/src/mesa/main/dd.h11
-rw-r--r--mesalib/src/mesa/main/dlist.c1074
-rw-r--r--mesalib/src/mesa/main/enable.c19
-rw-r--r--mesalib/src/mesa/main/extensions.c27
-rw-r--r--mesalib/src/mesa/main/fbobject.c31
-rw-r--r--mesalib/src/mesa/main/ff_fragment_shader.cpp16
-rw-r--r--mesalib/src/mesa/main/get.c8
-rw-r--r--mesalib/src/mesa/main/get_hash_params.py8
-rw-r--r--mesalib/src/mesa/main/getstring.c2
-rw-r--r--mesalib/src/mesa/main/glformats.c12
-rw-r--r--mesalib/src/mesa/main/imports.c14
-rw-r--r--mesalib/src/mesa/main/mipmap.c8
-rw-r--r--mesalib/src/mesa/main/mipmap.h4
-rw-r--r--mesalib/src/mesa/main/mtypes.h35
-rw-r--r--mesalib/src/mesa/main/performance_monitor.c19
-rw-r--r--mesalib/src/mesa/main/performance_monitor.h3
-rw-r--r--mesalib/src/mesa/main/shader_query.cpp36
-rw-r--r--mesalib/src/mesa/main/shaderapi.c2
-rw-r--r--mesalib/src/mesa/main/shaderobj.h2
-rw-r--r--mesalib/src/mesa/main/texgetimage.c3
-rw-r--r--mesalib/src/mesa/main/teximage.c255
-rw-r--r--mesalib/src/mesa/main/teximage.h4
-rw-r--r--mesalib/src/mesa/main/texobj.c29
-rw-r--r--mesalib/src/mesa/main/texparam.c75
-rw-r--r--mesalib/src/mesa/main/texstorage.c36
-rw-r--r--mesalib/src/mesa/main/texstore.c1
-rw-r--r--mesalib/src/mesa/main/textureview.c668
-rw-r--r--mesalib/src/mesa/main/textureview.h43
-rw-r--r--mesalib/src/mesa/main/version.c1
-rw-r--r--mesalib/src/mesa/math/m_matrix.c13
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp63
-rw-r--r--mesalib/src/mesa/program/prog_parameter.c3
-rw-r--r--mesalib/src/mesa/program/program.c8
-rw-r--r--mesalib/src/mesa/program/program_parse_extra.c9
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_framebuffer.c58
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_sampler.c32
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_clear.c124
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_drawpixels.c19
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_fbo.c97
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_fbo.h10
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_readpixels.c4
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c10
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.h1
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c16
-rw-r--r--mesalib/src/mesa/state_tracker/st_format.c6
-rw-r--r--mesalib/src/mesa/state_tracker/st_format.h2
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp74
-rw-r--r--mesalib/src/mesa/state_tracker/st_program.c9
-rw-r--r--mesalib/src/mesa/state_tracker/st_texture.h6
-rw-r--r--mesalib/src/mesa/swrast/s_texture.c7
-rw-r--r--mesalib/src/mesa/tnl/t_vertex.c6
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_api.c9
-rw-r--r--mesalib/src/mesa/x86/rtasm/x86sse.c1203
-rw-r--r--mesalib/src/mesa/x86/rtasm/x86sse.h256
140 files changed, 4348 insertions, 4275 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
diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h
index 5c214b604..76911f056 100644
--- a/mesalib/src/glsl/ast.h
+++ b/mesalib/src/glsl/ast.h
@@ -357,6 +357,7 @@ struct ast_type_qualifier {
unsigned in:1;
unsigned out:1;
unsigned centroid:1;
+ unsigned sample:1;
unsigned uniform:1;
unsigned smooth:1;
unsigned flat:1;
diff --git a/mesalib/src/glsl/ast_array_index.cpp b/mesalib/src/glsl/ast_array_index.cpp
index f7b5e8350..a5f23206a 100644
--- a/mesalib/src/glsl/ast_array_index.cpp
+++ b/mesalib/src/glsl/ast_array_index.cpp
@@ -41,8 +41,8 @@ update_max_array_access(ir_rvalue *ir, unsigned idx, YYLTYPE *loc,
{
if (ir_dereference_variable *deref_var = ir->as_dereference_variable()) {
ir_variable *var = deref_var->var;
- if (idx > var->max_array_access) {
- var->max_array_access = idx;
+ if (idx > var->data.max_array_access) {
+ var->data.max_array_access = idx;
/* Check whether this access will, as a side effect, implicitly cause
* the size of a built-in array to be too large.
@@ -168,7 +168,7 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
if (array->type->is_unsized_array()) {
_mesa_glsl_error(&loc, state, "unsized array index must be constant");
} else if (array->type->fields.array->is_interface()
- && array->variable_referenced()->mode == ir_var_uniform) {
+ && array->variable_referenced()->data.mode == ir_var_uniform) {
/* Page 46 in section 4.3.7 of the OpenGL ES 3.00 spec says:
*
* "All indexes used to index a uniform block array must be
@@ -184,7 +184,7 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
*/
ir_variable *v = array->whole_variable_referenced();
if (v != NULL)
- v->max_array_access = array->type->array_size() - 1;
+ v->data.max_array_access = array->type->array_size() - 1;
}
/* From page 23 (29 of the PDF) of the GLSL 1.30 spec:
diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp
index 2707522ef..e4c0fd1c4 100644
--- a/mesalib/src/glsl/ast_function.cpp
+++ b/mesalib/src/glsl/ast_function.cpp
@@ -123,7 +123,7 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
YYLTYPE loc = actual_ast->get_location();
/* Verify that 'const_in' parameters are ir_constants. */
- if (formal->mode == ir_var_const_in &&
+ if (formal->data.mode == ir_var_const_in &&
actual->ir_type != ir_type_constant) {
_mesa_glsl_error(&loc, state,
"parameter `in %s' must be a constant expression",
@@ -132,10 +132,10 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
}
/* Verify that 'out' and 'inout' actual parameters are lvalues. */
- if (formal->mode == ir_var_function_out
- || formal->mode == ir_var_function_inout) {
+ if (formal->data.mode == ir_var_function_out
+ || formal->data.mode == ir_var_function_inout) {
const char *mode = NULL;
- switch (formal->mode) {
+ switch (formal->data.mode) {
case ir_var_function_out: mode = "out"; break;
case ir_var_function_inout: mode = "inout"; break;
default: assert(false); break;
@@ -155,9 +155,9 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
ir_variable *var = actual->variable_referenced();
if (var)
- var->assigned = true;
+ var->data.assigned = true;
- if (var && var->read_only) {
+ if (var && var->data.read_only) {
_mesa_glsl_error(&loc, state,
"function parameter '%s %s' references the "
"read-only variable '%s'",
@@ -274,20 +274,20 @@ fix_parameter(void *mem_ctx, ir_rvalue *actual, const glsl_type *formal_type,
}
/**
- * If a function call is generated, \c call_ir will point to it on exit.
- * Otherwise \c call_ir will be set to \c NULL.
+ * Generate a function call.
+ *
+ * For non-void functions, this returns a dereference of the temporary variable
+ * which stores the return value for the call. For void functions, this returns
+ * NULL.
*/
static ir_rvalue *
generate_call(exec_list *instructions, ir_function_signature *sig,
exec_list *actual_parameters,
- ir_call **call_ir,
struct _mesa_glsl_parse_state *state)
{
void *ctx = state;
exec_list post_call_conversions;
- *call_ir = NULL;
-
/* Perform implicit conversion of arguments. For out parameters, we need
* to place them in a temporary variable and do the conversion after the
* call takes place. Since we haven't emitted the call yet, we'll place
@@ -304,7 +304,7 @@ generate_call(exec_list *instructions, ir_function_signature *sig,
assert(formal != NULL);
if (formal->type->is_numeric() || formal->type->is_boolean()) {
- switch (formal->mode) {
+ switch (formal->data.mode) {
case ir_var_const_in:
case ir_var_function_in: {
ir_rvalue *converted
@@ -316,7 +316,7 @@ generate_call(exec_list *instructions, ir_function_signature *sig,
case ir_var_function_inout:
fix_parameter(ctx, actual, formal->type,
instructions, &post_call_conversions,
- formal->mode == ir_var_function_inout);
+ formal->data.mode == ir_var_function_inout);
break;
default:
assert (!"Illegal formal parameter mode");
@@ -421,6 +421,25 @@ done:
return sig;
}
+static void
+print_function_prototypes(_mesa_glsl_parse_state *state, YYLTYPE *loc,
+ ir_function *f)
+{
+ if (f == NULL)
+ return;
+
+ foreach_list (node, &f->signatures) {
+ ir_function_signature *sig = (ir_function_signature *) node;
+
+ if (sig->is_builtin() && !sig->is_builtin_available(state))
+ continue;
+
+ char *str = prototype_string(sig->return_type, f->name, &sig->parameters);
+ _mesa_glsl_error(loc, state, " %s", str);
+ ralloc_free(str);
+ }
+}
+
/**
* Raise a "no matching function" error, listing all possible overloads the
* compiler considered so developers can figure out what went wrong.
@@ -431,30 +450,23 @@ no_matching_function_error(const char *name,
exec_list *actual_parameters,
_mesa_glsl_parse_state *state)
{
- char *str = prototype_string(NULL, name, actual_parameters);
- _mesa_glsl_error(loc, state, "no matching function for call to `%s'", str);
- ralloc_free(str);
-
- const char *prefix = "candidates are: ";
+ gl_shader *sh = _mesa_glsl_get_builtin_function_shader();
- for (int i = -1; i < (int) state->num_builtins_to_link; i++) {
- glsl_symbol_table *syms = i >= 0 ? state->builtins_to_link[i]->symbols
- : state->symbols;
- ir_function *f = syms->get_function(name);
- if (f == NULL)
- continue;
-
- foreach_list (node, &f->signatures) {
- ir_function_signature *sig = (ir_function_signature *) node;
-
- if (sig->is_builtin() && !sig->is_builtin_available(state))
- continue;
+ if (state->symbols->get_function(name) == NULL
+ && (!state->uses_builtin_functions
+ || sh->symbols->get_function(name) == NULL)) {
+ _mesa_glsl_error(loc, state, "no function with name '%s'", name);
+ } else {
+ char *str = prototype_string(NULL, name, actual_parameters);
+ _mesa_glsl_error(loc, state,
+ "no matching function for call to `%s'; candidates are:",
+ str);
+ ralloc_free(str);
- str = prototype_string(sig->return_type, f->name, &sig->parameters);
- _mesa_glsl_error(loc, state, "%s%s", prefix, str);
- ralloc_free(str);
+ print_function_prototypes(state, loc, state->symbols->get_function(name));
- prefix = " ";
+ if (state->uses_builtin_functions) {
+ print_function_prototypes(state, loc, sh->symbols->get_function(name));
}
}
}
@@ -1651,7 +1663,7 @@ ast_function_expression::hir(exec_list *instructions,
} else {
const ast_expression *id = subexpressions[0];
const char *func_name = id->primary_expression.identifier;
- YYLTYPE loc = id->get_location();
+ YYLTYPE loc = get_location();
exec_list actual_parameters;
process_parameters(instructions, &actual_parameters, &this->expressions,
@@ -1660,7 +1672,6 @@ ast_function_expression::hir(exec_list *instructions,
ir_function_signature *sig =
match_function_by_name(func_name, &actual_parameters, state);
- ir_call *call = NULL;
ir_rvalue *value = NULL;
if (sig == NULL) {
no_matching_function_error(func_name, &loc, &actual_parameters, state);
@@ -1669,8 +1680,7 @@ ast_function_expression::hir(exec_list *instructions,
/* an error has already been emitted */
value = ir_rvalue::error_value(ctx);
} else {
- value = generate_call(instructions, sig, &actual_parameters,
- &call, state);
+ value = generate_call(instructions, sig, &actual_parameters, state);
}
return value;
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index 43cf49745..3bc181e87 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -728,7 +728,7 @@ mark_whole_array_access(ir_rvalue *access)
ir_dereference_variable *deref = access->as_dereference_variable();
if (deref && deref->var) {
- deref->var->max_array_access = deref->type->length - 1;
+ deref->var->data.max_array_access = deref->type->length - 1;
}
}
@@ -767,7 +767,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
ir_variable *lhs_var = lhs->variable_referenced();
if (lhs_var)
- lhs_var->assigned = true;
+ lhs_var->data.assigned = true;
if (!error_emitted) {
if (non_lvalue_description != NULL) {
@@ -776,7 +776,7 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
non_lvalue_description);
error_emitted = true;
} else if (lhs->variable_referenced() != NULL
- && lhs->variable_referenced()->read_only) {
+ && lhs->variable_referenced()->data.read_only) {
_mesa_glsl_error(&lhs_loc, state,
"assignment to read-only variable '%s'",
lhs->variable_referenced()->name);
@@ -819,11 +819,11 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
assert(var != NULL);
- if (var->max_array_access >= unsigned(rhs->type->array_size())) {
+ if (var->data.max_array_access >= unsigned(rhs->type->array_size())) {
/* FINISHME: This should actually log the location of the RHS. */
_mesa_glsl_error(& lhs_loc, state, "array size must be > %u due to "
"previous access",
- var->max_array_access);
+ var->data.max_array_access);
}
var->type = glsl_type::get_array_instance(lhs->type->element_type(),
@@ -866,7 +866,7 @@ get_lvalue_copy(exec_list *instructions, ir_rvalue *lvalue)
var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
ir_var_temporary);
instructions->push_tail(var);
- var->mode = ir_var_auto;
+ var->data.mode = ir_var_auto;
instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
lvalue));
@@ -1639,7 +1639,7 @@ ast_expression::hir(exec_list *instructions,
state->symbols->get_variable(this->primary_expression.identifier);
if (var != NULL) {
- var->used = true;
+ var->data.used = true;
result = new(ctx) ir_dereference_variable(var);
} else {
_mesa_glsl_error(& loc, state, "`%s' undeclared",
@@ -1860,7 +1860,7 @@ ast_fully_specified_type::glsl_type(const char **name,
if (type->base_type == GLSL_TYPE_FLOAT
&& state->es_shader
- && state->target == fragment_shader
+ && state->target == MESA_SHADER_FRAGMENT
&& this->qualifier.precision == ast_precision_none
&& state->symbols->get_variable("#default precision") == NULL) {
YYLTYPE loc = this->get_location();
@@ -1882,15 +1882,15 @@ ast_fully_specified_type::glsl_type(const char **name,
* this function will produce undefined results.
*/
static bool
-is_varying_var(ir_variable *var, _mesa_glsl_parser_targets target)
+is_varying_var(ir_variable *var, gl_shader_type target)
{
switch (target) {
- case vertex_shader:
- return var->mode == ir_var_shader_out;
- case fragment_shader:
- return var->mode == ir_var_shader_in;
+ case MESA_SHADER_VERTEX:
+ return var->data.mode == ir_var_shader_out;
+ case MESA_SHADER_FRAGMENT:
+ return var->data.mode == ir_var_shader_in;
default:
- return var->mode == ir_var_shader_out || var->mode == ir_var_shader_in;
+ return var->data.mode == ir_var_shader_out || var->data.mode == ir_var_shader_in;
}
}
@@ -1941,7 +1941,7 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
ir_variable *var,
const ast_type_qualifier *qual)
{
- if (var->mode != ir_var_uniform) {
+ if (var->data.mode != ir_var_uniform) {
_mesa_glsl_error(loc, state,
"the \"binding\" qualifier only applies to uniforms");
return false;
@@ -1985,13 +1985,13 @@ validate_binding_qualifier(struct _mesa_glsl_parse_state *state,
*/
unsigned limit = 0;
switch (state->target) {
- case vertex_shader:
+ case MESA_SHADER_VERTEX:
limit = ctx->Const.VertexProgram.MaxTextureImageUnits;
break;
- case geometry_shader:
+ case MESA_SHADER_GEOMETRY:
limit = ctx->Const.GeometryProgram.MaxTextureImageUnits;
break;
- case fragment_shader:
+ case MESA_SHADER_FRAGMENT:
limit = ctx->Const.FragmentProgram.MaxTextureImageUnits;
break;
}
@@ -2049,8 +2049,8 @@ interpret_interpolation_qualifier(const struct ast_type_qualifier *qual,
}
- if ((state->target == vertex_shader && mode == ir_var_shader_in) ||
- (state->target == fragment_shader && mode == ir_var_shader_out)) {
+ if ((state->target == MESA_SHADER_VERTEX && mode == ir_var_shader_in) ||
+ (state->target == MESA_SHADER_FRAGMENT && mode == ir_var_shader_out)) {
_mesa_glsl_error(loc, state,
"interpolation qualifier `%s' cannot be applied to "
"vertex shader inputs or fragment shader outputs",
@@ -2077,8 +2077,8 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
* locations.
*/
switch (state->target) {
- case vertex_shader:
- if (var->mode == ir_var_shader_in) {
+ case MESA_SHADER_VERTEX:
+ if (var->data.mode == ir_var_shader_in) {
if (!state->check_explicit_attrib_location_allowed(loc, var))
return;
@@ -2088,14 +2088,14 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
fail = true;
break;
- case geometry_shader:
+ case MESA_SHADER_GEOMETRY:
_mesa_glsl_error(loc, state,
"geometry shader variables cannot be given "
"explicit locations");
return;
- case fragment_shader:
- if (var->mode == ir_var_shader_out) {
+ case MESA_SHADER_FRAGMENT:
+ if (var->data.mode == ir_var_shader_out) {
if (!state->check_explicit_attrib_location_allowed(loc, var))
return;
@@ -2112,7 +2112,7 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
mode_string(var),
_mesa_glsl_shader_target_name(state->target));
} else {
- var->explicit_location = true;
+ var->data.explicit_location = true;
/* This bit of silliness is needed because invalid explicit locations
* are supposed to be flagged during linking. Small negative values
@@ -2122,11 +2122,11 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
* ensures that negative values stay negative.
*/
if (qual->location >= 0) {
- var->location = (state->target == vertex_shader)
+ var->data.location = (state->target == MESA_SHADER_VERTEX)
? (qual->location + VERT_ATTRIB_GENERIC0)
: (qual->location + FRAG_RESULT_DATA0);
} else {
- var->location = qual->location;
+ var->data.location = qual->location;
}
if (qual->flags.q.explicit_index) {
@@ -2143,8 +2143,8 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
_mesa_glsl_error(loc, state,
"explicit index may only be 0 or 1");
} else {
- var->explicit_index = true;
- var->index = qual->index;
+ var->data.explicit_index = true;
+ var->data.index = qual->index;
}
}
}
@@ -2162,25 +2162,28 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
STATIC_ASSERT(sizeof(qual->flags.q) <= sizeof(qual->flags.i));
if (qual->flags.q.invariant) {
- if (var->used) {
+ if (var->data.used) {
_mesa_glsl_error(loc, state,
"variable `%s' may not be redeclared "
"`invariant' after being used",
var->name);
} else {
- var->invariant = 1;
+ var->data.invariant = 1;
}
}
if (qual->flags.q.constant || qual->flags.q.attribute
|| qual->flags.q.uniform
- || (qual->flags.q.varying && (state->target == fragment_shader)))
- var->read_only = 1;
+ || (qual->flags.q.varying && (state->target == MESA_SHADER_FRAGMENT)))
+ var->data.read_only = 1;
if (qual->flags.q.centroid)
- var->centroid = 1;
+ var->data.centroid = 1;
- if (qual->flags.q.attribute && state->target != vertex_shader) {
+ if (qual->flags.q.sample)
+ var->data.sample = 1;
+
+ if (qual->flags.q.attribute && state->target != MESA_SHADER_VERTEX) {
var->type = glsl_type::error_type;
_mesa_glsl_error(loc, state,
"`attribute' variables may not be declared in the "
@@ -2207,18 +2210,18 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
* the setting alone.
*/
if (qual->flags.q.in && qual->flags.q.out)
- var->mode = ir_var_function_inout;
+ var->data.mode = ir_var_function_inout;
else if (qual->flags.q.in)
- var->mode = is_parameter ? ir_var_function_in : ir_var_shader_in;
+ var->data.mode = is_parameter ? ir_var_function_in : ir_var_shader_in;
else if (qual->flags.q.attribute
- || (qual->flags.q.varying && (state->target == fragment_shader)))
- var->mode = ir_var_shader_in;
+ || (qual->flags.q.varying && (state->target == MESA_SHADER_FRAGMENT)))
+ var->data.mode = ir_var_shader_in;
else if (qual->flags.q.out)
- var->mode = is_parameter ? ir_var_function_out : ir_var_shader_out;
- else if (qual->flags.q.varying && (state->target == vertex_shader))
- var->mode = ir_var_shader_out;
+ var->data.mode = is_parameter ? ir_var_function_out : ir_var_shader_out;
+ else if (qual->flags.q.varying && (state->target == MESA_SHADER_VERTEX))
+ var->data.mode = ir_var_shader_out;
else if (qual->flags.q.uniform)
- var->mode = ir_var_uniform;
+ var->data.mode = ir_var_uniform;
if (!is_parameter && is_varying_var(var, state->target)) {
/* This variable is being used to link data between shader stages (in
@@ -2270,28 +2273,28 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
if (state->all_invariant && (state->current_function == NULL)) {
switch (state->target) {
- case vertex_shader:
- if (var->mode == ir_var_shader_out)
- var->invariant = true;
+ case MESA_SHADER_VERTEX:
+ if (var->data.mode == ir_var_shader_out)
+ var->data.invariant = true;
break;
- case geometry_shader:
- if ((var->mode == ir_var_shader_in)
- || (var->mode == ir_var_shader_out))
- var->invariant = true;
+ case MESA_SHADER_GEOMETRY:
+ if ((var->data.mode == ir_var_shader_in)
+ || (var->data.mode == ir_var_shader_out))
+ var->data.invariant = true;
break;
- case fragment_shader:
- if (var->mode == ir_var_shader_in)
- var->invariant = true;
+ case MESA_SHADER_FRAGMENT:
+ if (var->data.mode == ir_var_shader_in)
+ var->data.invariant = true;
break;
}
}
- var->interpolation =
- interpret_interpolation_qualifier(qual, (ir_variable_mode) var->mode,
+ var->data.interpolation =
+ interpret_interpolation_qualifier(qual, (ir_variable_mode) var->data.mode,
state, loc);
- var->pixel_center_integer = qual->flags.q.pixel_center_integer;
- var->origin_upper_left = qual->flags.q.origin_upper_left;
+ var->data.pixel_center_integer = qual->flags.q.pixel_center_integer;
+ var->data.origin_upper_left = qual->flags.q.origin_upper_left;
if ((qual->flags.q.origin_upper_left || qual->flags.q.pixel_center_integer)
&& (strcmp(var->name, "gl_FragCoord") != 0)) {
const char *const qual_string = (qual->flags.q.origin_upper_left)
@@ -2312,27 +2315,28 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
if (qual->flags.q.explicit_binding &&
validate_binding_qualifier(state, loc, var, qual)) {
- var->explicit_binding = true;
- var->binding = qual->binding;
+ var->data.explicit_binding = true;
+ var->data.binding = qual->binding;
}
if (var->type->contains_atomic()) {
- if (var->mode == ir_var_uniform) {
- if (var->explicit_binding) {
- unsigned *offset = &state->atomic_counter_offsets[var->binding];
+ if (var->data.mode == ir_var_uniform) {
+ if (var->data.explicit_binding) {
+ unsigned *offset =
+ &state->atomic_counter_offsets[var->data.binding];
if (*offset % ATOMIC_COUNTER_SIZE)
_mesa_glsl_error(loc, state,
"misaligned atomic counter offset");
- var->atomic.offset = *offset;
+ var->data.atomic.offset = *offset;
*offset += var->type->atomic_size();
} else {
_mesa_glsl_error(loc, state,
"atomic counters require explicit binding point");
}
- } else if (var->mode != ir_var_function_in) {
+ } else if (var->data.mode != ir_var_function_in) {
_mesa_glsl_error(loc, state, "atomic counters may only be declared as "
"function parameters or uniform-qualified "
"global variables");
@@ -2406,15 +2410,15 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
"gl_FragDepth");
}
if (qual->flags.q.depth_any)
- var->depth_layout = ir_depth_layout_any;
+ var->data.depth_layout = ir_depth_layout_any;
else if (qual->flags.q.depth_greater)
- var->depth_layout = ir_depth_layout_greater;
+ var->data.depth_layout = ir_depth_layout_greater;
else if (qual->flags.q.depth_less)
- var->depth_layout = ir_depth_layout_less;
+ var->data.depth_layout = ir_depth_layout_less;
else if (qual->flags.q.depth_unchanged)
- var->depth_layout = ir_depth_layout_unchanged;
+ var->data.depth_layout = ir_depth_layout_unchanged;
else
- var->depth_layout = ir_depth_layout_none;
+ var->data.depth_layout = ir_depth_layout_none;
if (qual->flags.q.std140 ||
qual->flags.q.packed ||
@@ -2475,10 +2479,10 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
const unsigned size = unsigned(var->type->array_size());
check_builtin_array_max_size(var->name, size, loc, state);
- if ((size > 0) && (size <= earlier->max_array_access)) {
+ if ((size > 0) && (size <= earlier->data.max_array_access)) {
_mesa_glsl_error(& loc, state, "array size must be > %u due to "
"previous access",
- earlier->max_array_access);
+ earlier->data.max_array_access);
}
earlier->type = var->type;
@@ -2488,12 +2492,12 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
state->is_version(150, 0))
&& strcmp(var->name, "gl_FragCoord") == 0
&& earlier->type == var->type
- && earlier->mode == var->mode) {
+ && earlier->data.mode == var->data.mode) {
/* Allow redeclaration of gl_FragCoord for ARB_fcc layout
* qualifiers.
*/
- earlier->origin_upper_left = var->origin_upper_left;
- earlier->pixel_center_integer = var->pixel_center_integer;
+ earlier->data.origin_upper_left = var->data.origin_upper_left;
+ earlier->data.pixel_center_integer = var->data.pixel_center_integer;
/* According to section 4.3.7 of the GLSL 1.30 spec,
* the following built-in varaibles can be redeclared with an
@@ -2513,41 +2517,41 @@ get_variable_being_redeclared(ir_variable *var, YYLTYPE loc,
|| strcmp(var->name, "gl_Color") == 0
|| strcmp(var->name, "gl_SecondaryColor") == 0)
&& earlier->type == var->type
- && earlier->mode == var->mode) {
- earlier->interpolation = var->interpolation;
+ && earlier->data.mode == var->data.mode) {
+ earlier->data.interpolation = var->data.interpolation;
/* Layout qualifiers for gl_FragDepth. */
} else if ((state->AMD_conservative_depth_enable ||
state->ARB_conservative_depth_enable)
&& strcmp(var->name, "gl_FragDepth") == 0
&& earlier->type == var->type
- && earlier->mode == var->mode) {
+ && earlier->data.mode == var->data.mode) {
/** From the AMD_conservative_depth spec:
* Within any shader, the first redeclarations of gl_FragDepth
* must appear before any use of gl_FragDepth.
*/
- if (earlier->used) {
+ if (earlier->data.used) {
_mesa_glsl_error(&loc, state,
"the first redeclaration of gl_FragDepth "
"must appear before any use of gl_FragDepth");
}
/* Prevent inconsistent redeclaration of depth layout qualifier. */
- if (earlier->depth_layout != ir_depth_layout_none
- && earlier->depth_layout != var->depth_layout) {
+ if (earlier->data.depth_layout != ir_depth_layout_none
+ && earlier->data.depth_layout != var->data.depth_layout) {
_mesa_glsl_error(&loc, state,
"gl_FragDepth: depth layout is declared here "
"as '%s, but it was previously declared as "
"'%s'",
- depth_layout_string(var->depth_layout),
- depth_layout_string(earlier->depth_layout));
+ depth_layout_string(var->data.depth_layout),
+ depth_layout_string(earlier->data.depth_layout));
}
- earlier->depth_layout = var->depth_layout;
+ earlier->data.depth_layout = var->data.depth_layout;
} else if (allow_all_redeclarations) {
- if (earlier->mode != var->mode) {
+ if (earlier->data.mode != var->data.mode) {
_mesa_glsl_error(&loc, state,
"redeclaration of `%s' with incorrect qualifiers",
var->name);
@@ -2582,7 +2586,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
* directly by an application via API commands, or indirectly by
* OpenGL."
*/
- if (var->mode == ir_var_uniform) {
+ if (var->data.mode == ir_var_uniform) {
state->check_version(120, 0, &initializer_loc,
"cannot initialize uniforms");
}
@@ -2592,11 +2596,11 @@ process_initializer(ir_variable *var, ast_declaration *decl,
"cannot initialize samplers");
}
- if ((var->mode == ir_var_shader_in) && (state->current_function == NULL)) {
+ if ((var->data.mode == ir_var_shader_in) && (state->current_function == NULL)) {
_mesa_glsl_error(& initializer_loc, state,
"cannot initialize %s shader input / %s",
_mesa_glsl_shader_target_name(state->target),
- (state->target == vertex_shader)
+ (state->target == MESA_SHADER_VERTEX)
? "attribute" : "varying");
}
@@ -2647,9 +2651,9 @@ process_initializer(ir_variable *var, ast_declaration *decl,
}
if (rhs && !rhs->type->is_error()) {
- bool temp = var->read_only;
+ bool temp = var->data.read_only;
if (type->qualifier.flags.q.constant)
- var->read_only = false;
+ var->data.read_only = false;
/* Never emit code to initialize a uniform.
*/
@@ -2664,7 +2668,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
initializer_type = rhs->type;
var->constant_initializer = rhs->constant_expression_value();
- var->has_initializer = true;
+ var->data.has_initializer = true;
/* If the declared variable is an unsized array, it must inherrit
* its full type from the initializer. A declaration such as
@@ -2688,7 +2692,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
*/
var->type = initializer_type;
- var->read_only = temp;
+ var->data.read_only = temp;
}
return result;
@@ -2840,23 +2844,23 @@ ast_declarator_list::hir(exec_list *instructions,
_mesa_glsl_error(& loc, state,
"undeclared variable `%s' cannot be marked "
"invariant", decl->identifier);
- } else if ((state->target == vertex_shader)
- && (earlier->mode != ir_var_shader_out)) {
+ } else if ((state->target == MESA_SHADER_VERTEX)
+ && (earlier->data.mode != ir_var_shader_out)) {
_mesa_glsl_error(& loc, state,
"`%s' cannot be marked invariant, vertex shader "
"outputs only", decl->identifier);
- } else if ((state->target == fragment_shader)
- && (earlier->mode != ir_var_shader_in)) {
+ } else if ((state->target == MESA_SHADER_FRAGMENT)
+ && (earlier->data.mode != ir_var_shader_in)) {
_mesa_glsl_error(& loc, state,
"`%s' cannot be marked invariant, fragment shader "
"inputs only", decl->identifier);
- } else if (earlier->used) {
+ } else if (earlier->data.used) {
_mesa_glsl_error(& loc, state,
"variable `%s' may not be redeclared "
"`invariant' after being used",
earlier->name);
} else {
- earlier->invariant = true;
+ earlier->data.invariant = true;
}
}
@@ -2940,7 +2944,7 @@ ast_declarator_list::hir(exec_list *instructions,
precision_names[this->type->qualifier.precision],
type_name);
}
- } else {
+ } else if (this->type->specifier->structure == NULL) {
_mesa_glsl_warning(&loc, state, "empty declaration");
}
}
@@ -3030,13 +3034,13 @@ ast_declarator_list::hir(exec_list *instructions,
& loc, false);
if (this->type->qualifier.flags.q.invariant) {
- if ((state->target == vertex_shader) &&
- var->mode != ir_var_shader_out) {
+ if ((state->target == MESA_SHADER_VERTEX) &&
+ var->data.mode != ir_var_shader_out) {
_mesa_glsl_error(& loc, state,
"`%s' cannot be marked invariant, vertex shader "
"outputs only", var->name);
- } else if ((state->target == fragment_shader) &&
- var->mode != ir_var_shader_in) {
+ } else if ((state->target == MESA_SHADER_FRAGMENT) &&
+ var->data.mode != ir_var_shader_in) {
/* FINISHME: Note that this doesn't work for invariant on
* a function signature inval
*/
@@ -3073,10 +3077,10 @@ ast_declarator_list::hir(exec_list *instructions,
"global scope%s",
mode, var->name, extra);
}
- } else if (var->mode == ir_var_shader_in) {
- var->read_only = true;
+ } else if (var->data.mode == ir_var_shader_in) {
+ var->data.read_only = true;
- if (state->target == vertex_shader) {
+ if (state->target == MESA_SHADER_VERTEX) {
bool error_emitted = false;
/* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
@@ -3131,7 +3135,7 @@ ast_declarator_list::hir(exec_list *instructions,
"cannot have array type")) {
error_emitted = true;
}
- } else if (state->target == geometry_shader) {
+ } else if (state->target == MESA_SHADER_GEOMETRY) {
/* From section 4.3.4 (Inputs) of the GLSL 1.50 spec:
*
* Geometry shader input variables get the per-vertex values
@@ -3180,11 +3184,11 @@ ast_declarator_list::hir(exec_list *instructions,
*/
if (state->is_version(130, 300) &&
var->type->contains_integer() &&
- var->interpolation != INTERP_QUALIFIER_FLAT &&
- ((state->target == fragment_shader && var->mode == ir_var_shader_in)
- || (state->target == vertex_shader && var->mode == ir_var_shader_out
+ var->data.interpolation != INTERP_QUALIFIER_FLAT &&
+ ((state->target == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_in)
+ || (state->target == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_out
&& state->es_shader))) {
- const char *var_type = (state->target == vertex_shader) ?
+ const char *var_type = (state->target == MESA_SHADER_VERTEX) ?
"vertex output" : "fragment input";
_mesa_glsl_error(&loc, state, "if a %s is (or contains) "
"an integer, then it must be qualified with 'flat'",
@@ -3241,14 +3245,14 @@ ast_declarator_list::hir(exec_list *instructions,
assert(i != NULL);
switch (state->target) {
- case vertex_shader:
+ case MESA_SHADER_VERTEX:
if (this->type->qualifier.flags.q.in) {
_mesa_glsl_error(&loc, state,
"qualifier '%s' cannot be applied to vertex "
"shader inputs", i);
}
break;
- case fragment_shader:
+ case MESA_SHADER_FRAGMENT:
if (this->type->qualifier.flags.q.out) {
_mesa_glsl_error(&loc, state,
"qualifier '%s' cannot be applied to fragment "
@@ -3271,12 +3275,20 @@ ast_declarator_list::hir(exec_list *instructions,
if (state->is_version(130, 300)
&& this->type->qualifier.flags.q.centroid
&& this->type->qualifier.flags.q.in
- && state->target == vertex_shader) {
+ && state->target == MESA_SHADER_VERTEX) {
_mesa_glsl_error(&loc, state,
"'centroid in' cannot be used in a vertex shader");
}
+ if (state->target == MESA_SHADER_VERTEX
+ && this->type->qualifier.flags.q.sample
+ && this->type->qualifier.flags.q.in) {
+
+ _mesa_glsl_error(&loc, state,
+ "'sample in' cannot be used in a vertex shader");
+ }
+
/* Section 4.3.6 of the GLSL 1.30 specification states:
* "It is an error to use centroid out in a fragment shader."
*
@@ -3284,7 +3296,7 @@ ast_declarator_list::hir(exec_list *instructions,
* "It is an error to use auxiliary storage qualifiers or interpolation
* qualifiers on an output in a fragment shader."
*/
- if (state->target == fragment_shader &&
+ if (state->target == MESA_SHADER_FRAGMENT &&
this->type->qualifier.flags.q.out &&
this->type->qualifier.has_auxiliary_storage()) {
_mesa_glsl_error(&loc, state,
@@ -3363,12 +3375,12 @@ ast_declarator_list::hir(exec_list *instructions,
false /* allow_all_redeclarations */);
if (earlier != NULL) {
if (strncmp(var->name, "gl_", 3) == 0 &&
- earlier->how_declared == ir_var_declared_in_block) {
+ earlier->data.how_declared == ir_var_declared_in_block) {
_mesa_glsl_error(&loc, state,
"`%s' has already been redeclared using "
"gl_PerVertex", var->name);
}
- earlier->how_declared = ir_var_declared_normally;
+ earlier->data.how_declared = ir_var_declared_normally;
}
if (decl->initializer != NULL) {
@@ -3548,7 +3560,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
* as out or inout function parameters, nor can they be assigned
* into."
*/
- if ((var->mode == ir_var_function_inout || var->mode == ir_var_function_out)
+ if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out)
&& type->contains_sampler()) {
_mesa_glsl_error(&loc, state, "out and inout parameters cannot contain samplers");
type = glsl_type::error_type;
@@ -3568,7 +3580,7 @@ ast_parameter_declarator::hir(exec_list *instructions,
* So for GLSL 1.10, passing an array as an out or inout parameter is not
* allowed. This restriction is removed in GLSL 1.20, and in GLSL ES.
*/
- if ((var->mode == ir_var_function_inout || var->mode == ir_var_function_out)
+ if ((var->data.mode == ir_var_function_inout || var->data.mode == ir_var_function_out)
&& type->is_array()
&& !state->check_version(120, 100, &loc,
"arrays cannot be out or inout parameters")) {
@@ -3942,7 +3954,7 @@ ast_jump_statement::hir(exec_list *instructions,
}
case ast_discard:
- if (state->target != fragment_shader) {
+ if (state->target != MESA_SHADER_FRAGMENT) {
YYLTYPE loc = this->get_location();
_mesa_glsl_error(& loc, state,
@@ -4480,7 +4492,7 @@ ast_type_specifier::hir(exec_list *instructions,
if (type->base_type == GLSL_TYPE_FLOAT
&& state->es_shader
- && state->target == fragment_shader) {
+ && state->target == MESA_SHADER_FRAGMENT) {
/* Section 4.5.3 (Default Precision Qualifiers) of the GLSL ES 1.00
* spec says:
*
@@ -4662,6 +4674,7 @@ ast_process_structure_or_interface_block(exec_list *instructions,
fields[i].interpolation =
interpret_interpolation_qualifier(qual, var_mode, state, &loc);
fields[i].centroid = qual->flags.q.centroid ? 1 : 0;
+ fields[i].sample = qual->flags.q.sample ? 1 : 0;
if (qual->flags.q.row_major || qual->flags.q.column_major) {
if (!qual->flags.q.uniform) {
@@ -4782,7 +4795,7 @@ public:
virtual ir_visitor_status visit(ir_dereference_variable *ir)
{
- if (ir->var->mode == mode && ir->var->get_interface_type() == block) {
+ if (ir->var->data.mode == mode && ir->var->get_interface_type() == block) {
found = true;
return visit_stop;
}
@@ -4930,6 +4943,8 @@ ast_interface_block::hir(exec_list *instructions,
earlier_per_vertex->fields.structure[j].interpolation;
fields[i].centroid =
earlier_per_vertex->fields.structure[j].centroid;
+ fields[i].sample =
+ earlier_per_vertex->fields.structure[j].sample;
}
}
@@ -4980,7 +4995,7 @@ ast_interface_block::hir(exec_list *instructions,
* variable (or input block, see interface blocks below) needs to be
* declared as an array.
*/
- if (state->target == geometry_shader && !this->is_array &&
+ if (state->target == MESA_SHADER_GEOMETRY && !this->is_array &&
var_mode == ir_var_shader_in) {
_mesa_glsl_error(&loc, state, "geometry shader inputs must be arrays");
}
@@ -5035,7 +5050,7 @@ ast_interface_block::hir(exec_list *instructions,
* geometry shader input.
*/
if (this->array_size == NULL &&
- (state->target != geometry_shader || !this->layout.flags.q.in)) {
+ (state->target != MESA_SHADER_GEOMETRY || !this->layout.flags.q.in)) {
_mesa_glsl_error(&loc, state,
"only geometry shader inputs may be unsized "
"instance block arrays");
@@ -5054,7 +5069,7 @@ ast_interface_block::hir(exec_list *instructions,
var_mode);
}
- if (state->target == geometry_shader && var_mode == ir_var_shader_in)
+ if (state->target == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in)
handle_geometry_shader_input_decl(state, loc, var);
if (ir_variable *earlier =
@@ -5063,7 +5078,7 @@ ast_interface_block::hir(exec_list *instructions,
_mesa_glsl_error(&loc, state, "`%s' redeclared",
this->instance_name);
}
- earlier->how_declared = ir_var_declared_normally;
+ earlier->data.how_declared = ir_var_declared_normally;
earlier->type = var->type;
earlier->reinit_interface_type(block_type);
delete var;
@@ -5082,8 +5097,9 @@ ast_interface_block::hir(exec_list *instructions,
new(state) ir_variable(fields[i].type,
ralloc_strdup(state, fields[i].name),
var_mode);
- var->interpolation = fields[i].interpolation;
- var->centroid = fields[i].centroid;
+ var->data.interpolation = fields[i].interpolation;
+ var->data.centroid = fields[i].centroid;
+ var->data.sample = fields[i].sample;
var->init_interface_type(block_type);
if (redeclaring_per_vertex) {
@@ -5094,11 +5110,11 @@ ast_interface_block::hir(exec_list *instructions,
_mesa_glsl_error(&loc, state,
"redeclaration of gl_PerVertex can only "
"include built-in variables");
- } else if (earlier->how_declared == ir_var_declared_normally) {
+ } else if (earlier->data.how_declared == ir_var_declared_normally) {
_mesa_glsl_error(&loc, state,
"`%s' has already been redeclared", var->name);
} else {
- earlier->how_declared = ir_var_declared_in_block;
+ earlier->data.how_declared = ir_var_declared_in_block;
earlier->reinit_interface_type(block_type);
}
continue;
@@ -5111,8 +5127,8 @@ ast_interface_block::hir(exec_list *instructions,
* the UBO declaration itself doesn't get an ir_variable unless it
* has an instance name. This is ugly.
*/
- var->explicit_binding = this->layout.flags.q.explicit_binding;
- var->binding = this->layout.binding;
+ var->data.explicit_binding = this->layout.flags.q.explicit_binding;
+ var->data.binding = this->layout.binding;
state->symbols->add_variable(var);
instructions->push_tail(var);
@@ -5144,8 +5160,8 @@ ast_interface_block::hir(exec_list *instructions,
ir_variable *const var = ((ir_instruction *) node)->as_variable();
if (var != NULL &&
var->get_interface_type() == earlier_per_vertex &&
- var->mode == var_mode) {
- if (var->how_declared == ir_var_declared_normally) {
+ var->data.mode == var_mode) {
+ if (var->data.how_declared == ir_var_declared_normally) {
_mesa_glsl_error(&loc, state,
"redeclaration of gl_PerVertex cannot "
"follow a redeclaration of `%s'",
@@ -5200,7 +5216,7 @@ ast_gs_input_layout::hir(exec_list *instructions,
*/
foreach_list (node, instructions) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
- if (var == NULL || var->mode != ir_var_shader_in)
+ if (var == NULL || var->data.mode != ir_var_shader_in)
continue;
/* Note: gl_PrimitiveIDIn has mode ir_var_shader_in, but it's not an
@@ -5208,12 +5224,12 @@ ast_gs_input_layout::hir(exec_list *instructions,
*/
if (var->type->is_unsized_array()) {
- if (var->max_array_access >= num_vertices) {
+ if (var->data.max_array_access >= num_vertices) {
_mesa_glsl_error(&loc, state,
"this geometry shader input layout implies %u"
" vertices, but an access to element %u of input"
" `%s' already exists", num_vertices,
- var->max_array_access, var->name);
+ var->data.max_array_access, var->name);
} else {
var->type = glsl_type::get_array_instance(var->type->fields.array,
num_vertices);
@@ -5241,7 +5257,7 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
foreach_list(node, instructions) {
ir_variable *var = ((ir_instruction *)node)->as_variable();
- if (!var || !var->assigned)
+ if (!var || !var->data.assigned)
continue;
if (strcmp(var->name, "gl_FragColor") == 0)
@@ -5249,8 +5265,8 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state,
else if (strcmp(var->name, "gl_FragData") == 0)
gl_FragData_assigned = true;
else if (strncmp(var->name, "gl_", 3) != 0) {
- if (state->target == fragment_shader &&
- var->mode == ir_var_shader_out) {
+ if (state->target == MESA_SHADER_FRAGMENT &&
+ var->data.mode == ir_var_shader_out) {
user_defined_fs_output_assigned = true;
user_defined_fs_output = var;
}
@@ -5331,7 +5347,7 @@ remove_per_vertex_blocks(exec_list *instructions,
foreach_list_safe(node, instructions) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
if (var != NULL && var->get_interface_type() == per_vertex &&
- var->mode == mode) {
+ var->data.mode == mode) {
state->symbols->disable_variable(var->name);
var->remove();
}
diff --git a/mesalib/src/glsl/ast_type.cpp b/mesalib/src/glsl/ast_type.cpp
index 2b088bf8b..d758bfa1f 100644
--- a/mesalib/src/glsl/ast_type.cpp
+++ b/mesalib/src/glsl/ast_type.cpp
@@ -90,7 +90,8 @@ ast_type_qualifier::has_storage() const
bool
ast_type_qualifier::has_auxiliary_storage() const
{
- return this->flags.q.centroid;
+ return this->flags.q.centroid
+ || this->flags.q.sample;
}
const char*
diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp
index 8cb75e5ad..840a6c9a2 100644
--- a/mesalib/src/glsl/builtin_functions.cpp
+++ b/mesalib/src/glsl/builtin_functions.cpp
@@ -77,7 +77,7 @@ always_available(const _mesa_glsl_parse_state *state)
static bool
compatibility_vs_only(const _mesa_glsl_parse_state *state)
{
- return state->target == vertex_shader &&
+ return state->target == MESA_SHADER_VERTEX &&
state->language_version <= 130 &&
!state->es_shader;
}
@@ -85,13 +85,13 @@ compatibility_vs_only(const _mesa_glsl_parse_state *state)
static bool
fs_only(const _mesa_glsl_parse_state *state)
{
- return state->target == fragment_shader;
+ return state->target == MESA_SHADER_FRAGMENT;
}
static bool
gs_only(const _mesa_glsl_parse_state *state)
{
- return state->target == geometry_shader;
+ return state->target == MESA_SHADER_GEOMETRY;
}
static bool
@@ -103,7 +103,7 @@ v110(const _mesa_glsl_parse_state *state)
static bool
v110_fs_only(const _mesa_glsl_parse_state *state)
{
- return !state->es_shader && state->target == fragment_shader;
+ return !state->es_shader && state->target == MESA_SHADER_FRAGMENT;
}
static bool
@@ -122,7 +122,7 @@ static bool
v130_fs_only(const _mesa_glsl_parse_state *state)
{
return state->is_version(130, 300) &&
- state->target == fragment_shader;
+ state->target == MESA_SHADER_FRAGMENT;
}
static bool
@@ -155,7 +155,7 @@ lod_exists_in_stage(const _mesa_glsl_parse_state *state)
* Since ARB_shader_texture_lod can only be enabled on desktop GLSL, we
* don't need to explicitly check state->es_shader.
*/
- return state->target == vertex_shader ||
+ return state->target == MESA_SHADER_VERTEX ||
state->is_version(130, 300) ||
state->ARB_shader_texture_lod_enable;
}
@@ -223,7 +223,7 @@ texture_array_lod(const _mesa_glsl_parse_state *state)
static bool
fs_texture_array(const _mesa_glsl_parse_state *state)
{
- return state->target == fragment_shader &&
+ return state->target == MESA_SHADER_FRAGMENT &&
state->EXT_texture_array_enable;
}
@@ -243,7 +243,7 @@ texture_multisample(const _mesa_glsl_parse_state *state)
static bool
fs_texture_cube_map_array(const _mesa_glsl_parse_state *state)
{
- return state->target == fragment_shader &&
+ return state->target == MESA_SHADER_FRAGMENT &&
(state->is_version(400, 0) ||
state->ARB_texture_cube_map_array_enable);
}
@@ -265,7 +265,7 @@ texture_query_levels(const _mesa_glsl_parse_state *state)
static bool
texture_query_lod(const _mesa_glsl_parse_state *state)
{
- return state->target == fragment_shader &&
+ return state->target == MESA_SHADER_FRAGMENT &&
state->ARB_texture_query_lod_enable;
}
@@ -292,7 +292,7 @@ texture_gather_only(const _mesa_glsl_parse_state *state)
static bool
fs_oes_derivatives(const _mesa_glsl_parse_state *state)
{
- return state->target == fragment_shader &&
+ return state->target == MESA_SHADER_FRAGMENT &&
(state->is_version(110, 300) ||
state->OES_standard_derivatives_enable);
}
@@ -318,7 +318,7 @@ tex3d(const _mesa_glsl_parse_state *state)
static bool
fs_tex3d(const _mesa_glsl_parse_state *state)
{
- return state->target == fragment_shader &&
+ return state->target == MESA_SHADER_FRAGMENT &&
(!state->es_shader || state->OES_texture_3D_enable);
}
@@ -357,8 +357,6 @@ public:
ir_function_signature *find(_mesa_glsl_parse_state *state,
const char *name, exec_list *actual_parameters);
-private:
- void *mem_ctx;
/**
* A shader to hold all the built-in signatures; created by this module.
*
@@ -368,6 +366,9 @@ private:
*/
gl_shader *shader;
+private:
+ void *mem_ctx;
+
/** Global variables used by built-in functions. */
ir_variable *gl_ModelViewProjectionMatrix;
ir_variable *gl_Vertex;
@@ -608,8 +609,7 @@ builtin_builder::find(_mesa_glsl_parse_state *state,
* that the "no matching signature" error will list potential candidates
* from the available built-ins.
*/
- state->builtins_to_link[0] = shader;
- state->num_builtins_to_link = 1;
+ state->uses_builtin_functions = true;
ir_function *f = shader->symbols->get_function(name);
if (f == NULL)
@@ -4020,4 +4020,11 @@ _mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
{
return builtins.find(state, name, actual_parameters);
}
+
+gl_shader *
+_mesa_glsl_get_builtin_function_shader()
+{
+ return builtins.shader;
+}
+
/** @} */
diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp
index d57324c2f..ff9acb8d0 100644
--- a/mesalib/src/glsl/builtin_variables.cpp
+++ b/mesalib/src/glsl/builtin_variables.cpp
@@ -332,6 +332,7 @@ per_vertex_accumulator::add_field(int slot, const glsl_type *type,
this->fields[this->num_fields].location = slot;
this->fields[this->num_fields].interpolation = INTERP_QUALIFIER_NONE;
this->fields[this->num_fields].centroid = 0;
+ this->fields[this->num_fields].sample = 0;
this->num_fields++;
}
@@ -434,14 +435,14 @@ builtin_variable_generator::add_variable(const char *name,
enum ir_variable_mode mode, int slot)
{
ir_variable *var = new(symtab) ir_variable(type, name, mode);
- var->how_declared = ir_var_declared_implicitly;
+ var->data.how_declared = ir_var_declared_implicitly;
- switch (var->mode) {
+ switch (var->data.mode) {
case ir_var_auto:
case ir_var_shader_in:
case ir_var_uniform:
case ir_var_system_value:
- var->read_only = true;
+ var->data.read_only = true;
break;
case ir_var_shader_out:
break;
@@ -454,9 +455,9 @@ builtin_variable_generator::add_variable(const char *name,
break;
}
- var->location = slot;
- var->explicit_location = (slot >= 0);
- var->explicit_index = 0;
+ var->data.location = slot;
+ var->data.explicit_location = (slot >= 0);
+ var->data.explicit_index = 0;
/* Once the variable is created an initialized, add it to the symbol table
* and add the declaration to the IR stream.
@@ -523,7 +524,7 @@ builtin_variable_generator::add_const(const char *name, int value)
ir_var_auto, -1);
var->constant_value = new(var) ir_constant(value);
var->constant_initializer = new(var) ir_constant(value);
- var->has_initializer = true;
+ var->data.has_initializer = true;
return var;
}
@@ -792,9 +793,9 @@ builtin_variable_generator::generate_gs_special_vars()
*/
ir_variable *var;
var = add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveIDIn");
- var->interpolation = INTERP_QUALIFIER_FLAT;
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
var = add_output(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");
- var->interpolation = INTERP_QUALIFIER_FLAT;
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
}
@@ -812,7 +813,7 @@ builtin_variable_generator::generate_fs_special_vars()
if (state->is_version(150, 0)) {
ir_variable *var =
add_input(VARYING_SLOT_PRIMITIVE_ID, int_t, "gl_PrimitiveID");
- var->interpolation = INTERP_QUALIFIER_FLAT;
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
}
/* gl_FragColor and gl_FragData were deprecated starting in desktop GLSL
@@ -857,6 +858,10 @@ builtin_variable_generator::generate_fs_special_vars()
*/
add_output(FRAG_RESULT_SAMPLE_MASK, array(int_t, 1), "gl_SampleMask");
}
+
+ if (state->ARB_gpu_shader5_enable) {
+ add_system_value(SYSTEM_VALUE_SAMPLE_MASK_IN, array(int_t, 1), "gl_SampleMaskIn");
+ }
}
@@ -872,13 +877,13 @@ builtin_variable_generator::add_varying(int slot, const glsl_type *type,
const char *name_as_gs_input)
{
switch (state->target) {
- case geometry_shader:
+ case MESA_SHADER_GEOMETRY:
this->per_vertex_in.add_field(slot, type, name);
/* FALLTHROUGH */
- case vertex_shader:
+ case MESA_SHADER_VERTEX:
this->per_vertex_out.add_field(slot, type, name);
break;
- case fragment_shader:
+ case MESA_SHADER_FRAGMENT:
add_input(slot, type, name);
break;
}
@@ -896,7 +901,7 @@ builtin_variable_generator::generate_varyings()
add_varying(loc, type, name, name "In")
/* gl_Position and gl_PointSize are not visible from fragment shaders. */
- if (state->target != fragment_shader) {
+ if (state->target != MESA_SHADER_FRAGMENT) {
ADD_VARYING(VARYING_SLOT_POS, vec4_t, "gl_Position");
ADD_VARYING(VARYING_SLOT_PSIZ, float_t, "gl_PointSize");
}
@@ -909,7 +914,7 @@ builtin_variable_generator::generate_varyings()
if (compatibility) {
ADD_VARYING(VARYING_SLOT_TEX0, array(vec4_t, 0), "gl_TexCoord");
ADD_VARYING(VARYING_SLOT_FOGC, float_t, "gl_FogFragCoord");
- if (state->target == fragment_shader) {
+ if (state->target == MESA_SHADER_FRAGMENT) {
ADD_VARYING(VARYING_SLOT_COL0, vec4_t, "gl_Color");
ADD_VARYING(VARYING_SLOT_COL1, vec4_t, "gl_SecondaryColor");
} else {
@@ -921,13 +926,13 @@ builtin_variable_generator::generate_varyings()
}
}
- if (state->target == geometry_shader) {
+ if (state->target == MESA_SHADER_GEOMETRY) {
const glsl_type *per_vertex_in_type =
this->per_vertex_in.construct_interface_instance();
add_variable("gl_in", array(per_vertex_in_type, 0),
ir_var_shader_in, -1);
}
- if (state->target == vertex_shader || state->target == geometry_shader) {
+ if (state->target == MESA_SHADER_VERTEX || state->target == MESA_SHADER_GEOMETRY) {
const glsl_type *per_vertex_out_type =
this->per_vertex_out.construct_interface_instance();
const glsl_struct_field *fields = per_vertex_out_type->fields.structure;
@@ -935,8 +940,9 @@ builtin_variable_generator::generate_varyings()
ir_variable *var =
add_variable(fields[i].name, fields[i].type, ir_var_shader_out,
fields[i].location);
- var->interpolation = fields[i].interpolation;
- var->centroid = fields[i].centroid;
+ var->data.interpolation = fields[i].interpolation;
+ var->data.centroid = fields[i].centroid;
+ var->data.sample = fields[i].sample;
var->init_interface_type(per_vertex_out_type);
}
}
@@ -958,13 +964,13 @@ _mesa_glsl_initialize_variables(exec_list *instructions,
gen.generate_varyings();
switch (state->target) {
- case vertex_shader:
+ case MESA_SHADER_VERTEX:
gen.generate_vs_special_vars();
break;
- case geometry_shader:
+ case MESA_SHADER_GEOMETRY:
gen.generate_gs_special_vars();
break;
- case fragment_shader:
+ case MESA_SHADER_FRAGMENT:
gen.generate_fs_special_vars();
break;
}
diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll
index 822d70d6b..50875bf3b 100644
--- a/mesalib/src/glsl/glsl_lexer.ll
+++ b/mesalib/src/glsl/glsl_lexer.ll
@@ -520,7 +520,7 @@ readonly KEYWORD(0, 300, 0, 0, READONLY);
writeonly KEYWORD(0, 300, 0, 0, WRITEONLY);
resource KEYWORD(0, 300, 0, 0, RESOURCE);
patch KEYWORD(0, 300, 0, 0, PATCH);
-sample KEYWORD(0, 300, 0, 0, SAMPLE);
+sample KEYWORD_WITH_ALT(400, 300, 400, 0, yyextra->ARB_gpu_shader5_enable, SAMPLE);
subroutine KEYWORD(0, 300, 0, 0, SUBROUTINE);
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index ada3690f6..39767609d 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -1521,7 +1521,7 @@ type_qualifier:
{
if ($2.has_auxiliary_storage()) {
_mesa_glsl_error(&@1, state,
- "duplicate auxiliary storage qualifier (centroid)");
+ "duplicate auxiliary storage qualifier (centroid or sample)");
}
if (!state->ARB_shading_language_420pack_enable &&
@@ -1571,7 +1571,12 @@ auxiliary_storage_qualifier:
memset(& $$, 0, sizeof($$));
$$.flags.q.centroid = 1;
}
- /* TODO: "sample" and "patch" also go here someday. */
+ | SAMPLE
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.flags.q.sample = 1;
+ }
+ /* TODO: "patch" also goes here someday. */
storage_qualifier:
CONST_TOK
@@ -2214,11 +2219,11 @@ basic_interface_block:
* "It is illegal to have an input block in a vertex shader
* or an output block in a fragment shader"
*/
- if ((state->target == vertex_shader) && $1.flags.q.in) {
+ if ((state->target == MESA_SHADER_VERTEX) && $1.flags.q.in) {
_mesa_glsl_error(& @1, state,
"`in' interface block is not allowed for "
"a vertex shader");
- } else if ((state->target == fragment_shader) && $1.flags.q.out) {
+ } else if ((state->target == MESA_SHADER_FRAGMENT) && $1.flags.q.out) {
_mesa_glsl_error(& @1, state,
"`out' interface block is not allowed for "
"a fragment shader");
@@ -2372,7 +2377,7 @@ layout_defaults:
{
void *ctx = state;
$$ = NULL;
- if (state->target != geometry_shader) {
+ if (state->target != MESA_SHADER_GEOMETRY) {
_mesa_glsl_error(& @1, state,
"input layout qualifiers only valid in "
"geometry shaders");
@@ -2400,7 +2405,7 @@ layout_defaults:
| layout_qualifier OUT_TOK ';'
{
- if (state->target != geometry_shader) {
+ if (state->target != MESA_SHADER_GEOMETRY) {
_mesa_glsl_error(& @1, state,
"out layout qualifiers only valid in "
"geometry shaders");
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index d76d94b7a..5f19368d8 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -58,9 +58,9 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
: ctx(_ctx), switch_state()
{
switch (target) {
- case GL_VERTEX_SHADER: this->target = vertex_shader; break;
- case GL_FRAGMENT_SHADER: this->target = fragment_shader; break;
- case GL_GEOMETRY_SHADER: this->target = geometry_shader; break;
+ case GL_VERTEX_SHADER: this->target = MESA_SHADER_VERTEX; break;
+ case GL_FRAGMENT_SHADER: this->target = MESA_SHADER_FRAGMENT; break;
+ case GL_GEOMETRY_SHADER: this->target = MESA_SHADER_GEOMETRY; break;
}
this->scanner = NULL;
@@ -76,7 +76,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
this->loop_nesting_ast = NULL;
this->struct_specifier_depth = 0;
- this->num_builtins_to_link = 0;
+
+ this->uses_builtin_functions = false;
/* Set default language version and extensions */
this->language_version = ctx->Const.ForceGLSLVersion ?
@@ -366,12 +367,12 @@ _mesa_glsl_shader_target_name(GLenum type)
* our internal enum into short stage names.
*/
const char *
-_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target)
+_mesa_glsl_shader_target_name(gl_shader_type target)
{
switch (target) {
- case vertex_shader: return "vertex";
- case fragment_shader: return "fragment";
- case geometry_shader: return "geometry";
+ case MESA_SHADER_VERTEX: return "vertex";
+ case MESA_SHADER_FRAGMENT: return "fragment";
+ case MESA_SHADER_GEOMETRY: return "geometry";
}
assert(!"Should not get here.");
@@ -877,6 +878,8 @@ _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
if (q->flags.q.centroid)
printf("centroid ");
+ if (q->flags.q.sample)
+ printf("sample ");
if (q->flags.q.uniform)
printf("uniform ");
if (q->flags.q.smooth)
@@ -1532,10 +1535,7 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
shader->InfoLog = state->info_log;
shader->Version = state->language_version;
shader->IsES = state->es_shader;
-
- memcpy(shader->builtins_to_link, state->builtins_to_link,
- sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
- shader->num_builtins_to_link = state->num_builtins_to_link;
+ shader->uses_builtin_functions = state->uses_builtin_functions;
if (shader->UniformBlocks)
ralloc_free(shader->UniformBlocks);
diff --git a/mesalib/src/glsl/glsl_parser_extras.h b/mesalib/src/glsl/glsl_parser_extras.h
index d232bb3f6..622ddbac7 100644
--- a/mesalib/src/glsl/glsl_parser_extras.h
+++ b/mesalib/src/glsl/glsl_parser_extras.h
@@ -34,12 +34,6 @@
#include <stdlib.h>
#include "glsl_symbol_table.h"
-enum _mesa_glsl_parser_targets {
- vertex_shader,
- geometry_shader,
- fragment_shader
-};
-
struct gl_context;
struct glsl_switch_state {
@@ -171,7 +165,7 @@ struct _mesa_glsl_parse_state {
bool es_shader;
unsigned language_version;
- enum _mesa_glsl_parser_targets target;
+ gl_shader_type target;
/**
* Number of nested struct_specifier levels
@@ -361,9 +355,7 @@ struct _mesa_glsl_parse_state {
/** Extensions supported by the OpenGL implementation. */
const struct gl_extensions *extensions;
- /** Shaders containing built-in functions that are used for linking. */
- struct gl_shader *builtins_to_link[16];
- unsigned num_builtins_to_link;
+ bool uses_builtin_functions;
/**
* For geometry shaders, size of the most recently seen input declaration
@@ -433,7 +425,7 @@ extern bool _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
* Get the textual name of the specified shader target
*/
extern const char *
-_mesa_glsl_shader_target_name(enum _mesa_glsl_parser_targets target);
+_mesa_glsl_shader_target_name(gl_shader_type target);
#endif /* __cplusplus */
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index f74013096..12d4ac0ee 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -103,6 +103,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
this->fields.structure[i].location = fields[i].location;
this->fields.structure[i].interpolation = fields[i].interpolation;
this->fields.structure[i].centroid = fields[i].centroid;
+ this->fields.structure[i].sample = fields[i].sample;
this->fields.structure[i].row_major = fields[i].row_major;
}
}
@@ -130,6 +131,7 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
this->fields.structure[i].location = fields[i].location;
this->fields.structure[i].interpolation = fields[i].interpolation;
this->fields.structure[i].centroid = fields[i].centroid;
+ this->fields.structure[i].sample = fields[i].sample;
this->fields.structure[i].row_major = fields[i].row_major;
}
}
@@ -483,6 +485,9 @@ glsl_type::record_key_compare(const void *a, const void *b)
if (key1->fields.structure[i].centroid
!= key2->fields.structure[i].centroid)
return 1;
+ if (key1->fields.structure[i].sample
+ != key2->fields.structure[i].sample)
+ return 1;
}
return 0;
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index 96eee5e64..fb7c9288d 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -634,6 +634,12 @@ struct glsl_struct_field {
* in ir_variable::centroid). 0 otherwise.
*/
unsigned centroid:1;
+
+ /**
+ * For interface blocks, 1 if this variable uses sample interpolation (as
+ * in ir_variable::sample). 0 otherwise.
+ */
+ unsigned sample:1;
};
static inline unsigned int
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index ffff2976a..04a7b874a 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -1277,11 +1277,6 @@ ir_constant::is_basis() const
ir_loop::ir_loop()
{
this->ir_type = ir_type_loop;
- this->cmp = ir_unop_neg;
- this->from = NULL;
- this->to = NULL;
- this->increment = NULL;
- this->counter = NULL;
}
@@ -1364,7 +1359,7 @@ ir_dereference::is_lvalue() const
/* Every l-value derference chain eventually ends in a variable.
*/
- if ((var == NULL) || var->read_only)
+ if ((var == NULL) || var->data.read_only)
return false;
/* From page 17 (page 23 of the PDF) of the GLSL 1.20 spec:
@@ -1584,29 +1579,36 @@ ir_swizzle::variable_referenced() const
ir_variable::ir_variable(const struct glsl_type *type, const char *name,
ir_variable_mode mode)
- : max_array_access(0), max_ifc_array_access(NULL),
- read_only(false), centroid(false), invariant(false),
- how_declared(ir_var_declared_normally), mode(mode),
- interpolation(INTERP_QUALIFIER_NONE), atomic()
+ : max_ifc_array_access(NULL)
{
this->ir_type = ir_type_variable;
this->type = type;
this->name = ralloc_strdup(this, name);
- this->explicit_location = false;
- this->has_initializer = false;
- this->location = -1;
- this->location_frac = 0;
+ this->data.explicit_location = false;
+ this->data.has_initializer = false;
+ this->data.location = -1;
+ this->data.location_frac = 0;
this->warn_extension = NULL;
this->constant_value = NULL;
this->constant_initializer = NULL;
- this->origin_upper_left = false;
- this->pixel_center_integer = false;
- this->depth_layout = ir_depth_layout_none;
- this->used = false;
+ this->data.origin_upper_left = false;
+ this->data.pixel_center_integer = false;
+ this->data.depth_layout = ir_depth_layout_none;
+ this->data.used = false;
+ this->data.read_only = false;
+ this->data.centroid = false;
+ this->data.sample = false;
+ this->data.invariant = false;
+ this->data.how_declared = ir_var_declared_normally;
+ this->data.mode = mode;
+ this->data.interpolation = INTERP_QUALIFIER_NONE;
+ this->data.max_array_access = 0;
+ this->data.atomic.buffer_index = 0;
+ this->data.atomic.offset = 0;
if (type != NULL) {
if (type->base_type == GLSL_TYPE_SAMPLER)
- this->read_only = true;
+ this->data.read_only = true;
if (type->is_interface())
this->init_interface_type(type);
@@ -1634,9 +1636,9 @@ interpolation_string(unsigned interpolation)
glsl_interp_qualifier
ir_variable::determine_interpolation_mode(bool flat_shade)
{
- if (this->interpolation != INTERP_QUALIFIER_NONE)
- return (glsl_interp_qualifier) this->interpolation;
- int location = this->location;
+ if (this->data.interpolation != INTERP_QUALIFIER_NONE)
+ return (glsl_interp_qualifier) this->data.interpolation;
+ int location = this->data.location;
bool is_gl_Color =
location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1;
if (flat_shade && is_gl_Color)
@@ -1706,10 +1708,11 @@ ir_function_signature::qualifiers_match(exec_list *params)
ir_variable *a = (ir_variable *)iter_a.get();
ir_variable *b = (ir_variable *)iter_b.get();
- if (a->read_only != b->read_only ||
- !modes_match(a->mode, b->mode) ||
- a->interpolation != b->interpolation ||
- a->centroid != b->centroid) {
+ if (a->data.read_only != b->data.read_only ||
+ !modes_match(a->data.mode, b->data.mode) ||
+ a->data.interpolation != b->data.interpolation ||
+ a->data.centroid != b->data.centroid ||
+ a->data.sample != b->data.sample) {
/* parameter a's qualifiers don't match */
return a->name;
@@ -1729,12 +1732,6 @@ ir_function_signature::replace_parameters(exec_list *new_params)
* parameter information comes from the function prototype, it may either
* specify incorrect parameter names or not have names at all.
*/
- foreach_iter(exec_list_iterator, iter, parameters) {
- assert(((ir_instruction *) iter.get())->as_variable() != NULL);
-
- iter.remove();
- }
-
new_params->move_nodes_to(&parameters);
}
@@ -1899,9 +1896,9 @@ vertices_per_prim(GLenum prim)
const char *
mode_string(const ir_variable *var)
{
- switch (var->mode) {
+ switch (var->data.mode) {
case ir_var_auto:
- return (var->read_only) ? "global constant" : "global variable";
+ return (var->data.read_only) ? "global constant" : "global variable";
case ir_var_uniform:
return "uniform";
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index 4f775da4b..780959b73 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -86,6 +86,7 @@ enum ir_node_type {
ir_type_max /**< maximum ir_type enum number, for validation */
};
+
/**
* Base class of all IR instructions
*/
@@ -402,7 +403,7 @@ public:
*/
inline bool is_in_uniform_block() const
{
- return this->mode == ir_var_uniform && this->interface_type != NULL;
+ return this->data.mode == ir_var_uniform && this->interface_type != NULL;
}
/**
@@ -502,13 +503,6 @@ public:
const char *name;
/**
- * Highest element accessed with a constant expression array index
- *
- * Not used for non-array variables.
- */
- unsigned max_array_access;
-
- /**
* For variables which satisfy the is_interface_instance() predicate, this
* points to an array of integers such that if the ith member of the
* interface block is an array, max_ifc_array_access[i] is the maximum
@@ -521,177 +515,189 @@ public:
*/
unsigned *max_ifc_array_access;
- /**
- * Is the variable read-only?
- *
- * This is set for variables declared as \c const, shader inputs,
- * and uniforms.
- */
- unsigned read_only:1;
- unsigned centroid:1;
- unsigned invariant:1;
-
- /**
- * Has this variable been used for reading or writing?
- *
- * Several GLSL semantic checks require knowledge of whether or not a
- * variable has been used. For example, it is an error to redeclare a
- * variable as invariant after it has been used.
- *
- * This is only maintained in the ast_to_hir.cpp path, not in
- * Mesa's fixed function or ARB program paths.
- */
- unsigned used:1;
-
- /**
- * Has this variable been statically assigned?
- *
- * This answers whether the variable was assigned in any path of
- * the shader during ast_to_hir. This doesn't answer whether it is
- * still written after dead code removal, nor is it maintained in
- * non-ast_to_hir.cpp (GLSL parsing) paths.
- */
- unsigned assigned:1;
-
- /**
- * Enum indicating how the variable was declared. See
- * ir_var_declaration_type.
- *
- * This is used to detect certain kinds of illegal variable redeclarations.
- */
- unsigned how_declared:2;
-
- /**
- * Storage class of the variable.
- *
- * \sa ir_variable_mode
- */
- unsigned mode:4;
-
- /**
- * Interpolation mode for shader inputs / outputs
- *
- * \sa ir_variable_interpolation
- */
- unsigned interpolation:2;
-
- /**
- * \name ARB_fragment_coord_conventions
- * @{
- */
- unsigned origin_upper_left:1;
- unsigned pixel_center_integer:1;
- /*@}*/
+ struct ir_variable_data {
- /**
- * Was the location explicitly set in the shader?
- *
- * If the location is explicitly set in the shader, it \b cannot be changed
- * by the linker or by the API (e.g., calls to \c glBindAttribLocation have
- * no effect).
- */
- unsigned explicit_location:1;
- unsigned explicit_index:1;
-
- /**
- * Was an initial binding explicitly set in the shader?
- *
- * If so, constant_value contains an integer ir_constant representing the
- * initial binding point.
- */
- unsigned explicit_binding:1;
+ /**
+ * Is the variable read-only?
+ *
+ * This is set for variables declared as \c const, shader inputs,
+ * and uniforms.
+ */
+ unsigned read_only:1;
+ unsigned centroid:1;
+ unsigned sample:1;
+ unsigned invariant:1;
+
+ /**
+ * Has this variable been used for reading or writing?
+ *
+ * Several GLSL semantic checks require knowledge of whether or not a
+ * variable has been used. For example, it is an error to redeclare a
+ * variable as invariant after it has been used.
+ *
+ * This is only maintained in the ast_to_hir.cpp path, not in
+ * Mesa's fixed function or ARB program paths.
+ */
+ unsigned used:1;
+
+ /**
+ * Has this variable been statically assigned?
+ *
+ * This answers whether the variable was assigned in any path of
+ * the shader during ast_to_hir. This doesn't answer whether it is
+ * still written after dead code removal, nor is it maintained in
+ * non-ast_to_hir.cpp (GLSL parsing) paths.
+ */
+ unsigned assigned:1;
- /**
- * Does this variable have an initializer?
- *
- * This is used by the linker to cross-validiate initializers of global
- * variables.
- */
- unsigned has_initializer:1;
+ /**
+ * Enum indicating how the variable was declared. See
+ * ir_var_declaration_type.
+ *
+ * This is used to detect certain kinds of illegal variable redeclarations.
+ */
+ unsigned how_declared:2;
- /**
- * Is this variable a generic output or input that has not yet been matched
- * up to a variable in another stage of the pipeline?
- *
- * This is used by the linker as scratch storage while assigning locations
- * to generic inputs and outputs.
- */
- unsigned is_unmatched_generic_inout:1;
+ /**
+ * Storage class of the variable.
+ *
+ * \sa ir_variable_mode
+ */
+ unsigned mode:4;
- /**
- * If non-zero, then this variable may be packed along with other variables
- * into a single varying slot, so this offset should be applied when
- * accessing components. For example, an offset of 1 means that the x
- * component of this variable is actually stored in component y of the
- * location specified by \c location.
- */
- unsigned location_frac:2;
+ /**
+ * Interpolation mode for shader inputs / outputs
+ *
+ * \sa ir_variable_interpolation
+ */
+ unsigned interpolation:2;
- /**
- * Non-zero if this variable was created by lowering a named interface
- * block which was not an array.
- *
- * Note that this variable and \c from_named_ifc_block_array will never
- * both be non-zero.
- */
- unsigned from_named_ifc_block_nonarray:1;
+ /**
+ * \name ARB_fragment_coord_conventions
+ * @{
+ */
+ unsigned origin_upper_left:1;
+ unsigned pixel_center_integer:1;
+ /*@}*/
+
+ /**
+ * Was the location explicitly set in the shader?
+ *
+ * If the location is explicitly set in the shader, it \b cannot be changed
+ * by the linker or by the API (e.g., calls to \c glBindAttribLocation have
+ * no effect).
+ */
+ unsigned explicit_location:1;
+ unsigned explicit_index:1;
+
+ /**
+ * Was an initial binding explicitly set in the shader?
+ *
+ * If so, constant_value contains an integer ir_constant representing the
+ * initial binding point.
+ */
+ unsigned explicit_binding:1;
- /**
- * Non-zero if this variable was created by lowering a named interface
- * block which was an array.
- *
- * Note that this variable and \c from_named_ifc_block_nonarray will never
- * both be non-zero.
- */
- unsigned from_named_ifc_block_array:1;
+ /**
+ * Does this variable have an initializer?
+ *
+ * This is used by the linker to cross-validiate initializers of global
+ * variables.
+ */
+ unsigned has_initializer:1;
+
+ /**
+ * Is this variable a generic output or input that has not yet been matched
+ * up to a variable in another stage of the pipeline?
+ *
+ * This is used by the linker as scratch storage while assigning locations
+ * to generic inputs and outputs.
+ */
+ unsigned is_unmatched_generic_inout:1;
+
+ /**
+ * If non-zero, then this variable may be packed along with other variables
+ * into a single varying slot, so this offset should be applied when
+ * accessing components. For example, an offset of 1 means that the x
+ * component of this variable is actually stored in component y of the
+ * location specified by \c location.
+ */
+ unsigned location_frac:2;
+
+ /**
+ * Non-zero if this variable was created by lowering a named interface
+ * block which was not an array.
+ *
+ * Note that this variable and \c from_named_ifc_block_array will never
+ * both be non-zero.
+ */
+ unsigned from_named_ifc_block_nonarray:1;
+
+ /**
+ * Non-zero if this variable was created by lowering a named interface
+ * block which was an array.
+ *
+ * Note that this variable and \c from_named_ifc_block_nonarray will never
+ * both be non-zero.
+ */
+ unsigned from_named_ifc_block_array:1;
- /**
- * \brief Layout qualifier for gl_FragDepth.
- *
- * This is not equal to \c ir_depth_layout_none if and only if this
- * variable is \c gl_FragDepth and a layout qualifier is specified.
- */
- ir_depth_layout depth_layout;
+ /**
+ * \brief Layout qualifier for gl_FragDepth.
+ *
+ * This is not equal to \c ir_depth_layout_none if and only if this
+ * variable is \c gl_FragDepth and a layout qualifier is specified.
+ */
+ ir_depth_layout depth_layout;
+
+ /**
+ * Storage location of the base of this variable
+ *
+ * The precise meaning of this field depends on the nature of the variable.
+ *
+ * - Vertex shader input: one of the values from \c gl_vert_attrib.
+ * - Vertex shader output: one of the values from \c gl_varying_slot.
+ * - Geometry shader input: one of the values from \c gl_varying_slot.
+ * - Geometry shader output: one of the values from \c gl_varying_slot.
+ * - Fragment shader input: one of the values from \c gl_varying_slot.
+ * - Fragment shader output: one of the values from \c gl_frag_result.
+ * - Uniforms: Per-stage uniform slot number for default uniform block.
+ * - Uniforms: Index within the uniform block definition for UBO members.
+ * - Other: This field is not currently used.
+ *
+ * If the variable is a uniform, shader input, or shader output, and the
+ * slot has not been assigned, the value will be -1.
+ */
+ int location;
- /**
- * Storage location of the base of this variable
- *
- * The precise meaning of this field depends on the nature of the variable.
- *
- * - Vertex shader input: one of the values from \c gl_vert_attrib.
- * - Vertex shader output: one of the values from \c gl_varying_slot.
- * - Geometry shader input: one of the values from \c gl_varying_slot.
- * - Geometry shader output: one of the values from \c gl_varying_slot.
- * - Fragment shader input: one of the values from \c gl_varying_slot.
- * - Fragment shader output: one of the values from \c gl_frag_result.
- * - Uniforms: Per-stage uniform slot number for default uniform block.
- * - Uniforms: Index within the uniform block definition for UBO members.
- * - Other: This field is not currently used.
- *
- * If the variable is a uniform, shader input, or shader output, and the
- * slot has not been assigned, the value will be -1.
- */
- int location;
+ /**
+ * output index for dual source blending.
+ */
+ int index;
- /**
- * output index for dual source blending.
- */
- int index;
+ /**
+ * Initial binding point for a sampler or UBO.
+ *
+ * For array types, this represents the binding point for the first element.
+ */
+ int binding;
- /**
- * Initial binding point for a sampler or UBO.
- *
- * For array types, this represents the binding point for the first element.
- */
- int binding;
+ /**
+ * Location an atomic counter is stored at.
+ */
+ struct {
+ unsigned buffer_index;
+ unsigned offset;
+ } atomic;
+
+ /**
+ * Highest element accessed with a constant expression array index
+ *
+ * Not used for non-array variables.
+ */
+ unsigned max_array_access;
- /**
- * Location an atomic counter is stored at.
- */
- struct {
- unsigned buffer_index;
- unsigned offset;
- } atomic;
+ } data;
/**
* Built-in state that backs this uniform
@@ -1022,34 +1028,6 @@ public:
/** List of ir_instruction that make up the body of the loop. */
exec_list body_instructions;
-
- /**
- * \name Loop counter and controls
- *
- * Represents a loop like a FORTRAN \c do-loop.
- *
- * \note
- * If \c from and \c to are the same value, the loop will execute once.
- */
- /*@{*/
- ir_rvalue *from; /** Value of the loop counter on the first
- * iteration of the loop.
- */
- ir_rvalue *to; /** Value of the loop counter on the last
- * iteration of the loop.
- */
- ir_rvalue *increment;
- ir_variable *counter;
-
- /**
- * Comparison operation in the loop terminator.
- *
- * If any of the loop control fields are non-\c NULL, this field must be
- * one of \c ir_binop_less, \c ir_binop_greater, \c ir_binop_lequal,
- * \c ir_binop_gequal, \c ir_binop_equal, or \c ir_binop_nequal.
- */
- int cmp;
- /*@}*/
};
@@ -2344,6 +2322,9 @@ extern ir_function_signature *
_mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
const char *name, exec_list *actual_parameters);
+extern gl_shader *
+_mesa_glsl_get_builtin_function_shader(void);
+
extern void
_mesa_glsl_release_functions(void);
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp
index 40ed33afc..4e5cf68ca 100644
--- a/mesalib/src/glsl/ir_clone.cpp
+++ b/mesalib/src/glsl/ir_clone.cpp
@@ -41,35 +41,19 @@ ir_variable *
ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
{
ir_variable *var = new(mem_ctx) ir_variable(this->type, this->name,
- (ir_variable_mode) this->mode);
+ (ir_variable_mode) this->data.mode);
- var->max_array_access = this->max_array_access;
+ var->data.max_array_access = this->data.max_array_access;
if (this->is_interface_instance()) {
var->max_ifc_array_access =
rzalloc_array(var, unsigned, this->interface_type->length);
memcpy(var->max_ifc_array_access, this->max_ifc_array_access,
this->interface_type->length * sizeof(unsigned));
}
- var->read_only = this->read_only;
- var->centroid = this->centroid;
- var->invariant = this->invariant;
- var->interpolation = this->interpolation;
- var->location = this->location;
- var->index = this->index;
- var->binding = this->binding;
- var->atomic.buffer_index = this->atomic.buffer_index;
- var->atomic.offset = this->atomic.offset;
+
+ memcpy(&var->data, &this->data, sizeof(var->data));
+
var->warn_extension = this->warn_extension;
- var->origin_upper_left = this->origin_upper_left;
- var->pixel_center_integer = this->pixel_center_integer;
- var->explicit_location = this->explicit_location;
- var->explicit_index = this->explicit_index;
- var->explicit_binding = this->explicit_binding;
- var->has_initializer = this->has_initializer;
- var->depth_layout = this->depth_layout;
- var->assigned = this->assigned;
- var->how_declared = this->how_declared;
- var->used = this->used;
var->num_state_slots = this->num_state_slots;
if (this->state_slots) {
@@ -157,20 +141,11 @@ ir_loop::clone(void *mem_ctx, struct hash_table *ht) const
{
ir_loop *new_loop = new(mem_ctx) ir_loop();
- if (this->from)
- new_loop->from = this->from->clone(mem_ctx, ht);
- if (this->to)
- new_loop->to = this->to->clone(mem_ctx, ht);
- if (this->increment)
- new_loop->increment = this->increment->clone(mem_ctx, ht);
- new_loop->counter = counter;
-
foreach_iter(exec_list_iterator, iter, this->body_instructions) {
ir_instruction *ir = (ir_instruction *)iter.get();
new_loop->body_instructions.push_tail(ir->clone(mem_ctx, ht));
}
- new_loop->cmp = this->cmp;
return new_loop;
}
diff --git a/mesalib/src/glsl/ir_constant_expression.cpp b/mesalib/src/glsl/ir_constant_expression.cpp
index 0efd1d5b3..7ca865e22 100644
--- a/mesalib/src/glsl/ir_constant_expression.cpp
+++ b/mesalib/src/glsl/ir_constant_expression.cpp
@@ -1583,7 +1583,7 @@ ir_dereference_variable::constant_expression_value(struct hash_table *variable_c
/* The constant_value of a uniform variable is its initializer,
* not the lifetime constant value of the uniform.
*/
- if (var->mode == ir_var_uniform)
+ if (var->data.mode == ir_var_uniform)
return NULL;
if (!var->constant_value)
diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp
index 53cf469d9..bd5318d23 100644
--- a/mesalib/src/glsl/ir_function.cpp
+++ b/mesalib/src/glsl/ir_function.cpp
@@ -66,7 +66,7 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b)
/* Try to find an implicit conversion from actual to param. */
inexact_match = true;
- switch ((enum ir_variable_mode)(param->mode)) {
+ switch ((enum ir_variable_mode)(param->data.mode)) {
case ir_var_auto:
case ir_var_uniform:
case ir_var_temporary:
diff --git a/mesalib/src/glsl/ir_hv_accept.cpp b/mesalib/src/glsl/ir_hv_accept.cpp
index 941b25e97..2a1f70e5b 100644
--- a/mesalib/src/glsl/ir_hv_accept.cpp
+++ b/mesalib/src/glsl/ir_hv_accept.cpp
@@ -91,26 +91,6 @@ ir_loop::accept(ir_hierarchical_visitor *v)
if (s == visit_stop)
return s;
- if (s != visit_continue_with_parent) {
- if (this->from) {
- s = this->from->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- }
-
- if (this->to) {
- s = this->to->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- }
-
- if (this->increment) {
- s = this->increment->accept(v);
- if (s != visit_continue)
- return (s == visit_continue_with_parent) ? visit_continue : s;
- }
- }
-
return v->visit_leave(this);
}
diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp
index f85e573c4..01c5f7f1c 100644
--- a/mesalib/src/glsl/ir_print_visitor.cpp
+++ b/mesalib/src/glsl/ir_print_visitor.cpp
@@ -148,8 +148,9 @@ void ir_print_visitor::visit(ir_variable *ir)
{
printf("(declare ");
- const char *const cent = (ir->centroid) ? "centroid " : "";
- const char *const inv = (ir->invariant) ? "invariant " : "";
+ const char *const cent = (ir->data.centroid) ? "centroid " : "";
+ const char *const samp = (ir->data.sample) ? "sample " : "";
+ const char *const inv = (ir->data.invariant) ? "invariant " : "";
const char *const mode[] = { "", "uniform ", "shader_in ", "shader_out ",
"in ", "out ", "inout ",
"const_in ", "sys ", "temporary " };
@@ -157,8 +158,8 @@ void ir_print_visitor::visit(ir_variable *ir)
const char *const interp[] = { "", "smooth", "flat", "noperspective" };
STATIC_ASSERT(ARRAY_SIZE(interp) == INTERP_QUALIFIER_COUNT);
- printf("(%s%s%s%s) ",
- cent, inv, mode[ir->mode], interp[ir->interpolation]);
+ printf("(%s%s%s%s%s) ",
+ cent, samp, inv, mode[ir->data.mode], interp[ir->data.interpolation]);
print_type(ir->type);
printf(" %s)", unique_name(ir));
@@ -416,9 +417,9 @@ void ir_print_visitor::visit(ir_constant *ir)
if (ir->value.f[i] == 0.0f)
/* 0.0 == -0.0, so print with %f to get the proper sign. */
printf("%.1f", ir->value.f[i]);
- else if (abs(ir->value.f[i]) < 0.000001f)
+ else if (fabs(ir->value.f[i]) < 0.000001f)
printf("%a", ir->value.f[i]);
- else if (abs(ir->value.f[i]) > 1000000.0f)
+ else if (fabs(ir->value.f[i]) > 1000000.0f)
printf("%e", ir->value.f[i]);
else
printf("%f", ir->value.f[i]);
@@ -522,19 +523,7 @@ ir_print_visitor::visit(ir_if *ir)
void
ir_print_visitor::visit(ir_loop *ir)
{
- printf("(loop (");
- if (ir->counter != NULL)
- ir->counter->accept(this);
- printf(") (");
- if (ir->from != NULL)
- ir->from->accept(this);
- printf(") (");
- if (ir->to != NULL)
- ir->to->accept(this);
- printf(") (");
- if (ir->increment != NULL)
- ir->increment->accept(this);
- printf(") (\n");
+ printf("(loop (\n");
indentation++;
foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index 00e2db9a3..7970112ec 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -412,33 +412,35 @@ ir_reader::read_declaration(s_expression *expr)
// FINISHME: Check for duplicate/conflicting qualifiers.
if (strcmp(qualifier->value(), "centroid") == 0) {
- var->centroid = 1;
+ var->data.centroid = 1;
+ } else if (strcmp(qualifier->value(), "sample") == 0) {
+ var->data.sample = 1;
} else if (strcmp(qualifier->value(), "invariant") == 0) {
- var->invariant = 1;
+ var->data.invariant = 1;
} else if (strcmp(qualifier->value(), "uniform") == 0) {
- var->mode = ir_var_uniform;
+ var->data.mode = ir_var_uniform;
} else if (strcmp(qualifier->value(), "auto") == 0) {
- var->mode = ir_var_auto;
+ var->data.mode = ir_var_auto;
} else if (strcmp(qualifier->value(), "in") == 0) {
- var->mode = ir_var_function_in;
+ var->data.mode = ir_var_function_in;
} else if (strcmp(qualifier->value(), "shader_in") == 0) {
- var->mode = ir_var_shader_in;
+ var->data.mode = ir_var_shader_in;
} else if (strcmp(qualifier->value(), "const_in") == 0) {
- var->mode = ir_var_const_in;
+ var->data.mode = ir_var_const_in;
} else if (strcmp(qualifier->value(), "out") == 0) {
- var->mode = ir_var_function_out;
+ var->data.mode = ir_var_function_out;
} else if (strcmp(qualifier->value(), "shader_out") == 0) {
- var->mode = ir_var_shader_out;
+ var->data.mode = ir_var_shader_out;
} else if (strcmp(qualifier->value(), "inout") == 0) {
- var->mode = ir_var_function_inout;
+ var->data.mode = ir_var_function_inout;
} else if (strcmp(qualifier->value(), "temporary") == 0) {
- var->mode = ir_var_temporary;
+ var->data.mode = ir_var_temporary;
} else if (strcmp(qualifier->value(), "smooth") == 0) {
- var->interpolation = INTERP_QUALIFIER_SMOOTH;
+ var->data.interpolation = INTERP_QUALIFIER_SMOOTH;
} else if (strcmp(qualifier->value(), "flat") == 0) {
- var->interpolation = INTERP_QUALIFIER_FLAT;
+ var->data.interpolation = INTERP_QUALIFIER_FLAT;
} else if (strcmp(qualifier->value(), "noperspective") == 0) {
- var->interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
+ var->data.interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
} else {
ir_read_error(expr, "unknown qualifier: %s", qualifier->value());
return NULL;
@@ -486,18 +488,16 @@ ir_reader::read_if(s_expression *expr, ir_loop *loop_ctx)
ir_loop *
ir_reader::read_loop(s_expression *expr)
{
- s_expression *s_counter, *s_from, *s_to, *s_inc, *s_body;
+ s_expression *s_body;
- s_pattern pat[] = { "loop", s_counter, s_from, s_to, s_inc, s_body };
- if (!MATCH(expr, pat)) {
- ir_read_error(expr, "expected (loop <counter> <from> <to> "
- "<increment> <body>)");
+ s_pattern loop_pat[] = { "loop", s_body };
+ if (!MATCH(expr, loop_pat)) {
+ ir_read_error(expr, "expected (loop <body>)");
return NULL;
}
- // FINISHME: actually read the count/from/to fields.
-
ir_loop *loop = new(mem_ctx) ir_loop;
+
read_instructions(&loop->body_instructions, s_body, loop);
if (state->error) {
delete loop;
diff --git a/mesalib/src/glsl/ir_set_program_inouts.cpp b/mesalib/src/glsl/ir_set_program_inouts.cpp
index ab23538c3..0b49eb2b6 100644
--- a/mesalib/src/glsl/ir_set_program_inouts.cpp
+++ b/mesalib/src/glsl/ir_set_program_inouts.cpp
@@ -27,7 +27,7 @@
* Sets the InputsRead and OutputsWritten of Mesa programs.
*
* Additionally, for fragment shaders, sets the InterpQualifier array, the
- * IsCentroid bitfield, and the UsesDFdy flag.
+ * IsCentroid and IsSample bitfields, and the UsesDFdy flag.
*
* Mesa programs (gl_program, not gl_shader_program) have a set of
* flags indicating which varyings are read and written. Computing
@@ -75,9 +75,9 @@ private:
static inline bool
is_shader_inout(ir_variable *var)
{
- return var->mode == ir_var_shader_in ||
- var->mode == ir_var_shader_out ||
- var->mode == ir_var_system_value;
+ return var->data.mode == ir_var_shader_in ||
+ var->data.mode == ir_var_shader_out ||
+ var->data.mode == ir_var_system_value;
}
static void
@@ -93,20 +93,24 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len,
*/
for (int i = 0; i < len; i++) {
- GLbitfield64 bitfield = BITFIELD64_BIT(var->location + var->index + offset + i);
- if (var->mode == ir_var_shader_in) {
+ GLbitfield64 bitfield =
+ BITFIELD64_BIT(var->data.location + var->data.index + offset + i);
+ if (var->data.mode == ir_var_shader_in) {
prog->InputsRead |= bitfield;
if (is_fragment_shader) {
gl_fragment_program *fprog = (gl_fragment_program *) prog;
- fprog->InterpQualifier[var->location + var->index + offset + i] =
- (glsl_interp_qualifier) var->interpolation;
- if (var->centroid)
+ fprog->InterpQualifier[var->data.location +
+ var->data.index + offset + i] =
+ (glsl_interp_qualifier) var->data.interpolation;
+ if (var->data.centroid)
fprog->IsCentroid |= bitfield;
+ if (var->data.sample)
+ fprog->IsSample |= bitfield;
}
- } else if (var->mode == ir_var_system_value) {
+ } else if (var->data.mode == ir_var_system_value) {
prog->SystemValuesRead |= bitfield;
} else {
- assert(var->mode == ir_var_shader_out);
+ assert(var->data.mode == ir_var_shader_out);
prog->OutputsWritten |= bitfield;
}
}
@@ -121,7 +125,7 @@ ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var)
{
const glsl_type *type = var->type;
if (this->shader_type == GL_GEOMETRY_SHADER &&
- var->mode == ir_var_shader_in && type->is_array()) {
+ var->data.mode == ir_var_shader_in && type->is_array()) {
type = type->fields.array;
}
@@ -160,7 +164,7 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var,
const glsl_type *type = var->type;
if (this->shader_type == GL_GEOMETRY_SHADER &&
- var->mode == ir_var_shader_in) {
+ var->data.mode == ir_var_shader_in) {
/* The only geometry shader input that is not an array is
* gl_PrimitiveIDIn, and in that case, this code will never be reached,
* because gl_PrimitiveIDIn can't be indexed into in array fashion.
@@ -242,7 +246,7 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
if (ir_dereference_variable * const deref_var =
inner_array->array->as_dereference_variable()) {
if (this->shader_type == GL_GEOMETRY_SHADER &&
- deref_var->var->mode == ir_var_shader_in) {
+ deref_var->var->data.mode == ir_var_shader_in) {
/* foo is a geometry shader input, so i is the vertex, and j the
* part of the input we're accessing.
*/
@@ -261,7 +265,7 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
ir->array->as_dereference_variable()) {
/* ir => foo[i], where foo is a variable. */
if (this->shader_type == GL_GEOMETRY_SHADER &&
- deref_var->var->mode == ir_var_shader_in) {
+ deref_var->var->data.mode == ir_var_shader_in) {
/* foo is a geometry shader input, so i is the vertex, and we're
* accessing the entire input.
*/
@@ -341,6 +345,7 @@ do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
gl_fragment_program *fprog = (gl_fragment_program *) prog;
memset(fprog->InterpQualifier, 0, sizeof(fprog->InterpQualifier));
fprog->IsCentroid = 0;
+ fprog->IsSample = 0;
fprog->UsesDFdy = false;
fprog->UsesKill = false;
}
diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp
index 13e41a089..4bbb3ce65 100644
--- a/mesalib/src/glsl/ir_validate.cpp
+++ b/mesalib/src/glsl/ir_validate.cpp
@@ -63,7 +63,6 @@ public:
virtual ir_visitor_status visit_enter(ir_if *ir);
- virtual ir_visitor_status visit_leave(ir_loop *ir);
virtual ir_visitor_status visit_enter(ir_function *ir);
virtual ir_visitor_status visit_leave(ir_function *ir);
virtual ir_visitor_status visit_enter(ir_function_signature *ir);
@@ -149,42 +148,6 @@ ir_validate::visit_enter(ir_if *ir)
ir_visitor_status
-ir_validate::visit_leave(ir_loop *ir)
-{
- if (ir->counter != NULL) {
- if ((ir->from == NULL) || (ir->to == NULL) || (ir->increment == NULL)) {
- printf("ir_loop has invalid loop controls:\n"
- " counter: %p\n"
- " from: %p\n"
- " to: %p\n"
- " increment: %p\n",
- (void *) ir->counter, (void *) ir->from, (void *) ir->to,
- (void *) ir->increment);
- abort();
- }
-
- if ((ir->cmp < ir_binop_less) || (ir->cmp > ir_binop_nequal)) {
- printf("ir_loop has invalid comparitor %d\n", ir->cmp);
- abort();
- }
- } else {
- if ((ir->from != NULL) || (ir->to != NULL) || (ir->increment != NULL)) {
- printf("ir_loop has invalid loop controls:\n"
- " counter: %p\n"
- " from: %p\n"
- " to: %p\n"
- " increment: %p\n",
- (void *) ir->counter, (void *) ir->from, (void *) ir->to,
- (void *) ir->increment);
- abort();
- }
- }
-
- return visit_continue;
-}
-
-
-ir_visitor_status
ir_validate::visit_enter(ir_function *ir)
{
/* Function definitions cannot be nested.
@@ -679,9 +642,9 @@ ir_validate::visit(ir_variable *ir)
* to be out of bounds.
*/
if (ir->type->array_size() > 0) {
- if (ir->max_array_access >= ir->type->length) {
+ if (ir->data.max_array_access >= ir->type->length) {
printf("ir_variable has maximum access out of bounds (%d vs %d)\n",
- ir->max_array_access, ir->type->length - 1);
+ ir->data.max_array_access, ir->type->length - 1);
ir->print();
abort();
}
@@ -707,7 +670,7 @@ ir_validate::visit(ir_variable *ir)
}
}
- if (ir->constant_initializer != NULL && !ir->has_initializer) {
+ if (ir->constant_initializer != NULL && !ir->data.has_initializer) {
printf("ir_variable didn't have an initializer, but has a constant "
"initializer value.\n");
ir->print();
@@ -789,8 +752,8 @@ ir_validate::visit_enter(ir_call *ir)
printf("ir_call parameter type mismatch:\n");
goto dump_ir;
}
- if (formal_param->mode == ir_var_function_out
- || formal_param->mode == ir_var_function_inout) {
+ if (formal_param->data.mode == ir_var_function_out
+ || formal_param->data.mode == ir_var_function_inout) {
if (!actual_param->is_lvalue()) {
printf("ir_call out/inout parameters must be lvalues:\n");
goto dump_ir;
diff --git a/mesalib/src/glsl/link_atomics.cpp b/mesalib/src/glsl/link_atomics.cpp
index 2466bbd79..33903ad54 100644
--- a/mesalib/src/glsl/link_atomics.cpp
+++ b/mesalib/src/glsl/link_atomics.cpp
@@ -73,16 +73,16 @@ namespace {
const active_atomic_counter *const first = (active_atomic_counter *) a;
const active_atomic_counter *const second = (active_atomic_counter *) b;
- return int(first->var->atomic.offset) - int(second->var->atomic.offset);
+ return int(first->var->data.atomic.offset) - int(second->var->data.atomic.offset);
}
bool
check_atomic_counters_overlap(const ir_variable *x, const ir_variable *y)
{
- return ((x->atomic.offset >= y->atomic.offset &&
- x->atomic.offset < y->atomic.offset + y->type->atomic_size()) ||
- (y->atomic.offset >= x->atomic.offset &&
- y->atomic.offset < x->atomic.offset + x->type->atomic_size()));
+ return ((x->data.atomic.offset >= y->data.atomic.offset &&
+ x->data.atomic.offset < y->data.atomic.offset + y->type->atomic_size()) ||
+ (y->data.atomic.offset >= x->data.atomic.offset &&
+ y->data.atomic.offset < x->data.atomic.offset + x->type->atomic_size()));
}
active_atomic_buffer *
@@ -107,7 +107,7 @@ namespace {
unsigned id;
bool found = prog->UniformHash->get(id, var->name);
assert(found);
- active_atomic_buffer *buf = &buffers[var->binding];
+ active_atomic_buffer *buf = &buffers[var->data.binding];
/* If this is the first time the buffer is used, increment
* the counter of buffers used.
@@ -118,7 +118,7 @@ namespace {
buf->push_back(id, var);
buf->stage_references[i]++;
- buf->size = MAX2(buf->size, var->atomic.offset +
+ buf->size = MAX2(buf->size, var->data.atomic.offset +
var->type->atomic_size());
}
}
@@ -143,7 +143,7 @@ namespace {
linker_error(prog, "Atomic counter %s declared at offset %d "
"which is already in use.",
buffers[i].counters[j].var->name,
- buffers[i].counters[j].var->atomic.offset);
+ buffers[i].counters[j].var->data.atomic.offset);
}
}
}
@@ -190,9 +190,9 @@ link_assign_atomic_counter_resources(struct gl_context *ctx,
gl_uniform_storage *const storage = &prog->UniformStorage[id];
mab.Uniforms[j] = id;
- var->atomic.buffer_index = i;
+ var->data.atomic.buffer_index = i;
storage->atomic_buffer_index = i;
- storage->offset = var->atomic.offset;
+ storage->offset = var->data.atomic.offset;
storage->array_stride = (var->type->is_array() ?
var->type->element_type()->atomic_size() : 0);
}
diff --git a/mesalib/src/glsl/link_functions.cpp b/mesalib/src/glsl/link_functions.cpp
index 68aa62032..56f3f207e 100644
--- a/mesalib/src/glsl/link_functions.cpp
+++ b/mesalib/src/glsl/link_functions.cpp
@@ -201,8 +201,9 @@ public:
if (formal_param->type->is_array()) {
ir_dereference_variable *deref = actual_param->as_dereference_variable();
if (deref && deref->var && deref->var->type->is_array()) {
- deref->var->max_array_access =
- MAX2(formal_param->max_array_access, deref->var->max_array_access);
+ deref->var->data.max_array_access =
+ MAX2(formal_param->data.max_array_access,
+ deref->var->data.max_array_access);
}
}
}
@@ -234,8 +235,9 @@ public:
* we need to track the maximal access to the array as linking
* pulls more functions in that access the array.
*/
- var->max_array_access =
- MAX2(var->max_array_access, ir->var->max_array_access);
+ var->data.max_array_access =
+ MAX2(var->data.max_array_access,
+ ir->var->data.max_array_access);
if (var->type->length == 0 && ir->var->type->length != 0)
var->type = ir->var->type;
diff --git a/mesalib/src/glsl/link_interface_blocks.cpp b/mesalib/src/glsl/link_interface_blocks.cpp
index 6900fa94e..476963642 100644
--- a/mesalib/src/glsl/link_interface_blocks.cpp
+++ b/mesalib/src/glsl/link_interface_blocks.cpp
@@ -60,7 +60,7 @@ struct interface_block_definition
if (var->type->is_array())
array_size = var->type->length;
}
- explicitly_declared = (var->how_declared != ir_var_declared_implicitly);
+ explicitly_declared = (var->data.how_declared != ir_var_declared_implicitly);
}
/**
@@ -270,7 +270,7 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog,
continue;
interface_block_definitions *definitions;
- switch (var->mode) {
+ switch (var->data.mode) {
case ir_var_shader_in:
definitions = &in_interfaces;
break;
@@ -298,7 +298,7 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog,
*/
definitions->store(def);
} else if (!intrastage_match(prev_def, &def,
- (ir_variable_mode) var->mode)) {
+ (ir_variable_mode) var->data.mode)) {
linker_error(prog, "definitions of interface block `%s' do not"
" match\n", iface_type->name);
return;
@@ -318,7 +318,7 @@ validate_interstage_inout_blocks(struct gl_shader_program *prog,
/* Add input interfaces from the consumer to the symbol table. */
foreach_list(node, consumer->ir) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
- if (!var || !var->get_interface_type() || var->mode != ir_var_shader_in)
+ if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_in)
continue;
definitions.store(interface_block_definition(var));
@@ -327,7 +327,7 @@ validate_interstage_inout_blocks(struct gl_shader_program *prog,
/* Verify that the producer's output interfaces match. */
foreach_list(node, producer->ir) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
- if (!var || !var->get_interface_type() || var->mode != ir_var_shader_out)
+ if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_out)
continue;
interface_block_definition *consumer_def =
@@ -361,7 +361,7 @@ validate_interstage_uniform_blocks(struct gl_shader_program *prog,
const gl_shader *stage = stages[i];
foreach_list(node, stage->ir) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
- if (!var || !var->get_interface_type() || var->mode != ir_var_uniform)
+ if (!var || !var->get_interface_type() || var->data.mode != ir_var_uniform)
continue;
interface_block_definition *old_def =
diff --git a/mesalib/src/glsl/link_uniform_initializers.cpp b/mesalib/src/glsl/link_uniform_initializers.cpp
index 786aaf0b4..04daa1760 100644
--- a/mesalib/src/glsl/link_uniform_initializers.cpp
+++ b/mesalib/src/glsl/link_uniform_initializers.cpp
@@ -224,15 +224,15 @@ link_set_uniform_initializers(struct gl_shader_program *prog)
foreach_list(node, shader->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if (!var || var->mode != ir_var_uniform)
+ if (!var || var->data.mode != ir_var_uniform)
continue;
if (!mem_ctx)
mem_ctx = ralloc_context(NULL);
- if (var->explicit_binding) {
+ if (var->data.explicit_binding) {
linker::set_uniform_binding(mem_ctx, prog, var->name,
- var->type, var->binding);
+ var->type, var->data.binding);
} else if (var->constant_value) {
linker::set_uniform_initializer(mem_ctx, prog, var->name,
var->type, var->constant_value);
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index 0a15739c2..bda6e4ffb 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -75,7 +75,7 @@ program_resource_visitor::process(ir_variable *var)
*/
/* Only strdup the name if we actually will need to modify it. */
- if (var->from_named_ifc_block_array) {
+ if (var->data.from_named_ifc_block_array) {
/* lower_named_interface_blocks created this variable by lowering an
* interface block array to an array variable. For example if the
* original source code was:
@@ -108,7 +108,7 @@ program_resource_visitor::process(ir_variable *var)
recursion(var->type, &name, new_length, false, NULL);
}
ralloc_free(name);
- } else if (var->from_named_ifc_block_nonarray) {
+ } else if (var->data.from_named_ifc_block_nonarray) {
/* lower_named_interface_blocks created this variable by lowering a
* named interface block (non-array) to an ordinary variable. For
* example if the original source code was:
@@ -408,10 +408,10 @@ public:
const struct gl_uniform_block *const block =
&prog->UniformBlocks[ubo_block_index];
- assert(var->location != -1);
+ assert(var->data.location != -1);
const struct gl_uniform_buffer_variable *const ubo_var =
- &block->Uniforms[var->location];
+ &block->Uniforms[var->data.location];
ubo_row_major = ubo_var->RowMajor;
ubo_byte_offset = ubo_var->Offset;
@@ -637,10 +637,10 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
if ((var == NULL) || !var->is_in_uniform_block())
continue;
- assert(var->mode == ir_var_uniform);
+ assert(var->data.mode == ir_var_uniform);
if (var->is_interface_instance()) {
- var->location = 0;
+ var->data.location = 0;
continue;
}
@@ -669,13 +669,13 @@ link_update_uniform_buffer_variables(struct gl_shader *shader)
if (strncmp(var->name, begin, l) == 0) {
found = true;
- var->location = j;
+ var->data.location = j;
break;
}
} else if (!strcmp(var->name,
shader->UniformBlocks[i].Uniforms[j].Name)) {
found = true;
- var->location = j;
+ var->data.location = j;
break;
}
}
@@ -767,7 +767,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
foreach_list(node, sh->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != ir_var_uniform))
+ if ((var == NULL) || (var->data.mode != ir_var_uniform))
continue;
/* FINISHME: Update code to process built-in uniforms!
@@ -818,7 +818,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
foreach_list(node, prog->_LinkedShaders[i]->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != ir_var_uniform))
+ if ((var == NULL) || (var->data.mode != ir_var_uniform))
continue;
/* FINISHME: Update code to process built-in uniforms!
diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp
index be36b5f8f..229a4cb85 100644
--- a/mesalib/src/glsl/link_varyings.cpp
+++ b/mesalib/src/glsl/link_varyings.cpp
@@ -93,31 +93,43 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
/* Check that all of the qualifiers match between stages.
*/
- if (input->centroid != output->centroid) {
+ if (input->data.centroid != output->data.centroid) {
linker_error(prog,
"%s shader output `%s' %s centroid qualifier, "
"but %s shader input %s centroid qualifier\n",
_mesa_glsl_shader_target_name(producer_type),
output->name,
- (output->centroid) ? "has" : "lacks",
+ (output->data.centroid) ? "has" : "lacks",
_mesa_glsl_shader_target_name(consumer_type),
- (input->centroid) ? "has" : "lacks");
+ (input->data.centroid) ? "has" : "lacks");
return;
}
- if (input->invariant != output->invariant) {
+ if (input->data.sample != output->data.sample) {
+ linker_error(prog,
+ "%s shader output `%s' %s sample qualifier, "
+ "but %s shader input %s sample qualifier\n",
+ _mesa_glsl_shader_target_name(producer_type),
+ output->name,
+ (output->data.sample) ? "has" : "lacks",
+ _mesa_glsl_shader_target_name(consumer_type),
+ (input->data.sample) ? "has" : "lacks");
+ return;
+ }
+
+ if (input->data.invariant != output->data.invariant) {
linker_error(prog,
"%s shader output `%s' %s invariant qualifier, "
"but %s shader input %s invariant qualifier\n",
_mesa_glsl_shader_target_name(producer_type),
output->name,
- (output->invariant) ? "has" : "lacks",
+ (output->data.invariant) ? "has" : "lacks",
_mesa_glsl_shader_target_name(consumer_type),
- (input->invariant) ? "has" : "lacks");
+ (input->data.invariant) ? "has" : "lacks");
return;
}
- if (input->interpolation != output->interpolation) {
+ if (input->data.interpolation != output->data.interpolation) {
linker_error(prog,
"%s shader output `%s' specifies %s "
"interpolation qualifier, "
@@ -125,9 +137,9 @@ cross_validate_types_and_qualifiers(struct gl_shader_program *prog,
"interpolation qualifier\n",
_mesa_glsl_shader_target_name(producer_type),
output->name,
- interpolation_string(output->interpolation),
+ interpolation_string(output->data.interpolation),
_mesa_glsl_shader_target_name(consumer_type),
- interpolation_string(input->interpolation));
+ interpolation_string(input->data.interpolation));
return;
}
}
@@ -143,11 +155,11 @@ cross_validate_front_and_back_color(struct gl_shader_program *prog,
GLenum consumer_type,
GLenum producer_type)
{
- if (front_color != NULL && front_color->assigned)
+ if (front_color != NULL && front_color->data.assigned)
cross_validate_types_and_qualifiers(prog, input, front_color,
consumer_type, producer_type);
- if (back_color != NULL && back_color->assigned)
+ if (back_color != NULL && back_color->data.assigned)
cross_validate_types_and_qualifiers(prog, input, back_color,
consumer_type, producer_type);
}
@@ -166,7 +178,7 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
foreach_list(node, producer->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != ir_var_shader_out))
+ if ((var == NULL) || (var->data.mode != ir_var_shader_out))
continue;
parameters.add_variable(var);
@@ -184,10 +196,10 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
foreach_list(node, consumer->ir) {
ir_variable *const input = ((ir_instruction *) node)->as_variable();
- if ((input == NULL) || (input->mode != ir_var_shader_in))
+ if ((input == NULL) || (input->data.mode != ir_var_shader_in))
continue;
- if (strcmp(input->name, "gl_Color") == 0 && input->used) {
+ if (strcmp(input->name, "gl_Color") == 0 && input->data.used) {
const ir_variable *const front_color =
parameters.get_variable("gl_FrontColor");
@@ -197,7 +209,7 @@ cross_validate_outputs_to_inputs(struct gl_shader_program *prog,
cross_validate_front_and_back_color(prog, input,
front_color, back_color,
consumer->Type, producer->Type);
- } else if (strcmp(input->name, "gl_SecondaryColor") == 0 && input->used) {
+ } else if (strcmp(input->name, "gl_SecondaryColor") == 0 && input->data.used) {
const ir_variable *const front_color =
parameters.get_variable("gl_FrontSecondaryColor");
@@ -317,8 +329,8 @@ tfeedback_decl::assign_location(struct gl_context *ctx,
assert(this->is_varying());
unsigned fine_location
- = this->matched_candidate->toplevel_var->location * 4
- + this->matched_candidate->toplevel_var->location_frac
+ = this->matched_candidate->toplevel_var->data.location * 4
+ + this->matched_candidate->toplevel_var->data.location_frac
+ this->matched_candidate->offset;
if (this->matched_candidate->type->is_array()) {
@@ -734,7 +746,7 @@ varying_matches::~varying_matches()
void
varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
{
- if (!producer_var->is_unmatched_generic_inout) {
+ if (!producer_var->data.is_unmatched_generic_inout) {
/* Either a location already exists for this variable (since it is part
* of fixed functionality), or it has already been recorded as part of a
* previous match.
@@ -752,12 +764,14 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
* regardless of where they appear. We can trivially satisfy that
* requirement by changing the interpolation type to flat here.
*/
- producer_var->centroid = false;
- producer_var->interpolation = INTERP_QUALIFIER_FLAT;
+ producer_var->data.centroid = false;
+ producer_var->data.sample = false;
+ producer_var->data.interpolation = INTERP_QUALIFIER_FLAT;
if (consumer_var) {
- consumer_var->centroid = false;
- consumer_var->interpolation = INTERP_QUALIFIER_FLAT;
+ consumer_var->data.centroid = false;
+ consumer_var->data.sample = false;
+ consumer_var->data.interpolation = INTERP_QUALIFIER_FLAT;
}
}
@@ -784,9 +798,9 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
this->matches[this->num_matches].producer_var = producer_var;
this->matches[this->num_matches].consumer_var = consumer_var;
this->num_matches++;
- producer_var->is_unmatched_generic_inout = 0;
+ producer_var->data.is_unmatched_generic_inout = 0;
if (consumer_var)
- consumer_var->is_unmatched_generic_inout = 0;
+ consumer_var->data.is_unmatched_generic_inout = 0;
}
@@ -838,12 +852,12 @@ varying_matches::store_locations(unsigned producer_base,
unsigned slot = generic_location / 4;
unsigned offset = generic_location % 4;
- producer_var->location = producer_base + slot;
- producer_var->location_frac = offset;
+ producer_var->data.location = producer_base + slot;
+ producer_var->data.location_frac = offset;
if (consumer_var) {
- assert(consumer_var->location == -1);
- consumer_var->location = consumer_base + slot;
- consumer_var->location_frac = offset;
+ assert(consumer_var->data.location == -1);
+ consumer_var->data.location = consumer_base + slot;
+ consumer_var->data.location_frac = offset;
}
}
}
@@ -873,9 +887,9 @@ varying_matches::compute_packing_class(ir_variable *var)
*
* Therefore, the packing class depends only on the interpolation type.
*/
- unsigned packing_class = var->centroid ? 1 : 0;
+ unsigned packing_class = var->data.centroid | (var->data.sample << 1);
packing_class *= 4;
- packing_class += var->interpolation;
+ packing_class += var->data.interpolation;
return packing_class;
}
@@ -933,8 +947,8 @@ is_varying_var(GLenum shaderType, const ir_variable *var)
{
/* Only fragment shaders will take a varying variable as an input */
if (shaderType == GL_FRAGMENT_SHADER &&
- var->mode == ir_var_shader_in) {
- switch (var->location) {
+ var->data.mode == ir_var_shader_in) {
+ switch (var->data.location) {
case VARYING_SLOT_POS:
case VARYING_SLOT_FACE:
case VARYING_SLOT_PNTC:
@@ -1082,7 +1096,7 @@ assign_varying_locations(struct gl_context *ctx,
ir_variable *const input_var =
((ir_instruction *) node)->as_variable();
- if ((input_var != NULL) && (input_var->mode == ir_var_shader_in)) {
+ if ((input_var != NULL) && (input_var->data.mode == ir_var_shader_in)) {
if (input_var->get_interface_type() != NULL) {
char *const iface_field_name =
ralloc_asprintf(mem_ctx, "%s.%s",
@@ -1101,7 +1115,7 @@ assign_varying_locations(struct gl_context *ctx,
foreach_list(node, producer->ir) {
ir_variable *const output_var = ((ir_instruction *) node)->as_variable();
- if ((output_var == NULL) || (output_var->mode != ir_var_shader_out))
+ if ((output_var == NULL) || (output_var->data.mode != ir_var_shader_out))
continue;
tfeedback_candidate_generator g(mem_ctx, tfeedback_candidates);
@@ -1121,7 +1135,7 @@ assign_varying_locations(struct gl_context *ctx,
(ir_variable *) hash_table_find(consumer_inputs, output_var->name);
}
- if (input_var && input_var->mode != ir_var_shader_in)
+ if (input_var && input_var->data.mode != ir_var_shader_in)
input_var = NULL;
if (input_var) {
@@ -1143,7 +1157,7 @@ assign_varying_locations(struct gl_context *ctx,
return false;
}
- if (matched_candidate->toplevel_var->is_unmatched_generic_inout)
+ if (matched_candidate->toplevel_var->data.is_unmatched_generic_inout)
matches.record(matched_candidate->toplevel_var, NULL);
}
@@ -1185,8 +1199,8 @@ assign_varying_locations(struct gl_context *ctx,
foreach_list(node, consumer->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if (var && var->mode == ir_var_shader_in &&
- var->is_unmatched_generic_inout) {
+ if (var && var->data.mode == ir_var_shader_in &&
+ var->data.is_unmatched_generic_inout) {
if (prog->Version <= 120) {
/* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
*
@@ -1211,7 +1225,7 @@ assign_varying_locations(struct gl_context *ctx,
/* An 'in' variable is only really a shader input if its
* value is written by the previous stage.
*/
- var->mode = ir_var_auto;
+ var->data.mode = ir_var_auto;
}
}
}
@@ -1229,7 +1243,7 @@ check_against_output_limit(struct gl_context *ctx,
foreach_list(node, producer->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if (var && var->mode == ir_var_shader_out &&
+ if (var && var->data.mode == ir_var_shader_out &&
is_varying_var(producer->Type, var)) {
output_vectors += var->type->count_attribute_slots();
}
@@ -1278,7 +1292,7 @@ check_against_input_limit(struct gl_context *ctx,
foreach_list(node, consumer->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if (var && var->mode == ir_var_shader_in &&
+ if (var && var->data.mode == ir_var_shader_in &&
is_varying_var(consumer->Type, var)) {
input_vectors += var->type->count_attribute_slots();
}
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 1366077f7..a6133ea9c 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -114,8 +114,8 @@ public:
ir_rvalue *param_rval = (ir_rvalue *)iter.get();
ir_variable *sig_param = (ir_variable *)sig_iter.get();
- if (sig_param->mode == ir_var_function_out ||
- sig_param->mode == ir_var_function_inout) {
+ if (sig_param->data.mode == ir_var_function_out ||
+ sig_param->data.mode == ir_var_function_inout) {
ir_variable *var = param_rval->variable_referenced();
if (var && strcmp(name, var->name) == 0) {
found = true;
@@ -198,7 +198,7 @@ public:
virtual ir_visitor_status visit(ir_variable *var)
{
- if (!var->type->is_array() || var->mode != ir_var_shader_in)
+ if (!var->type->is_array() || var->data.mode != ir_var_shader_in)
return visit_continue;
unsigned size = var->type->length;
@@ -217,16 +217,16 @@ public:
* array using an index too large for its actual size assigned at link
* time.
*/
- if (var->max_array_access >= this->num_vertices) {
+ if (var->data.max_array_access >= this->num_vertices) {
linker_error(this->prog, "geometry shader accesses element %i of "
"%s, but only %i input vertices\n",
- var->max_array_access, var->name, this->num_vertices);
+ var->data.max_array_access, var->name, this->num_vertices);
return visit_continue;
}
var->type = glsl_type::get_array_instance(var->type->element_type(),
this->num_vertices);
- var->max_array_access = this->num_vertices - 1;
+ var->data.max_array_access = this->num_vertices - 1;
return visit_continue;
}
@@ -379,9 +379,9 @@ link_invalidate_variable_locations(exec_list *ir)
* shader inputs (via layout(location=...)), and generic fragment shader
* outputs (also via layout(location=...)).
*/
- if (!var->explicit_location) {
- var->location = -1;
- var->location_frac = 0;
+ if (!var->data.explicit_location) {
+ var->data.location = -1;
+ var->data.location_frac = 0;
}
/* ir_variable::is_unmatched_generic_inout is used by the linker while
@@ -396,10 +396,10 @@ link_invalidate_variable_locations(exec_list *ir)
* GL_ARB_separate_shader_objects is supported. When that extension is
* implemented, this function will need some modifications.
*/
- if (!var->explicit_location) {
- var->is_unmatched_generic_inout = 1;
+ if (!var->data.explicit_location) {
+ var->data.is_unmatched_generic_inout = 1;
} else {
- var->is_unmatched_generic_inout = 0;
+ var->data.is_unmatched_generic_inout = 0;
}
}
}
@@ -580,13 +580,13 @@ cross_validate_globals(struct gl_shader_program *prog,
if (var == NULL)
continue;
- if (uniforms_only && (var->mode != ir_var_uniform))
+ if (uniforms_only && (var->data.mode != ir_var_uniform))
continue;
/* Don't cross validate temporaries that are at global scope. These
* will eventually get pulled into the shaders 'main'.
*/
- if (var->mode == ir_var_temporary)
+ if (var->data.mode == ir_var_temporary)
continue;
/* If a global with this name has already been seen, verify that the
@@ -619,17 +619,17 @@ cross_validate_globals(struct gl_shader_program *prog,
}
}
- if (var->explicit_location) {
- if (existing->explicit_location
- && (var->location != existing->location)) {
+ if (var->data.explicit_location) {
+ if (existing->data.explicit_location
+ && (var->data.location != existing->data.location)) {
linker_error(prog, "explicit locations for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
return;
}
- existing->location = var->location;
- existing->explicit_location = true;
+ existing->data.location = var->data.location;
+ existing->data.explicit_location = true;
}
/* From the GLSL 4.20 specification:
@@ -638,21 +638,21 @@ cross_validate_globals(struct gl_shader_program *prog,
* opaque-uniform name. However, it is not an error to specify a
* binding on some but not all declarations for the same name"
*/
- if (var->explicit_binding) {
- if (existing->explicit_binding &&
- var->binding != existing->binding) {
+ if (var->data.explicit_binding) {
+ if (existing->data.explicit_binding &&
+ var->data.binding != existing->data.binding) {
linker_error(prog, "explicit bindings for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
return;
}
- existing->binding = var->binding;
- existing->explicit_binding = true;
+ existing->data.binding = var->data.binding;
+ existing->data.explicit_binding = true;
}
if (var->type->contains_atomic() &&
- var->atomic.offset != existing->atomic.offset) {
+ var->data.atomic.offset != existing->data.atomic.offset) {
linker_error(prog, "offset specifications for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
@@ -671,9 +671,9 @@ cross_validate_globals(struct gl_shader_program *prog,
* of qualifiers."
*/
if (strcmp(var->name, "gl_FragDepth") == 0) {
- bool layout_declared = var->depth_layout != ir_depth_layout_none;
+ bool layout_declared = var->data.depth_layout != ir_depth_layout_none;
bool layout_differs =
- var->depth_layout != existing->depth_layout;
+ var->data.depth_layout != existing->data.depth_layout;
if (layout_declared && layout_differs) {
linker_error(prog,
@@ -682,7 +682,7 @@ cross_validate_globals(struct gl_shader_program *prog,
"the same set of qualifiers.");
}
- if (var->used && layout_differs) {
+ if (var->data.used && layout_differs) {
linker_error(prog,
"If gl_FragDepth is redeclared with a layout "
"qualifier in any fragment shader, it must be "
@@ -734,8 +734,8 @@ cross_validate_globals(struct gl_shader_program *prog,
}
}
- if (var->has_initializer) {
- if (existing->has_initializer
+ if (var->data.has_initializer) {
+ if (existing->data.has_initializer
&& (var->constant_initializer == NULL
|| existing->constant_initializer == NULL)) {
linker_error(prog,
@@ -750,21 +750,27 @@ cross_validate_globals(struct gl_shader_program *prog,
* otherwise) will propagate the existence to the variable
* stored in the symbol table.
*/
- existing->has_initializer = true;
+ existing->data.has_initializer = true;
}
- if (existing->invariant != var->invariant) {
+ if (existing->data.invariant != var->data.invariant) {
linker_error(prog, "declarations for %s `%s' have "
"mismatching invariant qualifiers\n",
mode_string(var), var->name);
return;
}
- if (existing->centroid != var->centroid) {
+ if (existing->data.centroid != var->data.centroid) {
linker_error(prog, "declarations for %s `%s' have "
"mismatching centroid qualifiers\n",
mode_string(var), var->name);
return;
}
+ if (existing->data.sample != var->data.sample) {
+ linker_error(prog, "declarations for %s `%s` have "
+ "mismatching sample qualifiers\n",
+ mode_string(var), var->name);
+ return;
+ }
} else
variables.add_variable(var);
}
@@ -884,7 +890,7 @@ remap_variables(ir_instruction *inst, struct gl_shader *target,
virtual ir_visitor_status visit(ir_dereference_variable *ir)
{
- if (ir->var->mode == ir_var_temporary) {
+ if (ir->var->data.mode == ir_var_temporary) {
ir_variable *var = (ir_variable *) hash_table_find(temps, ir->var);
assert(var != NULL);
@@ -958,13 +964,13 @@ move_non_declarations(exec_list *instructions, exec_node *last,
continue;
ir_variable *var = inst->as_variable();
- if ((var != NULL) && (var->mode != ir_var_temporary))
+ if ((var != NULL) && (var->data.mode != ir_var_temporary))
continue;
assert(inst->as_assignment()
|| inst->as_call()
|| inst->as_if() /* for initializers with the ?: operator */
- || ((var != NULL) && (var->mode == ir_var_temporary)));
+ || ((var != NULL) && (var->data.mode == ir_var_temporary)));
if (make_copies) {
inst = inst->clone(target, NULL);
@@ -1036,7 +1042,7 @@ public:
virtual ir_visitor_status visit(ir_variable *var)
{
- fixup_type(&var->type, var->max_array_access);
+ fixup_type(&var->type, var->data.max_array_access);
if (var->type->is_interface()) {
if (interface_contains_unsized_arrays(var->type)) {
const glsl_type *new_type =
@@ -1405,36 +1411,38 @@ link_intrastage_shaders(void *mem_ctx,
insertion_point, true, linked);
}
- /* Resolve initializers for global variables in the linked shader.
- */
- unsigned num_linking_shaders = num_shaders;
- for (unsigned i = 0; i < num_shaders; i++)
- num_linking_shaders += shader_list[i]->num_builtins_to_link;
+ /* Check if any shader needs built-in functions. */
+ bool need_builtins = false;
+ for (unsigned i = 0; i < num_shaders; i++) {
+ if (shader_list[i]->uses_builtin_functions) {
+ need_builtins = true;
+ break;
+ }
+ }
- gl_shader **linking_shaders =
- (gl_shader **) calloc(num_linking_shaders, sizeof(gl_shader *));
+ bool ok;
+ if (need_builtins) {
+ /* Make a temporary array one larger than shader_list, which will hold
+ * the built-in function shader as well.
+ */
+ gl_shader **linking_shaders = (gl_shader **)
+ calloc(num_shaders + 1, sizeof(gl_shader *));
+ memcpy(linking_shaders, shader_list, num_shaders * sizeof(gl_shader *));
+ linking_shaders[num_shaders] = _mesa_glsl_get_builtin_function_shader();
- memcpy(linking_shaders, shader_list,
- sizeof(linking_shaders[0]) * num_shaders);
+ ok = link_function_calls(prog, linked, linking_shaders, num_shaders + 1);
- unsigned idx = num_shaders;
- for (unsigned i = 0; i < num_shaders; i++) {
- memcpy(&linking_shaders[idx], shader_list[i]->builtins_to_link,
- sizeof(linking_shaders[0]) * shader_list[i]->num_builtins_to_link);
- idx += shader_list[i]->num_builtins_to_link;
+ free(linking_shaders);
+ } else {
+ ok = link_function_calls(prog, linked, shader_list, num_shaders);
}
- assert(idx == num_linking_shaders);
- if (!link_function_calls(prog, linked, linking_shaders,
- num_linking_shaders)) {
+ if (!ok) {
ctx->Driver.DeleteShader(ctx, linked);
- free(linking_shaders);
return NULL;
}
- free(linking_shaders);
-
/* At this point linked should contain all of the linked IR, so
* validate it to make sure nothing went wrong.
*/
@@ -1486,7 +1494,7 @@ update_array_sizes(struct gl_shader_program *prog)
foreach_list(node, prog->_LinkedShaders[i]->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != ir_var_uniform) ||
+ if ((var == NULL) || (var->data.mode != ir_var_uniform) ||
!var->type->is_array())
continue;
@@ -1501,7 +1509,7 @@ update_array_sizes(struct gl_shader_program *prog)
if (var->is_in_uniform_block() || var->type->contains_atomic())
continue;
- unsigned int size = var->max_array_access;
+ unsigned int size = var->data.max_array_access;
for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) {
if (prog->_LinkedShaders[j] == NULL)
continue;
@@ -1512,8 +1520,8 @@ update_array_sizes(struct gl_shader_program *prog)
continue;
if (strcmp(var->name, other_var->name) == 0 &&
- other_var->max_array_access > size) {
- size = other_var->max_array_access;
+ other_var->data.max_array_access > size) {
+ size = other_var->data.max_array_access;
}
}
}
@@ -1652,16 +1660,17 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
foreach_list(node, sh->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != (unsigned) direction))
+ if ((var == NULL) || (var->data.mode != (unsigned) direction))
continue;
- if (var->explicit_location) {
- if ((var->location >= (int)(max_index + generic_base))
- || (var->location < 0)) {
+ if (var->data.explicit_location) {
+ if ((var->data.location >= (int)(max_index + generic_base))
+ || (var->data.location < 0)) {
linker_error(prog,
"invalid explicit location %d specified for `%s'\n",
- (var->location < 0)
- ? var->location : var->location - generic_base,
+ (var->data.location < 0)
+ ? var->data.location
+ : var->data.location - generic_base,
var->name);
return false;
}
@@ -1670,8 +1679,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
if (prog->AttributeBindings->get(binding, var->name)) {
assert(binding >= VERT_ATTRIB_GENERIC0);
- var->location = binding;
- var->is_unmatched_generic_inout = 0;
+ var->data.location = binding;
+ var->data.is_unmatched_generic_inout = 0;
}
} else if (target_index == MESA_SHADER_FRAGMENT) {
unsigned binding;
@@ -1679,11 +1688,11 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
if (prog->FragDataBindings->get(binding, var->name)) {
assert(binding >= FRAG_RESULT_DATA0);
- var->location = binding;
- var->is_unmatched_generic_inout = 0;
+ var->data.location = binding;
+ var->data.is_unmatched_generic_inout = 0;
if (prog->FragDataIndexBindings->get(index, var->name)) {
- var->index = index;
+ var->data.index = index;
}
}
}
@@ -1694,8 +1703,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
* add it to the list of variables that need linker-assigned locations.
*/
const unsigned slots = var->type->count_attribute_slots();
- if (var->location != -1) {
- if (var->location >= generic_base && var->index < 1) {
+ if (var->data.location != -1) {
+ if (var->data.location >= generic_base && var->data.index < 1) {
/* From page 61 of the OpenGL 4.0 spec:
*
* "LinkProgram will fail if the attribute bindings assigned
@@ -1729,7 +1738,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
/* Mask representing the contiguous slots that will be used by
* this attribute.
*/
- const unsigned attr = var->location - generic_base;
+ const unsigned attr = var->data.location - generic_base;
const unsigned use_mask = (1 << slots) - 1;
/* Generate a link error if the set of bits requested for this
@@ -1795,8 +1804,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
return false;
}
- to_assign[i].var->location = generic_base + location;
- to_assign[i].var->is_unmatched_generic_inout = 0;
+ to_assign[i].var->data.location = generic_base + location;
+ to_assign[i].var->data.is_unmatched_generic_inout = 0;
used_locations |= (use_mask << location);
}
@@ -1813,15 +1822,15 @@ demote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode)
foreach_list(node, sh->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != int(mode)))
+ if ((var == NULL) || (var->data.mode != int(mode)))
continue;
/* A shader 'in' or 'out' variable is only really an input or output if
* its value is used by other shader stages. This will cause the variable
* to have a location assigned.
*/
- if (var->is_unmatched_generic_inout) {
- var->mode = ir_var_auto;
+ if (var->data.is_unmatched_generic_inout) {
+ var->data.mode = ir_var_auto;
}
}
}
@@ -1849,12 +1858,12 @@ store_fragdepth_layout(struct gl_shader_program *prog)
foreach_list(node, ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
- if (var == NULL || var->mode != ir_var_shader_out) {
+ if (var == NULL || var->data.mode != ir_var_shader_out) {
continue;
}
if (strcmp(var->name, "gl_FragDepth") == 0) {
- switch (var->depth_layout) {
+ switch (var->data.depth_layout) {
case ir_depth_layout_none:
prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE;
return;
diff --git a/mesalib/src/glsl/loop_analysis.cpp b/mesalib/src/glsl/loop_analysis.cpp
index b08241af5..fd2b6c923 100644
--- a/mesalib/src/glsl/loop_analysis.cpp
+++ b/mesalib/src/glsl/loop_analysis.cpp
@@ -33,6 +33,46 @@ static bool all_expression_operands_are_loop_constant(ir_rvalue *,
static ir_rvalue *get_basic_induction_increment(ir_assignment *, hash_table *);
+/**
+ * Record the fact that the given loop variable was referenced inside the loop.
+ *
+ * \arg in_assignee is true if the reference was on the LHS of an assignment.
+ *
+ * \arg in_conditional_code_or_nested_loop is true if the reference occurred
+ * inside an if statement or a nested loop.
+ *
+ * \arg current_assignment is the ir_assignment node that the loop variable is
+ * on the LHS of, if any (ignored if \c in_assignee is false).
+ */
+void
+loop_variable::record_reference(bool in_assignee,
+ bool in_conditional_code_or_nested_loop,
+ ir_assignment *current_assignment)
+{
+ if (in_assignee) {
+ assert(current_assignment != NULL);
+
+ if (in_conditional_code_or_nested_loop ||
+ current_assignment->condition != NULL) {
+ this->conditional_or_nested_assignment = true;
+ }
+
+ if (this->first_assignment == NULL) {
+ assert(this->num_assignments == 0);
+
+ this->first_assignment = current_assignment;
+ }
+
+ this->num_assignments++;
+ } else if (this->first_assignment == current_assignment) {
+ /* This catches the case where the variable is used in the RHS of an
+ * assignment where it is also in the LHS.
+ */
+ this->read_before_write = true;
+ }
+}
+
+
loop_state::loop_state()
{
this->ht = hash_table_ctor(0, hash_table_pointer_hash,
@@ -94,7 +134,7 @@ loop_terminator *
loop_variable_state::insert(ir_if *if_stmt)
{
void *mem_ctx = ralloc_parent(this);
- loop_terminator *t = rzalloc(mem_ctx, loop_terminator);
+ loop_terminator *t = new(mem_ctx) loop_terminator();
t->ir = if_stmt;
this->terminators.push_tail(t);
@@ -102,6 +142,33 @@ loop_variable_state::insert(ir_if *if_stmt)
return t;
}
+
+/**
+ * If the given variable already is recorded in the state for this loop,
+ * return the corresponding loop_variable object that records information
+ * about it.
+ *
+ * Otherwise, create a new loop_variable object to record information about
+ * the variable, and set its \c read_before_write field appropriately based on
+ * \c in_assignee.
+ *
+ * \arg in_assignee is true if this variable was encountered on the LHS of an
+ * assignment.
+ */
+loop_variable *
+loop_variable_state::get_or_insert(ir_variable *var, bool in_assignee)
+{
+ loop_variable *lv = this->get(var);
+
+ if (lv == NULL) {
+ lv = this->insert(var);
+ lv->read_before_write = !in_assignee;
+ }
+
+ return lv;
+}
+
+
namespace {
class loop_analysis : public ir_hierarchical_visitor {
@@ -157,14 +224,14 @@ loop_analysis::visit(ir_loop_jump *ir)
ir_visitor_status
loop_analysis::visit_enter(ir_call *ir)
{
- /* If we're not somewhere inside a loop, there's nothing to do. */
- if (this->state.is_empty())
- return visit_continue;
-
- loop_variable_state *const ls =
- (loop_variable_state *) this->state.get_head();
+ /* Mark every loop that we're currently analyzing as containing an ir_call
+ * (even those at outer nesting levels).
+ */
+ foreach_list(node, &this->state) {
+ loop_variable_state *const ls = (loop_variable_state *) node;
+ ls->contains_calls = true;
+ }
- ls->contains_calls = true;
return visit_continue_with_parent;
}
@@ -177,35 +244,18 @@ loop_analysis::visit(ir_dereference_variable *ir)
if (this->state.is_empty())
return visit_continue;
- loop_variable_state *const ls =
- (loop_variable_state *) this->state.get_head();
-
- ir_variable *var = ir->variable_referenced();
- loop_variable *lv = ls->get(var);
-
- if (lv == NULL) {
- lv = ls->insert(var);
- lv->read_before_write = !this->in_assignee;
- }
-
- if (this->in_assignee) {
- assert(this->current_assignment != NULL);
+ bool nested = false;
- lv->conditional_assignment = (this->if_statement_depth > 0)
- || (this->current_assignment->condition != NULL);
+ foreach_list(node, &this->state) {
+ loop_variable_state *const ls = (loop_variable_state *) node;
- if (lv->first_assignment == NULL) {
- assert(lv->num_assignments == 0);
-
- lv->first_assignment = this->current_assignment;
- }
+ ir_variable *var = ir->variable_referenced();
+ loop_variable *lv = ls->get_or_insert(var, this->in_assignee);
- lv->num_assignments++;
- } else if (lv->first_assignment == this->current_assignment) {
- /* This catches the case where the variable is used in the RHS of an
- * assignment where it is also in the LHS.
- */
- lv->read_before_write = true;
+ lv->record_reference(this->in_assignee,
+ nested || this->if_statement_depth > 0,
+ this->current_assignment);
+ nested = true;
}
return visit_continue;
@@ -286,7 +336,7 @@ loop_analysis::visit_leave(ir_loop *ir)
foreach_list_safe(node, &ls->variables) {
loop_variable *lv = (loop_variable *) node;
- if (lv->conditional_assignment || (lv->num_assignments > 1))
+ if (lv->conditional_or_nested_assignment || (lv->num_assignments > 1))
continue;
/* Process the RHS of the assignment. If all of the variables
@@ -326,9 +376,10 @@ loop_analysis::visit_leave(ir_loop *ir)
assert(lv->num_assignments == 1);
assert(lv->first_assignment != NULL);
- /* The assignmnet to the variable in the loop must be unconditional.
+ /* The assignment to the variable in the loop must be unconditional and
+ * not inside a nested loop.
*/
- if (lv->conditional_assignment)
+ if (lv->conditional_or_nested_assignment)
continue;
/* Basic loop induction variables have a single assignment in the loop
@@ -338,8 +389,6 @@ loop_analysis::visit_leave(ir_loop *ir)
ir_rvalue *const inc =
get_basic_induction_increment(lv->first_assignment, ls->var_hash);
if (inc != NULL) {
- lv->iv_scale = NULL;
- lv->biv = lv->var;
lv->increment = inc;
lv->remove();
@@ -347,6 +396,75 @@ loop_analysis::visit_leave(ir_loop *ir)
}
}
+ /* Search the loop terminating conditions for those of the form 'i < c'
+ * where i is a loop induction variable, c is a constant, and < is any
+ * relative operator. From each of these we can infer an iteration count.
+ * Also figure out which terminator (if any) produces the smallest
+ * iteration count--this is the limiting terminator.
+ */
+ foreach_list(node, &ls->terminators) {
+ loop_terminator *t = (loop_terminator *) node;
+ ir_if *if_stmt = t->ir;
+
+ /* If-statements can be either 'if (expr)' or 'if (deref)'. We only care
+ * about the former here.
+ */
+ ir_expression *cond = if_stmt->condition->as_expression();
+ if (cond == NULL)
+ continue;
+
+ switch (cond->operation) {
+ case ir_binop_less:
+ case ir_binop_greater:
+ case ir_binop_lequal:
+ case ir_binop_gequal: {
+ /* The expressions that we care about will either be of the form
+ * 'counter < limit' or 'limit < counter'. Figure out which is
+ * which.
+ */
+ ir_rvalue *counter = cond->operands[0]->as_dereference_variable();
+ ir_constant *limit = cond->operands[1]->as_constant();
+ enum ir_expression_operation cmp = cond->operation;
+
+ if (limit == NULL) {
+ counter = cond->operands[1]->as_dereference_variable();
+ limit = cond->operands[0]->as_constant();
+
+ switch (cmp) {
+ case ir_binop_less: cmp = ir_binop_greater; break;
+ case ir_binop_greater: cmp = ir_binop_less; break;
+ case ir_binop_lequal: cmp = ir_binop_gequal; break;
+ case ir_binop_gequal: cmp = ir_binop_lequal; break;
+ default: assert(!"Should not get here.");
+ }
+ }
+
+ if ((counter == NULL) || (limit == NULL))
+ break;
+
+ ir_variable *var = counter->variable_referenced();
+
+ ir_rvalue *init = find_initial_value(ir, var);
+
+ loop_variable *lv = ls->get(var);
+ if (lv != NULL && lv->is_induction_var()) {
+ t->iterations = calculate_iterations(init, limit, lv->increment,
+ cmp);
+
+ if (t->iterations >= 0 &&
+ (ls->limiting_terminator == NULL ||
+ t->iterations < ls->limiting_terminator->iterations)) {
+ ls->limiting_terminator = t;
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
return visit_continue;
}
diff --git a/mesalib/src/glsl/loop_analysis.h b/mesalib/src/glsl/loop_analysis.h
index 769d62661..f841042f0 100644
--- a/mesalib/src/glsl/loop_analysis.h
+++ b/mesalib/src/glsl/loop_analysis.h
@@ -39,16 +39,12 @@ analyze_loop_variables(exec_list *instructions);
/**
* Fill in loop control fields
*
- * Based on analysis of loop variables, this function tries to remove sequences
- * in the loop of the form
+ * Based on analysis of loop variables, this function tries to remove
+ * redundant sequences in the loop of the form
*
* (if (expression bool ...) (break))
*
- * and fill in the \c ir_loop::from, \c ir_loop::to, and \c ir_loop::counter
- * fields of the \c ir_loop.
- *
- * In this process, some conditional break-statements may be eliminated
- * altogether. For example, if it is provable that one loop exit condition will
+ * For example, if it is provable that one loop exit condition will
* always be satisfied before another, the unnecessary exit condition will be
* removed.
*/
@@ -59,6 +55,13 @@ set_loop_controls(exec_list *instructions, loop_state *ls);
extern bool
unroll_loops(exec_list *instructions, loop_state *ls, unsigned max_iterations);
+ir_rvalue *
+find_initial_value(ir_loop *loop, ir_variable *var);
+
+int
+calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
+ enum ir_expression_operation op);
+
/**
* Tracking for all variables used in a loop
@@ -67,15 +70,11 @@ class loop_variable_state : public exec_node {
public:
class loop_variable *get(const ir_variable *);
class loop_variable *insert(ir_variable *);
+ class loop_variable *get_or_insert(ir_variable *, bool in_assignee);
class loop_terminator *insert(ir_if *);
/**
- * Loop whose variable state is being tracked by this structure
- */
- ir_loop *loop;
-
- /**
* Variables that have not yet been classified
*/
exec_list variables;
@@ -104,18 +103,17 @@ public:
exec_list terminators;
/**
- * Hash table containing all variables accessed in this loop
+ * If any of the terminators in \c terminators leads to termination of the
+ * loop after a constant number of iterations, this is the terminator that
+ * leads to termination after the smallest number of iterations. Otherwise
+ * NULL.
*/
- hash_table *var_hash;
+ loop_terminator *limiting_terminator;
/**
- * Maximum number of loop iterations.
- *
- * If this value is negative, then the loop may be infinite. This actually
- * means that analysis was unable to determine an upper bound on the number
- * of loop iterations.
+ * Hash table containing all variables accessed in this loop
*/
- int max_iterations;
+ hash_table *var_hash;
/**
* Number of ir_loop_jump instructions that operate on this loop
@@ -129,11 +127,11 @@ public:
loop_variable_state()
{
- this->max_iterations = -1;
this->num_loop_jumps = 0;
this->contains_calls = false;
this->var_hash = hash_table_ctor(0, hash_table_pointer_hash,
hash_table_pointer_compare);
+ this->limiting_terminator = NULL;
}
~loop_variable_state()
@@ -171,8 +169,11 @@ public:
/** Are all variables in the RHS of the assignment loop constants? */
bool rhs_clean;
- /** Is there an assignment to the variable that is conditional? */
- bool conditional_assignment;
+ /**
+ * Is there an assignment to the variable that is conditional, or inside a
+ * nested loop?
+ */
+ bool conditional_or_nested_assignment;
/** Reference to the first assignment to the variable in the loop body. */
ir_assignment *first_assignment;
@@ -181,27 +182,30 @@ public:
unsigned num_assignments;
/**
- * Increment values for loop induction variables
+ * Increment value for a loop induction variable
*
- * Loop induction variables have a single increment of the form
- * \c b * \c biv + \c c, where \c b and \c c are loop constants and \c i
- * is a basic loop induction variable.
+ * If this is a loop induction variable, the amount by which the variable
+ * is incremented on each iteration through the loop.
*
- * If \c iv_scale is \c NULL, 1 is used. If \c biv is the same as \c var,
- * then \c var is a basic loop induction variable.
+ * If this is not a loop induction variable, NULL.
*/
- /*@{*/
- ir_rvalue *iv_scale;
- ir_variable *biv;
ir_rvalue *increment;
- /*@}*/
+
+
+ inline bool is_induction_var() const
+ {
+ /* Induction variables always have a non-null increment, and vice
+ * versa.
+ */
+ return this->increment != NULL;
+ }
inline bool is_loop_constant() const
{
const bool is_const = (this->num_assignments == 0)
|| ((this->num_assignments == 1)
- && !this->conditional_assignment
+ && !this->conditional_or_nested_assignment
&& !this->read_before_write
&& this->rhs_clean);
@@ -213,16 +217,35 @@ public:
/* Variables that are marked read-only *MUST* be loop constant.
*/
- assert(!this->var->read_only || (this->var->read_only && is_const));
+ assert(!this->var->data.read_only
+ || (this->var->data.read_only && is_const));
return is_const;
}
+
+ void record_reference(bool in_assignee,
+ bool in_conditional_code_or_nested_loop,
+ ir_assignment *current_assignment);
};
class loop_terminator : public exec_node {
public:
+ loop_terminator()
+ : ir(NULL), iterations(-1)
+ {
+ }
+
+ /**
+ * Statement which terminates the loop.
+ */
ir_if *ir;
+
+ /**
+ * The number of iterations after which the terminator is known to
+ * terminate the loop (if that is a fixed value). Otherwise -1.
+ */
+ int iterations;
};
diff --git a/mesalib/src/glsl/loop_controls.cpp b/mesalib/src/glsl/loop_controls.cpp
index 26481930d..3db06ad18 100644
--- a/mesalib/src/glsl/loop_controls.cpp
+++ b/mesalib/src/glsl/loop_controls.cpp
@@ -183,114 +183,41 @@ loop_control_visitor::visit_leave(ir_loop *ir)
return visit_continue;
}
- /* Search the loop terminating conditions for one of the form 'i < c' where
- * i is a loop induction variable, c is a constant, and < is any relative
- * operator.
- */
- int max_iterations = ls->max_iterations;
-
- if(ir->from && ir->to && ir->increment)
- max_iterations = calculate_iterations(ir->from, ir->to, ir->increment, (ir_expression_operation)ir->cmp);
-
- if(max_iterations < 0)
- max_iterations = INT_MAX;
+ if (ls->limiting_terminator != NULL) {
+ /* If the limiting terminator has an iteration count of zero, then we've
+ * proven that the loop cannot run, so delete it.
+ */
+ int iterations = ls->limiting_terminator->iterations;
+ if (iterations == 0) {
+ ir->remove();
+ this->progress = true;
+ return visit_continue;
+ }
+ }
+ /* Remove the conditional break statements associated with all terminators
+ * that are associated with a fixed iteration count, except for the one
+ * associated with the limiting terminator--that one needs to stay, since
+ * it terminates the loop. Exception: if the loop still has a normative
+ * bound, then that terminates the loop, so we don't even need the limiting
+ * terminator.
+ */
foreach_list(node, &ls->terminators) {
loop_terminator *t = (loop_terminator *) node;
- ir_if *if_stmt = t->ir;
- /* If-statements can be either 'if (expr)' or 'if (deref)'. We only care
- * about the former here.
- */
- ir_expression *cond = if_stmt->condition->as_expression();
- if (cond == NULL)
- continue;
-
- switch (cond->operation) {
- case ir_binop_less:
- case ir_binop_greater:
- case ir_binop_lequal:
- case ir_binop_gequal: {
- /* The expressions that we care about will either be of the form
- * 'counter < limit' or 'limit < counter'. Figure out which is
- * which.
- */
- ir_rvalue *counter = cond->operands[0]->as_dereference_variable();
- ir_constant *limit = cond->operands[1]->as_constant();
- enum ir_expression_operation cmp = cond->operation;
-
- if (limit == NULL) {
- counter = cond->operands[1]->as_dereference_variable();
- limit = cond->operands[0]->as_constant();
-
- switch (cmp) {
- case ir_binop_less: cmp = ir_binop_greater; break;
- case ir_binop_greater: cmp = ir_binop_less; break;
- case ir_binop_lequal: cmp = ir_binop_gequal; break;
- case ir_binop_gequal: cmp = ir_binop_lequal; break;
- default: assert(!"Should not get here.");
- }
- }
-
- if ((counter == NULL) || (limit == NULL))
- break;
-
- ir_variable *var = counter->variable_referenced();
-
- ir_rvalue *init = find_initial_value(ir, var);
-
- foreach_list(iv_node, &ls->induction_variables) {
- loop_variable *lv = (loop_variable *) iv_node;
-
- if (lv->var == var) {
- const int iterations = calculate_iterations(init, limit,
- lv->increment,
- cmp);
- if (iterations >= 0) {
- /* If the new iteration count is lower than the previously
- * believed iteration count, update the loop control values.
- */
- if (iterations < max_iterations) {
- ir->from = init->clone(ir, NULL);
- ir->to = limit->clone(ir, NULL);
- ir->increment = lv->increment->clone(ir, NULL);
- ir->counter = lv->var;
- ir->cmp = cmp;
-
- max_iterations = iterations;
- }
-
- /* Remove the conditional break statement. The loop
- * controls are now set such that the exit condition will be
- * satisfied.
- */
- if_stmt->remove();
-
- assert(ls->num_loop_jumps > 0);
- ls->num_loop_jumps--;
-
- this->progress = true;
- }
-
- break;
- }
- }
- break;
- }
+ if (t->iterations < 0)
+ continue;
- default:
- break;
+ if (t != ls->limiting_terminator) {
+ t->ir->remove();
+
+ assert(ls->num_loop_jumps > 0);
+ ls->num_loop_jumps--;
+
+ this->progress = true;
}
}
- /* If we have proven the one of the loop exit conditions is satisifed before
- * running the loop once, remove the loop.
- */
- if (max_iterations == 0)
- ir->remove();
- else
- ls->max_iterations = max_iterations;
-
return visit_continue;
}
diff --git a/mesalib/src/glsl/loop_unroll.cpp b/mesalib/src/glsl/loop_unroll.cpp
index ff97766f1..6eced1736 100644
--- a/mesalib/src/glsl/loop_unroll.cpp
+++ b/mesalib/src/glsl/loop_unroll.cpp
@@ -37,6 +37,10 @@ public:
}
virtual ir_visitor_status visit_leave(ir_loop *ir);
+ void simple_unroll(ir_loop *ir, int iterations);
+ void complex_unroll(ir_loop *ir, int iterations,
+ bool continue_from_then_branch);
+ void splice_post_if_instructions(ir_if *ir_if, exec_list *splice_dest);
loop_state *state;
@@ -86,6 +90,138 @@ public:
};
+/**
+ * Unroll a loop which does not contain any jumps. For example, if the input
+ * is:
+ *
+ * (loop (...) ...instrs...)
+ *
+ * And the iteration count is 3, the output will be:
+ *
+ * ...instrs... ...instrs... ...instrs...
+ */
+void
+loop_unroll_visitor::simple_unroll(ir_loop *ir, int iterations)
+{
+ void *const mem_ctx = ralloc_parent(ir);
+
+ for (int i = 0; i < iterations; i++) {
+ exec_list copy_list;
+
+ copy_list.make_empty();
+ clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
+
+ ir->insert_before(&copy_list);
+ }
+
+ /* The loop has been replaced by the unrolled copies. Remove the original
+ * loop from the IR sequence.
+ */
+ ir->remove();
+
+ this->progress = true;
+}
+
+
+/**
+ * Unroll a loop whose last statement is an ir_if. If \c
+ * continue_from_then_branch is true, the loop is repeated only when the
+ * "then" branch of the if is taken; otherwise it is repeated only when the
+ * "else" branch of the if is taken.
+ *
+ * For example, if the input is:
+ *
+ * (loop (...)
+ * ...body...
+ * (if (cond)
+ * (...then_instrs...)
+ * (...else_instrs...)))
+ *
+ * And the iteration count is 3, and \c continue_from_then_branch is true,
+ * then the output will be:
+ *
+ * ...body...
+ * (if (cond)
+ * (...then_instrs...
+ * ...body...
+ * (if (cond)
+ * (...then_instrs...
+ * ...body...
+ * (if (cond)
+ * (...then_instrs...)
+ * (...else_instrs...)))
+ * (...else_instrs...)))
+ * (...else_instrs))
+ */
+void
+loop_unroll_visitor::complex_unroll(ir_loop *ir, int iterations,
+ bool continue_from_then_branch)
+{
+ void *const mem_ctx = ralloc_parent(ir);
+ ir_instruction *ir_to_replace = ir;
+
+ for (int i = 0; i < iterations; i++) {
+ exec_list copy_list;
+
+ copy_list.make_empty();
+ clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
+
+ ir_if *ir_if = ((ir_instruction *) copy_list.get_tail())->as_if();
+ assert(ir_if != NULL);
+
+ ir_to_replace->insert_before(&copy_list);
+ ir_to_replace->remove();
+
+ /* placeholder that will be removed in the next iteration */
+ ir_to_replace =
+ new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);
+
+ exec_list *const list = (continue_from_then_branch)
+ ? &ir_if->then_instructions : &ir_if->else_instructions;
+
+ list->push_tail(ir_to_replace);
+ }
+
+ ir_to_replace->remove();
+
+ this->progress = true;
+}
+
+
+/**
+ * Move all of the instructions which follow \c ir_if to the end of
+ * \c splice_dest.
+ *
+ * For example, in the code snippet:
+ *
+ * (if (cond)
+ * (...then_instructions...
+ * break)
+ * (...else_instructions...))
+ * ...post_if_instructions...
+ *
+ * If \c ir_if points to the "if" instruction, and \c splice_dest points to
+ * (...else_instructions...), the code snippet is transformed into:
+ *
+ * (if (cond)
+ * (...then_instructions...
+ * break)
+ * (...else_instructions...
+ * ...post_if_instructions...))
+ */
+void
+loop_unroll_visitor::splice_post_if_instructions(ir_if *ir_if,
+ exec_list *splice_dest)
+{
+ while (!ir_if->get_next()->is_tail_sentinel()) {
+ ir_instruction *move_ir = (ir_instruction *) ir_if->get_next();
+
+ move_ir->remove();
+ splice_dest->push_tail(move_ir);
+ }
+}
+
+
ir_visitor_status
loop_unroll_visitor::visit_leave(ir_loop *ir)
{
@@ -100,14 +236,14 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
return visit_continue;
}
- iterations = ls->max_iterations;
-
/* Don't try to unroll loops where the number of iterations is not known
* at compile-time.
*/
- if (iterations < 0)
+ if (ls->limiting_terminator == NULL)
return visit_continue;
+ iterations = ls->limiting_terminator->iterations;
+
/* Don't try to unroll loops that have zillions of iterations either.
*/
if (iterations > (int) max_iterations)
@@ -120,127 +256,83 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
if (count.fail || count.nodes * iterations > (int)max_iterations * 5)
return visit_continue;
- if (ls->num_loop_jumps > 1)
- return visit_continue;
- else if (ls->num_loop_jumps) {
- ir_instruction *last_ir = (ir_instruction *) ir->body_instructions.get_tail();
- assert(last_ir != NULL);
-
- if (is_break(last_ir)) {
- /* If the only loop-jump is a break at the end of the loop, the loop
- * will execute exactly once. Remove the break, set the iteration
- * count, and fall through to the normal unroller.
- */
- last_ir->remove();
- iterations = 1;
-
- this->progress = true;
- } else {
- ir_if *ir_if = NULL;
- ir_instruction *break_ir = NULL;
- bool continue_from_then_branch = false;
-
- foreach_list(node, &ir->body_instructions) {
- /* recognize loops in the form produced by ir_lower_jumps */
- ir_instruction *cur_ir = (ir_instruction *) node;
-
- ir_if = cur_ir->as_if();
- if (ir_if != NULL) {
- /* Determine which if-statement branch, if any, ends with a
- * break. The branch that did *not* have the break will get a
- * temporary continue inserted in each iteration of the loop
- * unroll.
- *
- * Note that since ls->num_loop_jumps is <= 1, it is impossible
- * for both branches to end with a break.
- */
- ir_instruction *ir_if_last =
- (ir_instruction *) ir_if->then_instructions.get_tail();
-
- if (is_break(ir_if_last)) {
- continue_from_then_branch = false;
- break_ir = ir_if_last;
- break;
- } else {
- ir_if_last =
- (ir_instruction *) ir_if->else_instructions.get_tail();
-
- if (is_break(ir_if_last)) {
- break_ir = ir_if_last;
- continue_from_then_branch = true;
- break;
- }
- }
- }
- }
-
- if (break_ir == NULL)
- return visit_continue;
-
- /* move instructions after then if in the continue branch */
- while (!ir_if->get_next()->is_tail_sentinel()) {
- ir_instruction *move_ir = (ir_instruction *) ir_if->get_next();
-
- move_ir->remove();
- if (continue_from_then_branch)
- ir_if->then_instructions.push_tail(move_ir);
- else
- ir_if->else_instructions.push_tail(move_ir);
- }
-
- /* Remove the break from the if-statement.
- */
- break_ir->remove();
-
- void *const mem_ctx = ralloc_parent(ir);
- ir_instruction *ir_to_replace = ir;
-
- for (int i = 0; i < iterations; i++) {
- exec_list copy_list;
+ /* Note: the limiting terminator contributes 1 to ls->num_loop_jumps.
+ * We'll be removing the limiting terminator before we unroll.
+ */
+ assert(ls->num_loop_jumps > 0);
+ unsigned predicted_num_loop_jumps = ls->num_loop_jumps - 1;
- copy_list.make_empty();
- clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
+ if (predicted_num_loop_jumps > 1)
+ return visit_continue;
- ir_if = ((ir_instruction *) copy_list.get_tail())->as_if();
- assert(ir_if != NULL);
+ if (predicted_num_loop_jumps == 0) {
+ ls->limiting_terminator->ir->remove();
+ simple_unroll(ir, iterations);
+ return visit_continue;
+ }
- ir_to_replace->insert_before(&copy_list);
- ir_to_replace->remove();
+ ir_instruction *last_ir = (ir_instruction *) ir->body_instructions.get_tail();
+ assert(last_ir != NULL);
- /* placeholder that will be removed in the next iteration */
- ir_to_replace =
- new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);
+ if (is_break(last_ir)) {
+ /* If the only loop-jump is a break at the end of the loop, the loop
+ * will execute exactly once. Remove the break and use the simple
+ * unroller with an iteration count of 1.
+ */
+ last_ir->remove();
- exec_list *const list = (continue_from_then_branch)
- ? &ir_if->then_instructions : &ir_if->else_instructions;
+ ls->limiting_terminator->ir->remove();
+ simple_unroll(ir, 1);
+ return visit_continue;
+ }
- list->push_tail(ir_to_replace);
+ foreach_list(node, &ir->body_instructions) {
+ /* recognize loops in the form produced by ir_lower_jumps */
+ ir_instruction *cur_ir = (ir_instruction *) node;
+
+ /* Skip the limiting terminator, since it will go away when we
+ * unroll.
+ */
+ if (cur_ir == ls->limiting_terminator->ir)
+ continue;
+
+ ir_if *ir_if = cur_ir->as_if();
+ if (ir_if != NULL) {
+ /* Determine which if-statement branch, if any, ends with a
+ * break. The branch that did *not* have the break will get a
+ * temporary continue inserted in each iteration of the loop
+ * unroll.
+ *
+ * Note that since ls->num_loop_jumps is <= 1, it is impossible
+ * for both branches to end with a break.
+ */
+ ir_instruction *ir_if_last =
+ (ir_instruction *) ir_if->then_instructions.get_tail();
+
+ if (is_break(ir_if_last)) {
+ ls->limiting_terminator->ir->remove();
+ splice_post_if_instructions(ir_if, &ir_if->else_instructions);
+ ir_if_last->remove();
+ complex_unroll(ir, iterations, false);
+ return visit_continue;
+ } else {
+ ir_if_last =
+ (ir_instruction *) ir_if->else_instructions.get_tail();
+
+ if (is_break(ir_if_last)) {
+ ls->limiting_terminator->ir->remove();
+ splice_post_if_instructions(ir_if, &ir_if->then_instructions);
+ ir_if_last->remove();
+ complex_unroll(ir, iterations, true);
+ return visit_continue;
+ }
}
-
- ir_to_replace->remove();
-
- this->progress = true;
- return visit_continue;
}
}
- void *const mem_ctx = ralloc_parent(ir);
-
- for (int i = 0; i < iterations; i++) {
- exec_list copy_list;
-
- copy_list.make_empty();
- clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);
-
- ir->insert_before(&copy_list);
- }
-
- /* The loop has been replaced by the unrolled copies. Remove the original
- * loop from the IR sequence.
+ /* Did not find the break statement. It must be in a complex if-nesting,
+ * so don't try to unroll.
*/
- ir->remove();
-
- this->progress = true;
return visit_continue;
}
diff --git a/mesalib/src/glsl/lower_clip_distance.cpp b/mesalib/src/glsl/lower_clip_distance.cpp
index 04fa6d410..bb4f6ab11 100644
--- a/mesalib/src/glsl/lower_clip_distance.cpp
+++ b/mesalib/src/glsl/lower_clip_distance.cpp
@@ -135,13 +135,13 @@ lower_clip_distance_visitor::visit(ir_variable *ir)
"gl_ClipDistanceMESA");
this->new_clip_distance_1d_var->type
= glsl_type::get_array_instance(glsl_type::vec4_type, new_size);
- this->new_clip_distance_1d_var->max_array_access
- = ir->max_array_access / 4;
+ this->new_clip_distance_1d_var->data.max_array_access
+ = ir->data.max_array_access / 4;
ir->replace_with(this->new_clip_distance_1d_var);
} else {
/* 2D gl_ClipDistance (used for geometry input). */
- assert(ir->mode == ir_var_shader_in &&
+ assert(ir->data.mode == ir_var_shader_in &&
this->shader_type == GL_GEOMETRY_SHADER_ARB);
if (this->old_clip_distance_2d_var)
return visit_continue;
@@ -161,8 +161,8 @@ lower_clip_distance_visitor::visit(ir_variable *ir)
glsl_type::get_array_instance(glsl_type::vec4_type,
new_size),
ir->type->array_size());
- this->new_clip_distance_2d_var->max_array_access
- = ir->max_array_access / 4;
+ this->new_clip_distance_2d_var->data.max_array_access
+ = ir->data.max_array_access / 4;
ir->replace_with(this->new_clip_distance_2d_var);
}
@@ -500,8 +500,8 @@ lower_clip_distance_visitor::visit_leave(ir_call *ir)
this->base_ir->insert_before(temp_clip_distance);
actual_param->replace_with(
new(ctx) ir_dereference_variable(temp_clip_distance));
- if (formal_param->mode == ir_var_function_in
- || formal_param->mode == ir_var_function_inout) {
+ if (formal_param->data.mode == ir_var_function_in
+ || formal_param->data.mode == ir_var_function_inout) {
/* Copy from gl_ClipDistance to the temporary before the call.
* Since we are going to insert this copy before the current
* instruction, we need to visit it afterwards to make sure it
@@ -513,8 +513,8 @@ lower_clip_distance_visitor::visit_leave(ir_call *ir)
this->base_ir->insert_before(new_assignment);
this->visit_new_assignment(new_assignment);
}
- if (formal_param->mode == ir_var_function_out
- || formal_param->mode == ir_var_function_inout) {
+ if (formal_param->data.mode == ir_var_function_out
+ || formal_param->data.mode == ir_var_function_inout) {
/* Copy from the temporary to gl_ClipDistance after the call.
* Since visit_list_elements() has already decided which
* instruction it's going to visit next, we need to visit
diff --git a/mesalib/src/glsl/lower_instructions.cpp b/mesalib/src/glsl/lower_instructions.cpp
index d01879cbd..8f8d448ea 100644
--- a/mesalib/src/glsl/lower_instructions.cpp
+++ b/mesalib/src/glsl/lower_instructions.cpp
@@ -383,7 +383,6 @@ lower_instructions_visitor::ldexp_to_arith(ir_expression *ir)
/* Constants */
ir_constant *zeroi = ir_constant::zero(ir, ivec);
- ir_constant *zerof = ir_constant::zero(ir, ir->type);
ir_constant *sign_mantissa_mask = new(ir) ir_constant(0x807fffffu, vec_elem);
ir_constant *sign_mask = new(ir) ir_constant(0x80000000u, vec_elem);
@@ -429,8 +428,7 @@ lower_instructions_visitor::ldexp_to_arith(ir_expression *ir)
*/
i.insert_before(zero_sign_x);
i.insert_before(assign(zero_sign_x,
- bitcast_u2f(bit_or(bit_and(bitcast_f2u(x), sign_mask),
- bitcast_f2u(zerof)))));
+ bitcast_u2f(bit_and(bitcast_f2u(x), sign_mask))));
i.insert_before(is_not_zero_or_underflow);
i.insert_before(assign(is_not_zero_or_underflow,
diff --git a/mesalib/src/glsl/lower_named_interface_blocks.cpp b/mesalib/src/glsl/lower_named_interface_blocks.cpp
index d59d11150..09d867ea3 100644
--- a/mesalib/src/glsl/lower_named_interface_blocks.cpp
+++ b/mesalib/src/glsl/lower_named_interface_blocks.cpp
@@ -108,7 +108,7 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
* but, this will require changes to the other uniform block
* support code.
*/
- if (var->mode == ir_var_uniform)
+ if (var->data.mode == ir_var_uniform)
continue;
const glsl_type * iface_t = var->type;
@@ -139,8 +139,8 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
new_var =
new(mem_ctx) ir_variable(iface_t->fields.structure[i].type,
var_name,
- (ir_variable_mode) var->mode);
- new_var->from_named_ifc_block_nonarray = 1;
+ (ir_variable_mode) var->data.mode);
+ new_var->data.from_named_ifc_block_nonarray = 1;
} else {
const glsl_type *new_array_type =
glsl_type::get_array_instance(
@@ -149,14 +149,15 @@ flatten_named_interface_blocks_declarations::run(exec_list *instructions)
new_var =
new(mem_ctx) ir_variable(new_array_type,
var_name,
- (ir_variable_mode) var->mode);
- new_var->from_named_ifc_block_array = 1;
+ (ir_variable_mode) var->data.mode);
+ new_var->data.from_named_ifc_block_array = 1;
}
- new_var->location = iface_t->fields.structure[i].location;
- new_var->explicit_location = (new_var->location >= 0);
- new_var->interpolation =
+ new_var->data.location = iface_t->fields.structure[i].location;
+ new_var->data.explicit_location = (new_var->data.location >= 0);
+ new_var->data.interpolation =
iface_t->fields.structure[i].interpolation;
- new_var->centroid = iface_t->fields.structure[i].centroid;
+ new_var->data.centroid = iface_t->fields.structure[i].centroid;
+ new_var->data.sample = iface_t->fields.structure[i].sample;
new_var->init_interface_type(iface_t);
hash_table_insert(interface_namespace, new_var,
@@ -211,7 +212,7 @@ flatten_named_interface_blocks_declarations::handle_rvalue(ir_rvalue **rvalue)
* but, this will require changes to the other uniform block
* support code.
*/
- if (var->mode == ir_var_uniform)
+ if (var->data.mode == ir_var_uniform)
return;
if (var->get_interface_type() != NULL) {
diff --git a/mesalib/src/glsl/lower_output_reads.cpp b/mesalib/src/glsl/lower_output_reads.cpp
index 128b0b8cd..afe17766b 100644
--- a/mesalib/src/glsl/lower_output_reads.cpp
+++ b/mesalib/src/glsl/lower_output_reads.cpp
@@ -91,7 +91,7 @@ output_read_remover::~output_read_remover()
ir_visitor_status
output_read_remover::visit(ir_dereference_variable *ir)
{
- if (ir->var->mode != ir_var_shader_out)
+ if (ir->var->data.mode != ir_var_shader_out)
return visit_continue;
ir_variable *temp = (ir_variable *) hash_table_find(replacements, ir->var);
diff --git a/mesalib/src/glsl/lower_packed_varyings.cpp b/mesalib/src/glsl/lower_packed_varyings.cpp
index 61ee692f6..9edef5d04 100644
--- a/mesalib/src/glsl/lower_packed_varyings.cpp
+++ b/mesalib/src/glsl/lower_packed_varyings.cpp
@@ -258,8 +258,8 @@ lower_packed_varyings_visitor::run(exec_list *instructions)
if (var == NULL)
continue;
- if (var->mode != this->mode ||
- var->location < (int) this->location_base ||
+ if (var->data.mode != this->mode ||
+ var->data.location < (int) this->location_base ||
!this->needs_lowering(var))
continue;
@@ -268,18 +268,18 @@ lower_packed_varyings_visitor::run(exec_list *instructions)
* safe, caller should ensure that integral varyings always use flat
* interpolation, even when this is not required by GLSL.
*/
- assert(var->interpolation == INTERP_QUALIFIER_FLAT ||
+ assert(var->data.interpolation == INTERP_QUALIFIER_FLAT ||
!var->type->contains_integer());
/* Change the old varying into an ordinary global. */
- var->mode = ir_var_auto;
+ var->data.mode = ir_var_auto;
/* Create a reference to the old varying. */
ir_dereference_variable *deref
= new(this->mem_ctx) ir_dereference_variable(var);
/* Recursively pack or unpack it. */
- this->lower_rvalue(deref, var->location * 4 + var->location_frac, var,
+ this->lower_rvalue(deref, var->data.location * 4 + var->data.location_frac, var,
var->name, this->gs_input_vertices != 0, 0);
}
}
@@ -547,7 +547,7 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
if (this->packed_varyings[slot] == NULL) {
char *packed_name = ralloc_asprintf(this->mem_ctx, "packed:%s", name);
const glsl_type *packed_type;
- if (unpacked_var->interpolation == INTERP_QUALIFIER_FLAT)
+ if (unpacked_var->data.interpolation == INTERP_QUALIFIER_FLAT)
packed_type = glsl_type::ivec4_type;
else
packed_type = glsl_type::vec4_type;
@@ -562,11 +562,12 @@ lower_packed_varyings_visitor::get_packed_varying_deref(
/* Prevent update_array_sizes() from messing with the size of the
* array.
*/
- packed_var->max_array_access = this->gs_input_vertices - 1;
+ packed_var->data.max_array_access = this->gs_input_vertices - 1;
}
- packed_var->centroid = unpacked_var->centroid;
- packed_var->interpolation = unpacked_var->interpolation;
- packed_var->location = location;
+ packed_var->data.centroid = unpacked_var->data.centroid;
+ packed_var->data.sample = unpacked_var->data.sample;
+ packed_var->data.interpolation = unpacked_var->data.interpolation;
+ packed_var->data.location = location;
unpacked_var->insert_before(packed_var);
this->packed_varyings[slot] = packed_var;
} else {
diff --git a/mesalib/src/glsl/lower_ubo_reference.cpp b/mesalib/src/glsl/lower_ubo_reference.cpp
index 16b6801b8..c73b148b0 100644
--- a/mesalib/src/glsl/lower_ubo_reference.cpp
+++ b/mesalib/src/glsl/lower_ubo_reference.cpp
@@ -143,7 +143,7 @@ lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue)
struct gl_uniform_block *block = &shader->UniformBlocks[i];
this->ubo_var = var->is_interface_instance()
- ? &block->Uniforms[0] : &block->Uniforms[var->location];
+ ? &block->Uniforms[0] : &block->Uniforms[var->data.location];
break;
}
diff --git a/mesalib/src/glsl/lower_variable_index_to_cond_assign.cpp b/mesalib/src/glsl/lower_variable_index_to_cond_assign.cpp
index 699fb3903..7c5d80f43 100644
--- a/mesalib/src/glsl/lower_variable_index_to_cond_assign.cpp
+++ b/mesalib/src/glsl/lower_variable_index_to_cond_assign.cpp
@@ -365,7 +365,7 @@ public:
if (var == NULL)
return this->lower_temps;
- switch (var->mode) {
+ switch (var->data.mode) {
case ir_var_auto:
case ir_var_temporary:
return this->lower_temps;
diff --git a/mesalib/src/glsl/opt_array_splitting.cpp b/mesalib/src/glsl/opt_array_splitting.cpp
index c7c5f6712..e946e0ae5 100644
--- a/mesalib/src/glsl/opt_array_splitting.cpp
+++ b/mesalib/src/glsl/opt_array_splitting.cpp
@@ -122,8 +122,8 @@ ir_array_reference_visitor::get_variable_entry(ir_variable *var)
{
assert(var);
- if (var->mode != ir_var_auto &&
- var->mode != ir_var_temporary)
+ if (var->data.mode != ir_var_auto &&
+ var->data.mode != ir_var_temporary)
return NULL;
if (!(var->type->is_array() || var->type->is_matrix()))
diff --git a/mesalib/src/glsl/opt_constant_folding.cpp b/mesalib/src/glsl/opt_constant_folding.cpp
index 072fefe9a..08a47b96b 100644
--- a/mesalib/src/glsl/opt_constant_folding.cpp
+++ b/mesalib/src/glsl/opt_constant_folding.cpp
@@ -127,8 +127,8 @@ ir_constant_folding_visitor::visit_enter(ir_call *ir)
ir_rvalue *param_rval = (ir_rvalue *)iter.get();
ir_variable *sig_param = (ir_variable *)sig_iter.get();
- if (sig_param->mode == ir_var_function_in
- || sig_param->mode == ir_var_const_in) {
+ if (sig_param->data.mode == ir_var_function_in
+ || sig_param->data.mode == ir_var_const_in) {
ir_rvalue *new_param = param_rval;
handle_rvalue(&new_param);
diff --git a/mesalib/src/glsl/opt_constant_propagation.cpp b/mesalib/src/glsl/opt_constant_propagation.cpp
index 2f65937fe..f1a6fbdaa 100644
--- a/mesalib/src/glsl/opt_constant_propagation.cpp
+++ b/mesalib/src/glsl/opt_constant_propagation.cpp
@@ -285,8 +285,8 @@ ir_constant_propagation_visitor::visit_enter(ir_call *ir)
foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
ir_rvalue *param = (ir_rvalue *)iter.get();
- if (sig_param->mode != ir_var_function_out
- && sig_param->mode != ir_var_function_inout) {
+ if (sig_param->data.mode != ir_var_function_out
+ && sig_param->data.mode != ir_var_function_inout) {
ir_rvalue *new_param = param;
handle_rvalue(&new_param);
if (new_param != param)
diff --git a/mesalib/src/glsl/opt_constant_variable.cpp b/mesalib/src/glsl/opt_constant_variable.cpp
index cbe6450c6..a026c51c3 100644
--- a/mesalib/src/glsl/opt_constant_variable.cpp
+++ b/mesalib/src/glsl/opt_constant_variable.cpp
@@ -137,8 +137,8 @@ ir_constant_variable_visitor::visit_enter(ir_call *ir)
ir_rvalue *param_rval = (ir_rvalue *)iter.get();
ir_variable *param = (ir_variable *)sig_iter.get();
- if (param->mode == ir_var_function_out ||
- param->mode == ir_var_function_inout) {
+ if (param->data.mode == ir_var_function_out ||
+ param->data.mode == ir_var_function_inout) {
ir_variable *var = param_rval->variable_referenced();
struct assignment_entry *entry;
diff --git a/mesalib/src/glsl/opt_copy_propagation.cpp b/mesalib/src/glsl/opt_copy_propagation.cpp
index 7282b611e..db5dfc153 100644
--- a/mesalib/src/glsl/opt_copy_propagation.cpp
+++ b/mesalib/src/glsl/opt_copy_propagation.cpp
@@ -189,8 +189,8 @@ ir_copy_propagation_visitor::visit_enter(ir_call *ir)
foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
ir_instruction *ir = (ir_instruction *)iter.get();
- if (sig_param->mode != ir_var_function_out
- && sig_param->mode != ir_var_function_inout) {
+ if (sig_param->data.mode != ir_var_function_out
+ && sig_param->data.mode != ir_var_function_inout) {
ir->accept(this);
}
sig_param_iter.next();
diff --git a/mesalib/src/glsl/opt_copy_propagation_elements.cpp b/mesalib/src/glsl/opt_copy_propagation_elements.cpp
index 6a19da40d..ba8a0f532 100644
--- a/mesalib/src/glsl/opt_copy_propagation_elements.cpp
+++ b/mesalib/src/glsl/opt_copy_propagation_elements.cpp
@@ -297,8 +297,8 @@ ir_copy_propagation_elements_visitor::visit_enter(ir_call *ir)
foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
ir_instruction *ir = (ir_instruction *)iter.get();
- if (sig_param->mode != ir_var_function_out
- && sig_param->mode != ir_var_function_inout) {
+ if (sig_param->data.mode != ir_var_function_out
+ && sig_param->data.mode != ir_var_function_inout) {
ir->accept(this);
}
sig_param_iter.next();
diff --git a/mesalib/src/glsl/opt_cse.cpp b/mesalib/src/glsl/opt_cse.cpp
index 8f73940d8..a2b63ee99 100644
--- a/mesalib/src/glsl/opt_cse.cpp
+++ b/mesalib/src/glsl/opt_cse.cpp
@@ -193,7 +193,7 @@ is_cse_candidate_visitor::visit(ir_dereference_variable *ir)
/* Currently, since we don't handle kills of the ae based on variables
* getting assigned, we can only handle constant variables.
*/
- if (ir->var->read_only) {
+ if (ir->var->data.read_only) {
return visit_continue;
} else {
ok = false;
diff --git a/mesalib/src/glsl/opt_dead_builtin_varyings.cpp b/mesalib/src/glsl/opt_dead_builtin_varyings.cpp
index b336bc0a8..a939a2b64 100644
--- a/mesalib/src/glsl/opt_dead_builtin_varyings.cpp
+++ b/mesalib/src/glsl/opt_dead_builtin_varyings.cpp
@@ -85,10 +85,10 @@ public:
{
ir_variable *var = ir->variable_referenced();
- if (!var || var->mode != this->mode)
+ if (!var || var->data.mode != this->mode)
return visit_continue;
- if (this->find_frag_outputs && var->location == FRAG_RESULT_DATA0) {
+ if (this->find_frag_outputs && var->data.location == FRAG_RESULT_DATA0) {
this->fragdata_array = var;
ir_constant *index = ir->array_index->as_constant();
@@ -105,7 +105,7 @@ public:
return visit_continue_with_parent;
}
- if (!this->find_frag_outputs && var->location == VARYING_SLOT_TEX0) {
+ if (!this->find_frag_outputs && var->data.location == VARYING_SLOT_TEX0) {
this->texcoord_array = var;
ir_constant *index = ir->array_index->as_constant();
@@ -130,17 +130,17 @@ public:
{
ir_variable *var = ir->variable_referenced();
- if (var->mode != this->mode || !var->type->is_array())
+ if (var->data.mode != this->mode || !var->type->is_array())
return visit_continue;
- if (this->find_frag_outputs && var->location == FRAG_RESULT_DATA0) {
+ if (this->find_frag_outputs && var->data.location == FRAG_RESULT_DATA0) {
/* This is a whole array dereference. */
this->fragdata_usage |= (1 << var->type->array_size()) - 1;
this->lower_fragdata_array = false;
return visit_continue;
}
- if (!this->find_frag_outputs && var->location == VARYING_SLOT_TEX0) {
+ if (!this->find_frag_outputs && var->data.location == VARYING_SLOT_TEX0) {
/* This is a whole array dereference like "gl_TexCoord = x;",
* there's probably no point in lowering that.
*/
@@ -152,7 +152,7 @@ public:
virtual ir_visitor_status visit(ir_variable *var)
{
- if (var->mode != this->mode)
+ if (var->data.mode != this->mode)
return visit_continue;
/* Nothing to do here for fragment outputs. */
@@ -160,7 +160,7 @@ public:
return visit_continue;
/* Handle colors and fog. */
- switch (var->location) {
+ switch (var->data.location) {
case VARYING_SLOT_COL0:
this->color[0] = var;
this->color_usage |= 1;
@@ -358,9 +358,9 @@ public:
new_var[i] =
new(ctx) ir_variable(glsl_type::vec4_type, name,
this->info->mode);
- new_var[i]->location = start_location + i;
- new_var[i]->explicit_location = true;
- new_var[i]->explicit_index = 0;
+ new_var[i]->data.location = start_location + i;
+ new_var[i]->data.explicit_location = true;
+ new_var[i]->data.explicit_index = 0;
}
ir->head->insert_before(new_var[i]);
diff --git a/mesalib/src/glsl/opt_dead_code.cpp b/mesalib/src/glsl/opt_dead_code.cpp
index b65e5c2ce..a8d8b4a39 100644
--- a/mesalib/src/glsl/opt_dead_code.cpp
+++ b/mesalib/src/glsl/opt_dead_code.cpp
@@ -79,9 +79,9 @@ do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
/* Remove a single dead assignment to the variable we found.
* Don't do so if it's a shader or function output, though.
*/
- if (entry->var->mode != ir_var_function_out &&
- entry->var->mode != ir_var_function_inout &&
- entry->var->mode != ir_var_shader_out) {
+ if (entry->var->data.mode != ir_var_function_out &&
+ entry->var->data.mode != ir_var_function_inout &&
+ entry->var->data.mode != ir_var_shader_out) {
entry->assign->remove();
progress = true;
@@ -99,7 +99,7 @@ do_dead_code(exec_list *instructions, bool uniform_locations_assigned)
* stage. Also, once uniform locations have been assigned, the
* declaration cannot be deleted.
*/
- if (entry->var->mode == ir_var_uniform &&
+ if (entry->var->data.mode == ir_var_uniform &&
(uniform_locations_assigned ||
entry->var->constant_value))
continue;
diff --git a/mesalib/src/glsl/opt_dead_code_local.cpp b/mesalib/src/glsl/opt_dead_code_local.cpp
index 42a30b3d8..43a01662a 100644
--- a/mesalib/src/glsl/opt_dead_code_local.cpp
+++ b/mesalib/src/glsl/opt_dead_code_local.cpp
@@ -121,7 +121,7 @@ public:
*/
foreach_iter(exec_list_iterator, iter, *this->assignments) {
assignment_entry *entry = (assignment_entry *)iter.get();
- if (entry->lhs->mode == ir_var_shader_out) {
+ if (entry->lhs->data.mode == ir_var_shader_out) {
if (debug)
printf("kill %s\n", entry->lhs->name);
entry->remove();
diff --git a/mesalib/src/glsl/opt_flip_matrices.cpp b/mesalib/src/glsl/opt_flip_matrices.cpp
index 2107b1d47..9044fd680 100644
--- a/mesalib/src/glsl/opt_flip_matrices.cpp
+++ b/mesalib/src/glsl/opt_flip_matrices.cpp
@@ -104,8 +104,8 @@ matrix_flipper::visit_enter(ir_expression *ir)
var_ref->var = texmat_transpose;
- texmat_transpose->max_array_access =
- MAX2(texmat_transpose->max_array_access, mat_var->max_array_access);
+ texmat_transpose->data.max_array_access =
+ MAX2(texmat_transpose->data.max_array_access, mat_var->data.max_array_access);
progress = true;
}
diff --git a/mesalib/src/glsl/opt_function_inlining.cpp b/mesalib/src/glsl/opt_function_inlining.cpp
index f8033a095..c8f42a424 100644
--- a/mesalib/src/glsl/opt_function_inlining.cpp
+++ b/mesalib/src/glsl/opt_function_inlining.cpp
@@ -132,21 +132,21 @@ ir_call::generate_inline(ir_instruction *next_ir)
parameters[i] = NULL;
} else {
parameters[i] = sig_param->clone(ctx, ht);
- parameters[i]->mode = ir_var_auto;
+ parameters[i]->data.mode = ir_var_auto;
/* Remove the read-only decoration becuase we're going to write
* directly to this variable. If the cloned variable is left
* read-only and the inlined function is inside a loop, the loop
* analysis code will get confused.
*/
- parameters[i]->read_only = false;
+ parameters[i]->data.read_only = false;
next_ir->insert_before(parameters[i]);
}
/* Move the actual param into our param variable if it's an 'in' type. */
- if (parameters[i] && (sig_param->mode == ir_var_function_in ||
- sig_param->mode == ir_var_const_in ||
- sig_param->mode == ir_var_function_inout)) {
+ if (parameters[i] && (sig_param->data.mode == ir_var_function_in ||
+ sig_param->data.mode == ir_var_const_in ||
+ sig_param->data.mode == ir_var_function_inout)) {
ir_assignment *assign;
assign = new(ctx) ir_assignment(new(ctx) ir_dereference_variable(parameters[i]),
@@ -202,8 +202,8 @@ ir_call::generate_inline(ir_instruction *next_ir)
const ir_variable *const sig_param = (ir_variable *) sig_param_iter.get();
/* Move our param variable into the actual param if it's an 'out' type. */
- if (parameters[i] && (sig_param->mode == ir_var_function_out ||
- sig_param->mode == ir_var_function_inout)) {
+ if (parameters[i] && (sig_param->data.mode == ir_var_function_out ||
+ sig_param->data.mode == ir_var_function_inout)) {
ir_assignment *assign;
assign = new(ctx) ir_assignment(param->clone(ctx, NULL)->as_rvalue(),
diff --git a/mesalib/src/glsl/opt_structure_splitting.cpp b/mesalib/src/glsl/opt_structure_splitting.cpp
index 9f4b3dd8f..414f0000d 100644
--- a/mesalib/src/glsl/opt_structure_splitting.cpp
+++ b/mesalib/src/glsl/opt_structure_splitting.cpp
@@ -103,8 +103,8 @@ ir_structure_reference_visitor::get_variable_entry(ir_variable *var)
{
assert(var);
- if (!var->type->is_record() || var->mode == ir_var_uniform
- || var->mode == ir_var_shader_in || var->mode == ir_var_shader_out)
+ if (!var->type->is_record() || var->data.mode == ir_var_uniform
+ || var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out)
return NULL;
foreach_iter(exec_list_iterator, iter, this->variable_list) {
diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp
index 46c06e6c4..6d75a1573 100644
--- a/mesalib/src/glsl/opt_tree_grafting.cpp
+++ b/mesalib/src/glsl/opt_tree_grafting.cpp
@@ -211,8 +211,8 @@ ir_tree_grafting_visitor::visit_enter(ir_call *ir)
ir_rvalue *ir = (ir_rvalue *)iter.get();
ir_rvalue *new_ir = ir;
- if (sig_param->mode != ir_var_function_in
- && sig_param->mode != ir_var_const_in) {
+ if (sig_param->data.mode != ir_var_function_in
+ && sig_param->data.mode != ir_var_const_in) {
if (check_graft(ir, sig_param) == visit_stop)
return visit_stop;
continue;
@@ -361,9 +361,9 @@ tree_grafting_basic_block(ir_instruction *bb_first,
if (!lhs_var)
continue;
- if (lhs_var->mode == ir_var_function_out ||
- lhs_var->mode == ir_var_function_inout ||
- lhs_var->mode == ir_var_shader_out)
+ if (lhs_var->data.mode == ir_var_function_out ||
+ lhs_var->data.mode == ir_var_function_inout ||
+ lhs_var->data.mode == ir_var_shader_out)
continue;
ir_variable_refcount_entry *entry = info->refs->get_variable_entry(lhs_var);
diff --git a/mesalib/src/glsl/standalone_scaffolding.h b/mesalib/src/glsl/standalone_scaffolding.h
index 7afb1c313..9f4818a8a 100644
--- a/mesalib/src/glsl/standalone_scaffolding.h
+++ b/mesalib/src/glsl/standalone_scaffolding.h
@@ -60,7 +60,7 @@ _mesa_shader_type_to_index(GLenum v)
return MESA_SHADER_GEOMETRY;
default:
assert(!"bad value in _mesa_shader_type_to_index()");
- return MESA_SHADER_TYPES;
+ return MESA_SHADER_VERTEX;
}
}
diff --git a/mesalib/src/mapi/glapi/gen/ARB_clear_buffer_object.xml b/mesalib/src/mapi/glapi/gen/ARB_clear_buffer_object.xml
new file mode 100644
index 000000000..cb97a0185
--- /dev/null
+++ b/mesalib/src/mapi/glapi/gen/ARB_clear_buffer_object.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+
+<OpenGLAPI>
+
+<category name="GL_ARB_clear_buffer_object" number="121">
+
+ <function name ="ClearBufferData" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="internalformat" type="GLenum"/>
+ <param name="format" type="GLenum"/>
+ <param name="type" type="GLenum"/>
+ <param name="data" type="const GLvoid *"/>
+ </function>
+
+ <function name ="ClearBufferSubData" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="internalformat" type="GLenum"/>
+ <param name="offset" type="GLintptr"/>
+ <param name="size" type="GLsizeiptr"/>
+ <param name="format" type="GLenum"/>
+ <param name="type" type="GLenum"/>
+ <param name="data" type="const GLvoid *"/>
+ </function>
+
+<!-- <function name="ClearNamedBufferDataEXT" offset="assign">
+ <param name="buffer" type="GLuint"/>
+ <param name="internalformat" type="GLenum"/>
+ <param name="format" type="GLenum"/>
+ <param name="type" type="GLenum"/>
+ <param name="data" type="const GLvoid *"/>
+ </function>
+
+
+ <function name="ClearNamedBufferSubDataEXT" offset="assign">
+ <param name="buffer" type="GLuint"/>
+ <param name="internalformat" type="GLenum"/>
+ <param name="offset" type="GLintptr"/>
+ <param name="size" type="GLsizeiptr"/>
+ <param name="format" type="GLenum"/>
+ <param name="type" type="GLenum"/>
+ <param name="data" type="const GLvoid *"/>
+ </function> -->
+
+</category>
+
+</OpenGLAPI>
diff --git a/mesalib/src/mapi/glapi/gen/ARB_texture_view.xml b/mesalib/src/mapi/glapi/gen/ARB_texture_view.xml
new file mode 100644
index 000000000..3e6b8c904
--- /dev/null
+++ b/mesalib/src/mapi/glapi/gen/ARB_texture_view.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+<OpenGLAPI>
+
+<category name="GL_ARB_texture_view" number="124">
+
+ <function name="TextureView" offset="assign">
+ <param name="texture" type="GLuint"/>
+ <param name="target" type="GLenum"/>
+ <param name="origtexture" type="GLuint"/>
+ <param name="internalformat" type="GLenum"/>
+ <param name="minlevel" type="GLuint"/>
+ <param name="numlevels" type="GLuint"/>
+ <param name="minlayer" type="GLuint"/>
+ <param name="numlayers" type="GLuint"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/mesalib/src/mapi/glapi/gen/Makefile.am b/mesalib/src/mapi/glapi/gen/Makefile.am
index 7af769acf..65bd9137c 100644
--- a/mesalib/src/mapi/glapi/gen/Makefile.am
+++ b/mesalib/src/mapi/glapi/gen/Makefile.am
@@ -125,6 +125,7 @@ API_XML = \
ARB_texture_rg.xml \
ARB_texture_storage_multisample.xml \
ARB_texture_storage.xml \
+ ARB_texture_view.xml \
ARB_vertex_array_object.xml \
ARB_vertex_attrib_binding.xml \
AMD_draw_buffers_blend.xml \
diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml
index 5c877aa3f..697b2ecce 100644
--- a/mesalib/src/mapi/glapi/gen/gl_API.xml
+++ b/mesalib/src/mapi/glapi/gen/gl_API.xml
@@ -8460,7 +8460,13 @@
</category>
-<!-- ARB extensions #120...#124 -->
+<!-- ARB extension #120 -->
+
+<xi:include href="ARB_clear_buffer_object.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+<!-- ARB extensions #122...#123 -->
+
+<xi:include href="ARB_texture_view.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="ARB_vertex_attrib_binding.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
diff --git a/mesalib/src/mapi/glapi/gen/gl_genexec.py b/mesalib/src/mapi/glapi/gen/gl_genexec.py
index 3ce190fe3..b557b3b99 100644
--- a/mesalib/src/mapi/glapi/gen/gl_genexec.py
+++ b/mesalib/src/mapi/glapi/gen/gl_genexec.py
@@ -102,6 +102,7 @@ header = """/**
#include "main/texstate.h"
#include "main/texstorage.h"
#include "main/texturebarrier.h"
+#include "main/textureview.h"
#include "main/transformfeedback.h"
#include "main/mtypes.h"
#include "main/varray.h"
diff --git a/mesalib/src/mapi/glapi/gen/gl_gentable.py b/mesalib/src/mapi/glapi/gen/gl_gentable.py
index fa9626825..35dddc7a0 100644
--- a/mesalib/src/mapi/glapi/gen/gl_gentable.py
+++ b/mesalib/src/mapi/glapi/gen/gl_gentable.py
@@ -50,7 +50,9 @@ header = """/* GLXEXT is the define used in the xserver when the GLX extension i
#include <execinfo.h>
#endif
+#ifndef _WIN32
#include <dlfcn.h>
+#endif
#include <stdlib.h>
#include <stdio.h>
diff --git a/mesalib/src/mesa/Makefile.am b/mesalib/src/mesa/Makefile.am
index a60600e03..884383652 100644
--- a/mesalib/src/mesa/Makefile.am
+++ b/mesalib/src/mesa/Makefile.am
@@ -103,7 +103,11 @@ noinst_PROGRAMS = gen_matypes
gen_matypes_SOURCES = x86/gen_matypes.c
BUILT_SOURCES += matypes.h
-ARCH_LIBS = libmesa_sse41.la
+ARCH_LIBS =
+
+if SSE41_SUPPORTED
+ARCH_LIBS += libmesa_sse41.la
+endif
if HAVE_X86_64_ASM
MESA_ASM_FILES_FOR_ARCH += $(X86_64_FILES)
diff --git a/mesalib/src/mesa/Makefile.sources b/mesalib/src/mesa/Makefile.sources
index a84f8a788..39525bc5b 100644
--- a/mesalib/src/mesa/Makefile.sources
+++ b/mesalib/src/mesa/Makefile.sources
@@ -103,6 +103,7 @@ MAIN_FILES = \
$(SRCDIR)main/texstate.c \
$(SRCDIR)main/texstorage.c \
$(SRCDIR)main/texstore.c \
+ $(SRCDIR)main/textureview.c \
$(SRCDIR)main/texturebarrier.c \
$(SRCDIR)main/transformfeedback.c \
$(SRCDIR)main/uniforms.c \
diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript
index a2bb9f131..bb9b304ef 100644
--- a/mesalib/src/mesa/SConscript
+++ b/mesalib/src/mesa/SConscript
@@ -133,6 +133,7 @@ main_sources = [
'main/texstorage.c',
'main/texstore.c',
'main/texturebarrier.c',
+ 'main/textureview.c',
'main/transformfeedback.c',
'main/uniform_query.cpp',
'main/uniforms.c',
diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c
index 5faa98af1..f18568827 100644
--- a/mesalib/src/mesa/drivers/common/driverfuncs.c
+++ b/mesalib/src/mesa/drivers/common/driverfuncs.c
@@ -211,6 +211,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
/* GL_ARB_texture_storage */
driver->AllocTextureStorage = _mesa_alloc_texture_storage;
+ /* GL_ARB_texture_view */
+ driver->TextureView = NULL;
+
/* GL_ARB_texture_multisample */
driver->GetSamplePosition = NULL;
}
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c
index 0bce77ea9..d64821112 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.c
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c
@@ -438,16 +438,19 @@ driCreateContextAttribs(__DRIscreen *screen, int api,
return NULL;
}
- struct gl_context *ctx = context->driverPrivate;
+ *error = __DRI_CTX_ERROR_SUCCESS;
+ return context;
+}
+
+void
+driContextSetFlags(struct gl_context *ctx, uint32_t flags)
+{
if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0)
ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT;
if ((flags & __DRI_CTX_FLAG_DEBUG) != 0) {
ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT;
ctx->Debug.DebugOutput = GL_TRUE;
}
-
- *error = __DRI_CTX_ERROR_SUCCESS;
- return context;
}
static __DRIcontext *
@@ -873,3 +876,18 @@ const __DRIimageDriverExtension driImageDriverExtension = {
.getAPIMask = driGetAPIMask,
.createContextAttribs = driCreateContextAttribs,
};
+
+/* swrast copy sub buffer entrypoint. */
+static void driCopySubBuffer(__DRIdrawable *pdp, int x, int y,
+ int w, int h)
+{
+ assert(pdp->driScreenPriv->swrast_loader);
+
+ pdp->driScreenPriv->driver->CopySubBuffer(pdp, x, y, w, h);
+}
+
+/* for swrast only */
+const __DRIcopySubBufferExtension driCopySubBufferExtension = {
+ { __DRI_COPY_SUB_BUFFER, 1 },
+ .copySubBuffer = driCopySubBuffer,
+};
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.h b/mesalib/src/mesa/drivers/dri/common/dri_util.h
index 79a8564ad..a79a4ed7a 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.h
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.h
@@ -66,7 +66,7 @@ extern const __DRIcoreExtension driCoreExtension;
extern const __DRIswrastExtension driSWRastExtension;
extern const __DRIdri2Extension driDRI2Extension;
extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
-
+extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
/**
* Driver callback functions.
*
@@ -115,6 +115,9 @@ struct __DriverAPIRec {
int width, int height);
void (*ReleaseBuffer) (__DRIscreen *screenPrivate, __DRIbuffer *buffer);
+
+ void (*CopySubBuffer)(__DRIdrawable *driDrawPriv, int x, int y,
+ int w, int h);
};
extern const struct __DriverAPIRec driDriverAPI;
@@ -289,6 +292,9 @@ dri2InvalidateDrawable(__DRIdrawable *drawable);
extern void
driUpdateFramebufferSize(struct gl_context *ctx, const __DRIdrawable *dPriv);
+extern void
+driContextSetFlags(struct gl_context *ctx, uint32_t flags);
+
extern const __DRIimageDriverExtension driImageDriverExtension;
#endif /* _DRI_UTIL_H_ */
diff --git a/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c b/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c
index 6bf5d7327..a8217703d 100644
--- a/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c
+++ b/mesalib/src/mesa/drivers/dri/common/megadriver_stub.c
@@ -23,6 +23,132 @@
#include <stdio.h>
#include "dri_util.h"
+#include <dlfcn.h>
+#include "main/macros.h"
+
+/* We need GNU extensions to dlfcn.h in order to provide backward
+ * compatibility for the older DRI driver loader mechanism. (dladdr,
+ * Dl_info, and RTLD_DEFAULT are only defined when _GNU_SOURCE is
+ * defined.)
+ */
+#ifdef _GNU_SOURCE
+
+#define MEGADRIVER_STUB_MAX_EXTENSIONS 10
+#define LIB_PATH_SUFFIX "_dri.so"
+#define LIB_PATH_SUFFIX_LENGTH (sizeof(LIB_PATH_SUFFIX)-1)
+
+/* This is the table of extensions that the loader will dlsym() for.
+ *
+ * Initially it is empty for the megadriver stub, but the library
+ * constructor may initialize it based on the name of the library that
+ * is being loaded.
+ */
+PUBLIC const __DRIextension *
+__driDriverExtensions[MEGADRIVER_STUB_MAX_EXTENSIONS] = {
+ NULL
+};
+
+/**
+ * This is a constructor function for the megadriver dynamic library.
+ *
+ * When the driver is dlopen'ed, this function will run. It will
+ * search for the name of the foo_dri.so file that was opened using
+ * the dladdr function.
+ *
+ * After finding foo's name, it will call __driDriverGetExtensions_foo
+ * and use the return to update __driDriverExtensions to enable
+ * compatibility with older DRI driver loaders.
+ */
+__attribute__((constructor)) static void
+megadriver_stub_init(void)
+{
+ Dl_info info;
+ char *driver_name;
+ size_t name_len;
+ char *get_extensions_name;
+ const __DRIextension **(*get_extensions)(void);
+ const __DRIextension **extensions;
+ int i;
+
+ /* Call dladdr on __driDriverExtensions. We are really
+ * interested in the returned info.dli_fname so we can
+ * figure out the path name of the library being loaded.
+ */
+ i = dladdr((void*) __driDriverExtensions, &info);
+ if (i == 0)
+ return;
+
+ /* Search for the last '/' character in the path. */
+ driver_name = strrchr(info.dli_fname, '/');
+ if (driver_name != NULL) {
+ /* Skip '/' character */
+ driver_name++;
+ } else {
+ /* Try using the start of the path */
+ driver_name = (char*) info.dli_fname;
+ }
+
+ /* Make sure the path ends with _dri.so */
+ name_len = strlen(driver_name);
+ i = name_len - LIB_PATH_SUFFIX_LENGTH;
+ if (i < 0 || strcmp(driver_name + i, LIB_PATH_SUFFIX) != 0)
+ return;
+
+ /* Duplicate the string so we can modify it.
+ * So far we've been using info.dli_fname.
+ */
+ driver_name = strdup(driver_name);
+ if (!driver_name)
+ return;
+
+ /* The path ends with _dri.so. Chop this part of the
+ * string off. Then we'll have the driver's final name.
+ */
+ driver_name[i] = '\0';
+
+ i = asprintf(&get_extensions_name, "%s_%s",
+ __DRI_DRIVER_GET_EXTENSIONS, driver_name);
+ free(driver_name);
+ if (i == -1)
+ return;
+
+ /* dlsym to get the driver's get extensions function. We
+ * don't have the dlopen handle, so we have to use
+ * RTLD_DEFAULT. It seems unlikely that the symbol will
+ * be found in another library, but this isn't optimal.
+ */
+ get_extensions = dlsym(RTLD_DEFAULT, get_extensions_name);
+ free(get_extensions_name);
+ if (!get_extensions)
+ return;
+
+ /* Use the newer DRI loader entrypoint to find extensions.
+ * We will then expose these extensions via the older
+ * __driDriverExtensions symbol.
+ */
+ extensions = get_extensions();
+
+ /* Copy the extensions into the __driDriverExtensions array
+ * we declared.
+ */
+ for (i = 0; i < ARRAY_SIZE(__driDriverExtensions); i++) {
+ __driDriverExtensions[i] = extensions[i];
+ if (extensions[i] == NULL)
+ break;
+ }
+
+ /* If the driver had more extensions than we reserved, then
+ * bail out.
+ */
+ if (i == ARRAY_SIZE(__driDriverExtensions)) {
+ __driDriverExtensions[0] = NULL;
+ fprintf(stderr, "Megadriver stub did not reserve enough extension "
+ "slots.\n");
+ return;
+ }
+}
+
+#endif /* _GNU_SOURCE */
static const
__DRIconfig **stub_error_init_screen(__DRIscreen *psp)
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
index 73dc5c4c0..79a27408f 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
@@ -402,7 +402,7 @@ swrast_map_renderbuffer(struct gl_context *ctx,
stride = w * cpp;
xrb->Base.Buffer = malloc(h * stride);
- sPriv->swrast_loader->getImage(dPriv, x, y, w, h,
+ sPriv->swrast_loader->getImage(dPriv, x, rb->Height - y - h, w, h,
(char *) xrb->Base.Buffer,
dPriv->loaderPrivate);
@@ -705,6 +705,8 @@ dri_create_context(gl_api api,
goto context_fail;
}
+ driContextSetFlags(mesaCtx, flags);
+
/* do bounds checking to prevent segfaults and server crashes! */
mesaCtx->Const.CheckArrayBounds = GL_TRUE;
@@ -820,6 +822,39 @@ dri_unbind_context(__DRIcontext * cPriv)
return GL_TRUE;
}
+static void
+dri_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
+ int w, int h)
+{
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ void *data;
+ int iy;
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct gl_framebuffer *fb;
+ struct dri_swrast_renderbuffer *frontrb, *backrb;
+
+ TRACE;
+
+ fb = &drawable->Base;
+
+ frontrb =
+ dri_swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
+ backrb =
+ dri_swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
+
+ /* check for signle-buffered */
+ if (backrb == NULL)
+ return;
+
+ iy = frontrb->Base.Base.Height - y - h;
+ data = (char *)backrb->Base.Buffer + (iy * backrb->pitch) + (x * ((backrb->bpp + 7) / 8));
+ sPriv->swrast_loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
+ x, iy, w, h,
+ frontrb->pitch,
+ data,
+ dPriv->loaderPrivate);
+}
+
static const struct __DriverAPIRec swrast_driver_api = {
.InitScreen = dri_init_screen,
@@ -831,6 +866,7 @@ static const struct __DriverAPIRec swrast_driver_api = {
.SwapBuffers = dri_swap_buffers,
.MakeCurrent = dri_make_current,
.UnbindContext = dri_unbind_context,
+ .CopySubBuffer = dri_copy_sub_buffer,
};
static const struct __DRIDriverVtableExtensionRec swrast_vtable = {
@@ -841,6 +877,7 @@ static const struct __DRIDriverVtableExtensionRec swrast_vtable = {
static const __DRIextension *swrast_driver_extensions[] = {
&driCoreExtension.base,
&driSWRastExtension.base,
+ &driCopySubBufferExtension.base,
&swrast_vtable.base,
NULL
};
diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c
index c9332bd52..30c815d67 100644
--- a/mesalib/src/mesa/main/attrib.c
+++ b/mesalib/src/mesa/main/attrib.c
@@ -182,7 +182,7 @@ struct texture_state
* Allocate new attribute node of given type/kind. Attach payload data.
* Insert it into the linked list named by 'head'.
*/
-static void
+static bool
save_attrib_data(struct gl_attrib_node **head,
GLbitfield kind, void *payload)
{
@@ -196,7 +196,42 @@ save_attrib_data(struct gl_attrib_node **head,
}
else {
/* out of memory! */
+ return false;
+ }
+ return true;
+}
+
+
+/**
+ * Helper function for_mesa_PushAttrib for simple attributes.
+ * Allocates memory for attribute data and copies the given attribute data.
+ * \param head head of linked list to insert attribute data into
+ * \param attr_bit one of the GL_<attrib>_BIT flags
+ * \param attr_size number of bytes to allocate for attribute data
+ * \param attr_data the attribute data to copy
+ * \return true for success, false for out of memory
+ */
+static bool
+push_attrib(struct gl_context *ctx, struct gl_attrib_node **head,
+ GLbitfield attr_bit, GLuint attr_size, const void *attr_data)
+{
+ void *attribute;
+
+ attribute = MALLOC(attr_size);
+ if (attribute == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
+ return false;
+ }
+
+ if (save_attrib_data(head, attr_bit, attribute)) {
+ memcpy(attribute, attr_data, attr_size);
}
+ else {
+ FREE(attribute);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
+ return false;
+ }
+ return true;
}
@@ -220,42 +255,58 @@ _mesa_PushAttrib(GLbitfield mask)
head = NULL;
if (mask & GL_ACCUM_BUFFER_BIT) {
- struct gl_accum_attrib *attr;
- attr = MALLOC_STRUCT( gl_accum_attrib );
- memcpy( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
- save_attrib_data(&head, GL_ACCUM_BUFFER_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_ACCUM_BUFFER_BIT,
+ sizeof(struct gl_accum_attrib),
+ (void*)&ctx->Accum))
+ goto end;
}
if (mask & GL_COLOR_BUFFER_BIT) {
GLuint i;
struct gl_colorbuffer_attrib *attr;
attr = MALLOC_STRUCT( gl_colorbuffer_attrib );
- memcpy( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) );
- /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
- attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
- save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr);
+ if (attr == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
+ goto end;
+ }
+
+ if (save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr)) {
+ memcpy(attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib));
+ /* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
+ for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
+ attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
+ }
+ else {
+ FREE(attr);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
+ goto end;
+ }
}
if (mask & GL_CURRENT_BIT) {
- struct gl_current_attrib *attr;
- FLUSH_CURRENT( ctx, 0 );
- attr = MALLOC_STRUCT( gl_current_attrib );
- memcpy( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
- save_attrib_data(&head, GL_CURRENT_BIT, attr);
+ FLUSH_CURRENT(ctx, 0);
+ if (!push_attrib(ctx, &head, GL_CURRENT_BIT,
+ sizeof(struct gl_current_attrib),
+ (void*)&ctx->Current))
+ goto end;
}
if (mask & GL_DEPTH_BUFFER_BIT) {
- struct gl_depthbuffer_attrib *attr;
- attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
- memcpy( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
- save_attrib_data(&head, GL_DEPTH_BUFFER_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_DEPTH_BUFFER_BIT,
+ sizeof(struct gl_depthbuffer_attrib),
+ (void*)&ctx->Depth))
+ goto end;
}
if (mask & GL_ENABLE_BIT) {
struct gl_enable_attrib *attr;
GLuint i;
attr = MALLOC_STRUCT( gl_enable_attrib );
+ if (attr == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
+ goto end;
+ }
+
/* Copy enable flags from all other attributes into the enable struct. */
attr->AlphaTest = ctx->Color.AlphaEnabled;
attr->AutoNormal = ctx->Eval.AutoNormal;
@@ -322,97 +373,112 @@ _mesa_PushAttrib(GLbitfield mask)
/* GL_ARB_fragment_program */
attr->FragmentProgram = ctx->FragmentProgram.Enabled;
- save_attrib_data(&head, GL_ENABLE_BIT, attr);
+ if (!save_attrib_data(&head, GL_ENABLE_BIT, attr)) {
+ FREE(attr);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
+ goto end;
+ }
/* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */
attr->sRGBEnabled = ctx->Color.sRGBEnabled;
}
if (mask & GL_EVAL_BIT) {
- struct gl_eval_attrib *attr;
- attr = MALLOC_STRUCT( gl_eval_attrib );
- memcpy( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
- save_attrib_data(&head, GL_EVAL_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_EVAL_BIT,
+ sizeof(struct gl_eval_attrib),
+ (void*)&ctx->Eval))
+ goto end;
}
if (mask & GL_FOG_BIT) {
- struct gl_fog_attrib *attr;
- attr = MALLOC_STRUCT( gl_fog_attrib );
- memcpy( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
- save_attrib_data(&head, GL_FOG_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_FOG_BIT,
+ sizeof(struct gl_fog_attrib),
+ (void*)&ctx->Fog))
+ goto end;
}
if (mask & GL_HINT_BIT) {
- struct gl_hint_attrib *attr;
- attr = MALLOC_STRUCT( gl_hint_attrib );
- memcpy( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
- save_attrib_data(&head, GL_HINT_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_HINT_BIT,
+ sizeof(struct gl_hint_attrib),
+ (void*)&ctx->Hint))
+ goto end;
}
if (mask & GL_LIGHTING_BIT) {
- struct gl_light_attrib *attr;
- FLUSH_CURRENT(ctx, 0); /* flush material changes */
- attr = MALLOC_STRUCT( gl_light_attrib );
- memcpy( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
- save_attrib_data(&head, GL_LIGHTING_BIT, attr);
+ FLUSH_CURRENT(ctx, 0); /* flush material changes */
+ if (!push_attrib(ctx, &head, GL_LIGHTING_BIT,
+ sizeof(struct gl_light_attrib),
+ (void*)&ctx->Light))
+ goto end;
}
if (mask & GL_LINE_BIT) {
- struct gl_line_attrib *attr;
- attr = MALLOC_STRUCT( gl_line_attrib );
- memcpy( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
- save_attrib_data(&head, GL_LINE_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_LINE_BIT,
+ sizeof(struct gl_line_attrib),
+ (void*)&ctx->Line))
+ goto end;
}
if (mask & GL_LIST_BIT) {
- struct gl_list_attrib *attr;
- attr = MALLOC_STRUCT( gl_list_attrib );
- memcpy( attr, &ctx->List, sizeof(struct gl_list_attrib) );
- save_attrib_data(&head, GL_LIST_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_LIST_BIT,
+ sizeof(struct gl_list_attrib),
+ (void*)&ctx->List))
+ goto end;
}
if (mask & GL_PIXEL_MODE_BIT) {
struct gl_pixel_attrib *attr;
attr = MALLOC_STRUCT( gl_pixel_attrib );
- memcpy( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
- /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */
- attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
- save_attrib_data(&head, GL_PIXEL_MODE_BIT, attr);
+ if (attr == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
+ goto end;
+ }
+
+ if (save_attrib_data(&head, GL_PIXEL_MODE_BIT, attr)) {
+ memcpy(attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib));
+ /* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */
+ attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
+ }
+ else {
+ FREE(attr);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib");
+ goto end;
+ }
}
if (mask & GL_POINT_BIT) {
- struct gl_point_attrib *attr;
- attr = MALLOC_STRUCT( gl_point_attrib );
- memcpy( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
- save_attrib_data(&head, GL_POINT_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_POINT_BIT,
+ sizeof(struct gl_point_attrib),
+ (void*)&ctx->Point))
+ goto end;
}
if (mask & GL_POLYGON_BIT) {
- struct gl_polygon_attrib *attr;
- attr = MALLOC_STRUCT( gl_polygon_attrib );
- memcpy( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
- save_attrib_data(&head, GL_POLYGON_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_POLYGON_BIT,
+ sizeof(struct gl_polygon_attrib),
+ (void*)&ctx->Polygon))
+ goto end;
}
if (mask & GL_POLYGON_STIPPLE_BIT) {
- GLuint *stipple;
- stipple = malloc( 32*sizeof(GLuint) );
- memcpy( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
- save_attrib_data(&head, GL_POLYGON_STIPPLE_BIT, stipple);
+ if (!push_attrib(ctx, &head, GL_POLYGON_STIPPLE_BIT,
+ sizeof(ctx->PolygonStipple),
+ (void*)&ctx->PolygonStipple))
+ goto end;
}
if (mask & GL_SCISSOR_BIT) {
- struct gl_scissor_attrib *attr;
- attr = MALLOC_STRUCT( gl_scissor_attrib );
- memcpy( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
- save_attrib_data(&head, GL_SCISSOR_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_SCISSOR_BIT,
+ sizeof(struct gl_scissor_attrib),
+ (void*)&ctx->Scissor))
+ goto end;
}
if (mask & GL_STENCIL_BUFFER_BIT) {
- struct gl_stencil_attrib *attr;
- attr = MALLOC_STRUCT( gl_stencil_attrib );
- memcpy( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
- save_attrib_data(&head, GL_STENCIL_BUFFER_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_STENCIL_BUFFER_BIT,
+ sizeof(struct gl_stencil_attrib),
+ (void*)&ctx->Stencil))
+ goto end;
}
if (mask & GL_TEXTURE_BIT) {
@@ -424,6 +490,12 @@ _mesa_PushAttrib(GLbitfield mask)
goto end;
}
+ if (!save_attrib_data(&head, GL_TEXTURE_BIT, texstate)) {
+ FREE(texstate);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushAttrib(GL_TEXTURE_BIT)");
+ goto end;
+ }
+
_mesa_lock_context_textures(ctx);
/* copy/save the bulk of texture state here */
@@ -450,35 +522,35 @@ _mesa_PushAttrib(GLbitfield mask)
_mesa_reference_shared_state(ctx, &texstate->SharedRef, ctx->Shared);
_mesa_unlock_context_textures(ctx);
-
- save_attrib_data(&head, GL_TEXTURE_BIT, texstate);
}
if (mask & GL_TRANSFORM_BIT) {
- struct gl_transform_attrib *attr;
- attr = MALLOC_STRUCT( gl_transform_attrib );
- memcpy( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
- save_attrib_data(&head, GL_TRANSFORM_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_TRANSFORM_BIT,
+ sizeof(struct gl_transform_attrib),
+ (void*)&ctx->Transform))
+ goto end;
}
if (mask & GL_VIEWPORT_BIT) {
- struct gl_viewport_attrib *attr;
- attr = MALLOC_STRUCT( gl_viewport_attrib );
- memcpy( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
- save_attrib_data(&head, GL_VIEWPORT_BIT, attr);
+ if (!push_attrib(ctx, &head, GL_VIEWPORT_BIT,
+ sizeof(struct gl_viewport_attrib),
+ (void*)&ctx->Viewport))
+ goto end;
}
/* GL_ARB_multisample */
if (mask & GL_MULTISAMPLE_BIT_ARB) {
- struct gl_multisample_attrib *attr;
- attr = MALLOC_STRUCT( gl_multisample_attrib );
- memcpy( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) );
- save_attrib_data(&head, GL_MULTISAMPLE_BIT_ARB, attr);
+ if (!push_attrib(ctx, &head, GL_MULTISAMPLE_BIT_ARB,
+ sizeof(struct gl_multisample_attrib),
+ (void*)&ctx->Multisample))
+ goto end;
}
end:
- ctx->AttribStack[ctx->AttribStackDepth] = head;
- ctx->AttribStackDepth++;
+ if (head != NULL) {
+ ctx->AttribStack[ctx->AttribStackDepth] = head;
+ ctx->AttribStackDepth++;
+ }
}
@@ -641,12 +713,6 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable)
_mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP,
!!(enabled & TEXTURE_CUBE_BIT));
}
- if (ctx->Extensions.MESA_texture_array) {
- _mesa_set_enable(ctx, GL_TEXTURE_1D_ARRAY_EXT,
- !!(enabled & TEXTURE_1D_ARRAY_BIT));
- _mesa_set_enable(ctx, GL_TEXTURE_2D_ARRAY_EXT,
- !!(enabled & TEXTURE_2D_ARRAY_BIT));
- }
}
if (ctx->Texture.Unit[i].TexGenEnabled != genEnabled) {
@@ -688,12 +754,6 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate)
_mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV,
!!(unit->Enabled & TEXTURE_RECT_BIT));
}
- if (ctx->Extensions.MESA_texture_array) {
- _mesa_set_enable(ctx, GL_TEXTURE_1D_ARRAY_EXT,
- !!(unit->Enabled & TEXTURE_1D_ARRAY_BIT));
- _mesa_set_enable(ctx, GL_TEXTURE_2D_ARRAY_EXT,
- !!(unit->Enabled & TEXTURE_2D_ARRAY_BIT));
- }
_mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode);
_mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor);
_mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenS.Mode);
@@ -768,7 +828,7 @@ pop_texture_group(struct gl_context *ctx, struct texture_state *texstate)
}
else if ((obj->Target == GL_TEXTURE_1D_ARRAY_EXT ||
obj->Target == GL_TEXTURE_2D_ARRAY_EXT) &&
- !ctx->Extensions.MESA_texture_array) {
+ !ctx->Extensions.EXT_texture_array) {
continue;
}
else if (obj->Target == GL_TEXTURE_CUBE_MAP_ARRAY &&
@@ -1482,13 +1542,20 @@ restore_array_attrib(struct gl_context *ctx,
* init/alloc the fields of 'attrib'.
* Needs to the init part matching free_array_attrib_data below.
*/
-static void
+static bool
init_array_attrib_data(struct gl_context *ctx,
struct gl_array_attrib *attrib)
{
/* Get a non driver gl_array_object. */
attrib->ArrayObj = CALLOC_STRUCT( gl_array_object );
+
+ if (attrib->ArrayObj == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
+ return false;
+ }
+
_mesa_initialize_array_object(ctx, attrib->ArrayObj, 0);
+ return true;
}
/**
@@ -1529,24 +1596,65 @@ _mesa_PushClientAttrib(GLbitfield mask)
struct gl_pixelstore_attrib *attr;
/* packing attribs */
attr = CALLOC_STRUCT( gl_pixelstore_attrib );
- copy_pixelstore(ctx, attr, &ctx->Pack);
- save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr);
+ if (attr == NULL) {
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" );
+ goto end;
+ }
+ if (save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr)) {
+ copy_pixelstore(ctx, attr, &ctx->Pack);
+ }
+ else {
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" );
+ FREE(attr);
+ goto end;
+ }
+
/* unpacking attribs */
attr = CALLOC_STRUCT( gl_pixelstore_attrib );
- copy_pixelstore(ctx, attr, &ctx->Unpack);
- save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr);
+ if (attr == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
+ goto end;
+ }
+
+ if (save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr)) {
+ copy_pixelstore(ctx, attr, &ctx->Unpack);
+ }
+ else {
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib" );
+ FREE(attr);
+ goto end;
+ }
}
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
struct gl_array_attrib *attr;
attr = CALLOC_STRUCT( gl_array_attrib );
- init_array_attrib_data(ctx, attr);
- save_array_attrib(ctx, attr, &ctx->Array);
- save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr);
- }
+ if (attr == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
+ goto end;
+ }
- ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
- ctx->ClientAttribStackDepth++;
+ if (!init_array_attrib_data(ctx, attr)) {
+ FREE(attr);
+ goto end;
+ }
+
+ if (save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr)) {
+ save_array_attrib(ctx, attr, &ctx->Array);
+ }
+ else {
+ free_array_attrib_data(ctx, attr);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushClientAttrib");
+ FREE(attr);
+ /* goto to keep safe from possible later changes */
+ goto end;
+ }
+ }
+end:
+ if (head != NULL) {
+ ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head;
+ ctx->ClientAttribStackDepth++;
+ }
}
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c
index 8b5ebc489..a3d8f24b1 100644
--- a/mesalib/src/mesa/main/bufferobj.c
+++ b/mesalib/src/mesa/main/bufferobj.c
@@ -41,6 +41,9 @@
#include "fbobject.h"
#include "mtypes.h"
#include "texobj.h"
+#include "teximage.h"
+#include "glformats.h"
+#include "texstore.h"
#include "transformfeedback.h"
#include "dispatch.h"
@@ -124,11 +127,13 @@ get_buffer_target(struct gl_context *ctx, GLenum target)
* Get the buffer object bound to the specified target in a GL context.
* \param ctx the GL context
* \param target the buffer object target to be retrieved.
+ * \param error the GL error to record if target is illegal.
* \return pointer to the buffer object bound to \c target in the
* specified context or \c NULL if \c target is invalid.
*/
static inline struct gl_buffer_object *
-get_buffer(struct gl_context *ctx, const char *func, GLenum target)
+get_buffer(struct gl_context *ctx, const char *func, GLenum target,
+ GLenum error)
{
struct gl_buffer_object **bufObj = get_buffer_target(ctx, target);
@@ -138,7 +143,7 @@ get_buffer(struct gl_context *ctx, const char *func, GLenum target)
}
if (!_mesa_is_bufferobj(*bufObj)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(buffer 0)", func);
+ _mesa_error(ctx, error, "%s(no buffer bound)", func);
return NULL;
}
@@ -186,25 +191,58 @@ simplified_access_mode(struct gl_context *ctx, GLbitfield access)
/**
+ * Test if the buffer is mapped, and if so, if the mapped range overlaps the
+ * given range.
+ * The regions do not overlap if and only if the end of the given
+ * region is before the mapped region or the start of the given region
+ * is after the mapped region.
+ *
+ * \param obj Buffer object target on which to operate.
+ * \param offset Offset of the first byte of the subdata range.
+ * \param size Size, in bytes, of the subdata range.
+ * \return true if ranges overlap, false otherwise
+ *
+ */
+static bool
+bufferobj_range_mapped(const struct gl_buffer_object *obj,
+ GLintptr offset, GLsizeiptr size)
+{
+ if (_mesa_bufferobj_mapped(obj)) {
+ const GLintptr end = offset + size;
+ const GLintptr mapEnd = obj->Offset + obj->Length;
+
+ if (!(end <= obj->Offset || offset >= mapEnd)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**
* Tests the subdata range parameters and sets the GL error code for
- * \c glBufferSubDataARB and \c glGetBufferSubDataARB.
+ * \c glBufferSubDataARB, \c glGetBufferSubDataARB and
+ * \c glClearBufferSubData.
*
* \param ctx GL context.
* \param target Buffer object target on which to operate.
* \param offset Offset of the first byte of the subdata range.
* \param size Size, in bytes, of the subdata range.
+ * \param mappedRange If true, checks if an overlapping range is mapped.
+ * If false, checks if buffer is mapped.
+ * \param errorNoBuffer Error code if no buffer is bound to target.
* \param caller Name of calling function for recording errors.
* \return A pointer to the buffer object bound to \c target in the
* specified context or \c NULL if any of the parameter or state
- * conditions for \c glBufferSubDataARB or \c glGetBufferSubDataARB
- * are invalid.
+ * conditions are invalid.
*
- * \sa glBufferSubDataARB, glGetBufferSubDataARB
+ * \sa glBufferSubDataARB, glGetBufferSubDataARB, glClearBufferSubData
*/
static struct gl_buffer_object *
-buffer_object_subdata_range_good( struct gl_context * ctx, GLenum target,
- GLintptrARB offset, GLsizeiptrARB size,
- const char *caller )
+buffer_object_subdata_range_good(struct gl_context * ctx, GLenum target,
+ GLintptrARB offset, GLsizeiptrARB size,
+ bool mappedRange, GLenum errorNoBuffer,
+ const char *caller)
{
struct gl_buffer_object *bufObj;
@@ -218,22 +256,30 @@ buffer_object_subdata_range_good( struct gl_context * ctx, GLenum target,
return NULL;
}
- bufObj = get_buffer(ctx, caller, target);
+ bufObj = get_buffer(ctx, caller, target, errorNoBuffer);
if (!bufObj)
return NULL;
if (offset + size > bufObj->Size) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "%s(offset %lu + size %lu > buffer size %lu)", caller,
+ "%s(offset %lu + size %lu > buffer size %lu)", caller,
(unsigned long) offset,
(unsigned long) size,
(unsigned long) bufObj->Size);
return NULL;
}
- if (_mesa_bufferobj_mapped(bufObj)) {
- /* Buffer is currently mapped */
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
- return NULL;
+
+ if (mappedRange) {
+ if (bufferobj_range_mapped(bufObj, offset, size)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
+ return NULL;
+ }
+ }
+ else {
+ if (_mesa_bufferobj_mapped(bufObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
+ return NULL;
+ }
}
return bufObj;
@@ -241,6 +287,98 @@ buffer_object_subdata_range_good( struct gl_context * ctx, GLenum target,
/**
+ * Test the format and type parameters and set the GL error code for
+ * \c glClearBufferData and \c glClearBufferSubData.
+ *
+ * \param ctx GL context.
+ * \param internalformat Format to which the data is to be converted.
+ * \param format Format of the supplied data.
+ * \param type Type of the supplied data.
+ * \param caller Name of calling function for recording errors.
+ * \return If internalformat, format and type are legal the gl_format
+ * corresponding to internalformat, otherwise MESA_FORMAT_NONE.
+ *
+ * \sa glClearBufferData and glClearBufferSubData
+ */
+static gl_format
+validate_clear_buffer_format(struct gl_context *ctx,
+ GLenum internalformat,
+ GLenum format, GLenum type,
+ const char *caller)
+{
+ gl_format mesaFormat;
+ GLenum errorFormatType;
+
+ mesaFormat = _mesa_validate_texbuffer_format(ctx, internalformat);
+ if (mesaFormat == MESA_FORMAT_NONE) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(invalid internalformat)", caller);
+ return MESA_FORMAT_NONE;
+ }
+
+ /* NOTE: not mentioned in ARB_clear_buffer_object but according to
+ * EXT_texture_integer there is no conversion between integer and
+ * non-integer formats
+ */
+ if (_mesa_is_enum_format_signed_int(format) !=
+ _mesa_is_format_integer_color(mesaFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(integer vs non-integer)", caller);
+ return MESA_FORMAT_NONE;
+ }
+
+ if (!_mesa_is_color_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(format is not a color format)", caller);
+ return MESA_FORMAT_NONE;
+ }
+
+ errorFormatType = _mesa_error_check_format_and_type(ctx, format, type);
+ if (errorFormatType != GL_NO_ERROR) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "%s(invalid format or type)", caller);
+ return MESA_FORMAT_NONE;
+ }
+
+ return mesaFormat;
+}
+
+
+/**
+ * Convert user-specified clear value to the specified internal format.
+ *
+ * \param ctx GL context.
+ * \param internalformat Format to which the data is converted.
+ * \param clearValue Points to the converted clear value.
+ * \param format Format of the supplied data.
+ * \param type Type of the supplied data.
+ * \param data Data which is to be converted to internalformat.
+ * \param caller Name of calling function for recording errors.
+ * \return true if data could be converted, false otherwise.
+ *
+ * \sa glClearBufferData, glClearBufferSubData
+ */
+static bool
+convert_clear_buffer_data(struct gl_context *ctx,
+ gl_format internalformat,
+ GLubyte *clearValue, GLenum format, GLenum type,
+ const GLvoid *data, const char *caller)
+{
+ GLenum internalformatBase = _mesa_get_format_base_format(internalformat);
+
+ if (_mesa_texstore(ctx, 1, internalformatBase, internalformat,
+ 0, &clearValue, 1, 1, 1,
+ format, type, data, &ctx->Unpack)) {
+ return true;
+ }
+ else {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
+ return false;
+ }
+}
+
+
+/**
* Allocate and initialize a new buffer object.
*
* Default callback for the \c dd_function_table::NewBufferObject() hook.
@@ -505,6 +643,82 @@ _mesa_buffer_get_subdata( struct gl_context *ctx, GLintptrARB offset,
/**
+ * Clear a subrange of the buffer object with copies of the supplied data.
+ * If data is NULL the buffer is filled with zeros.
+ *
+ * This is the default callback for \c dd_function_table::ClearBufferSubData()
+ * Note that all GL error checking will have been done already.
+ *
+ * \param ctx GL context.
+ * \param offset Offset of the first byte to be cleared.
+ * \param size Size, in bytes, of the to be cleared range.
+ * \param clearValue Source of the data.
+ * \param clearValueSize Size, in bytes, of the supplied data.
+ * \param bufObj Object to be cleared.
+ *
+ * \sa glClearBufferSubData, glClearBufferData and
+ * dd_function_table::ClearBufferSubData.
+ */
+static void
+_mesa_buffer_clear_subdata(struct gl_context *ctx,
+ GLintptr offset, GLsizeiptr size,
+ const GLvoid *clearValue,
+ GLsizeiptr clearValueSize,
+ struct gl_buffer_object *bufObj)
+{
+ GLsizeiptr i;
+ GLubyte *dest;
+
+ if (_mesa_bufferobj_mapped(bufObj)) {
+ GLubyte *data = malloc(size);
+ GLubyte *dataStart = data;
+ if (data == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearBuffer[Sub]Data");
+ return;
+ }
+
+ if (clearValue == NULL) {
+ /* Clear with zeros, per the spec */
+ memset(data, 0, size);
+ }
+ else {
+ for (i = 0; i < size/clearValueSize; ++i) {
+ memcpy(data, clearValue, clearValueSize);
+ data += clearValueSize;
+ }
+ }
+ ctx->Driver.BufferSubData(ctx, offset, size, dataStart, bufObj);
+ return;
+ }
+
+ ASSERT(ctx->Driver.MapBufferRange);
+ dest = ctx->Driver.MapBufferRange(ctx, offset, size,
+ GL_MAP_WRITE_BIT |
+ GL_MAP_INVALIDATE_RANGE_BIT,
+ bufObj);
+
+ if (!dest) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearBuffer[Sub]Data");
+ return;
+ }
+
+ if (clearValue == NULL) {
+ /* Clear with zeros, per the spec */
+ memset(dest, 0, size);
+ ctx->Driver.UnmapBuffer(ctx, bufObj);
+ return;
+ }
+
+ for (i = 0; i < size/clearValueSize; ++i) {
+ memcpy(dest, clearValue, clearValueSize);
+ dest += clearValueSize;
+ }
+
+ ctx->Driver.UnmapBuffer(ctx, bufObj);
+}
+
+
+/**
* Default fallback for \c dd_function_table::MapBufferRange().
* Called via glMapBufferRange().
*/
@@ -810,6 +1024,9 @@ _mesa_init_buffer_object_functions(struct dd_function_table *driver)
driver->GetBufferSubData = _mesa_buffer_get_subdata;
driver->UnmapBuffer = _mesa_buffer_unmap;
+ /* GL_ARB_clear_buffer_object */
+ driver->ClearBufferSubData = _mesa_buffer_clear_subdata;
+
/* GL_ARB_map_buffer_range */
driver->MapBufferRange = _mesa_buffer_map_range;
driver->FlushMappedBufferRange = _mesa_buffer_flush_mapped_range;
@@ -1064,7 +1281,7 @@ _mesa_BufferData(GLenum target, GLsizeiptrARB size,
return;
}
- bufObj = get_buffer(ctx, "glBufferDataARB", target);
+ bufObj = get_buffer(ctx, "glBufferDataARB", target, GL_INVALID_OPERATION);
if (!bufObj)
return;
@@ -1103,6 +1320,7 @@ _mesa_BufferSubData(GLenum target, GLintptrARB offset,
struct gl_buffer_object *bufObj;
bufObj = buffer_object_subdata_range_good( ctx, target, offset, size,
+ false, GL_INVALID_OPERATION,
"glBufferSubDataARB" );
if (!bufObj) {
/* error already recorded */
@@ -1126,8 +1344,9 @@ _mesa_GetBufferSubData(GLenum target, GLintptrARB offset,
GET_CURRENT_CONTEXT(ctx);
struct gl_buffer_object *bufObj;
- bufObj = buffer_object_subdata_range_good( ctx, target, offset, size,
- "glGetBufferSubDataARB" );
+ bufObj = buffer_object_subdata_range_good(ctx, target, offset, size,
+ false, GL_INVALID_OPERATION,
+ "glGetBufferSubDataARB");
if (!bufObj) {
/* error already recorded */
return;
@@ -1138,6 +1357,111 @@ _mesa_GetBufferSubData(GLenum target, GLintptrARB offset,
}
+void GLAPIENTRY
+_mesa_ClearBufferData(GLenum target, GLenum internalformat, GLenum format,
+ GLenum type, const GLvoid* data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object* bufObj;
+ gl_format mesaFormat;
+ GLubyte clearValue[MAX_PIXEL_BYTES];
+ GLsizeiptr clearValueSize;
+
+ bufObj = get_buffer(ctx, "glClearBufferData", target, GL_INVALID_VALUE);
+ if (!bufObj) {
+ return;
+ }
+
+ if (_mesa_bufferobj_mapped(bufObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glClearBufferData(buffer currently mapped)");
+ return;
+ }
+
+ mesaFormat = validate_clear_buffer_format(ctx, internalformat,
+ format, type,
+ "glClearBufferData");
+ if (mesaFormat == MESA_FORMAT_NONE) {
+ return;
+ }
+
+ clearValueSize = _mesa_get_format_bytes(mesaFormat);
+ if (bufObj->Size % clearValueSize != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glClearBufferData(size is not a multiple of "
+ "internalformat size)");
+ return;
+ }
+
+ if (data == NULL) {
+ /* clear to zeros, per the spec */
+ ctx->Driver.ClearBufferSubData(ctx, 0, bufObj->Size,
+ NULL, 0, bufObj);
+ return;
+ }
+
+ if (!convert_clear_buffer_data(ctx, mesaFormat, clearValue,
+ format, type, data, "glClearBufferData")) {
+ return;
+ }
+
+ ctx->Driver.ClearBufferSubData(ctx, 0, bufObj->Size,
+ clearValue, clearValueSize, bufObj);
+}
+
+
+void GLAPIENTRY
+_mesa_ClearBufferSubData(GLenum target, GLenum internalformat,
+ GLintptr offset, GLsizeiptr size,
+ GLenum format, GLenum type,
+ const GLvoid* data)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_buffer_object* bufObj;
+ gl_format mesaFormat;
+ GLubyte clearValue[MAX_PIXEL_BYTES];
+ GLsizeiptr clearValueSize;
+
+ bufObj = buffer_object_subdata_range_good(ctx, target, offset, size,
+ true, GL_INVALID_VALUE,
+ "glClearBufferSubData");
+ if (!bufObj) {
+ return;
+ }
+
+ mesaFormat = validate_clear_buffer_format(ctx, internalformat,
+ format, type,
+ "glClearBufferSubData");
+ if (mesaFormat == MESA_FORMAT_NONE) {
+ return;
+ }
+
+ clearValueSize = _mesa_get_format_bytes(mesaFormat);
+ if (offset % clearValueSize != 0 || size % clearValueSize != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glClearBufferSubData(offset or size is not a multiple of "
+ "internalformat size)");
+ return;
+ }
+
+ if (data == NULL) {
+ /* clear to zeros, per the spec */
+ ctx->Driver.ClearBufferSubData(ctx, offset, size,
+ NULL, 0, bufObj);
+ return;
+ }
+
+ if (!convert_clear_buffer_data(ctx, mesaFormat, clearValue,
+ format, type, data,
+ "glClearBufferSubData")) {
+ return;
+ }
+
+ ctx->Driver.ClearBufferSubData(ctx, offset, size,
+ clearValue, clearValueSize, bufObj);
+}
+
+
void * GLAPIENTRY
_mesa_MapBuffer(GLenum target, GLenum access)
{
@@ -1172,7 +1496,7 @@ _mesa_MapBuffer(GLenum target, GLenum access)
return NULL;
}
- bufObj = get_buffer(ctx, "glMapBufferARB", target);
+ bufObj = get_buffer(ctx, "glMapBufferARB", target, GL_INVALID_OPERATION);
if (!bufObj)
return NULL;
@@ -1241,7 +1565,7 @@ _mesa_UnmapBuffer(GLenum target)
GLboolean status = GL_TRUE;
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- bufObj = get_buffer(ctx, "glUnmapBufferARB", target);
+ bufObj = get_buffer(ctx, "glUnmapBufferARB", target, GL_INVALID_OPERATION);
if (!bufObj)
return GL_FALSE;
@@ -1302,7 +1626,8 @@ _mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
GET_CURRENT_CONTEXT(ctx);
struct gl_buffer_object *bufObj;
- bufObj = get_buffer(ctx, "glGetBufferParameterivARB", target);
+ bufObj = get_buffer(ctx, "glGetBufferParameterivARB", target,
+ GL_INVALID_OPERATION);
if (!bufObj)
return;
@@ -1355,7 +1680,8 @@ _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
GET_CURRENT_CONTEXT(ctx);
struct gl_buffer_object *bufObj;
- bufObj = get_buffer(ctx, "glGetBufferParameteri64v", target);
+ bufObj = get_buffer(ctx, "glGetBufferParameteri64v", target,
+ GL_INVALID_OPERATION);
if (!bufObj)
return;
@@ -1408,7 +1734,8 @@ _mesa_GetBufferPointerv(GLenum target, GLenum pname, GLvoid **params)
return;
}
- bufObj = get_buffer(ctx, "glGetBufferPointervARB", target);
+ bufObj = get_buffer(ctx, "glGetBufferPointervARB", target,
+ GL_INVALID_OPERATION);
if (!bufObj)
return;
@@ -1424,11 +1751,13 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
GET_CURRENT_CONTEXT(ctx);
struct gl_buffer_object *src, *dst;
- src = get_buffer(ctx, "glCopyBufferSubData", readTarget);
+ src = get_buffer(ctx, "glCopyBufferSubData", readTarget,
+ GL_INVALID_OPERATION);
if (!src)
return;
- dst = get_buffer(ctx, "glCopyBufferSubData", writeTarget);
+ dst = get_buffer(ctx, "glCopyBufferSubData", writeTarget,
+ GL_INVALID_OPERATION);
if (!dst)
return;
@@ -1572,7 +1901,7 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
return NULL;
}
- bufObj = get_buffer(ctx, "glMapBufferRange", target);
+ bufObj = get_buffer(ctx, "glMapBufferRange", target, GL_INVALID_OPERATION);
if (!bufObj)
return NULL;
@@ -1651,7 +1980,8 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
return;
}
- bufObj = get_buffer(ctx, "glFlushMappedBufferRange", target);
+ bufObj = get_buffer(ctx, "glFlushMappedBufferRange", target,
+ GL_INVALID_OPERATION);
if (!bufObj)
return;
@@ -2331,23 +2661,11 @@ _mesa_InvalidateBufferSubData(GLuint buffer, GLintptr offset,
* mapped by MapBuffer, or if the invalidate range intersects the range
* currently mapped by MapBufferRange."
*/
- if (_mesa_bufferobj_mapped(bufObj)) {
- const GLintptr mapEnd = bufObj->Offset + bufObj->Length;
-
- /* The regions do not overlap if and only if the end of the discard
- * region is before the mapped region or the start of the discard region
- * is after the mapped region.
- *
- * Note that 'end' and 'mapEnd' are the first byte *after* the discard
- * region and the mapped region, repsectively. It is okay for that byte
- * to be mapped (for 'end') or discarded (for 'mapEnd').
- */
- if (!(end <= bufObj->Offset || offset >= mapEnd)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glInvalidateBufferSubData(intersection with mapped "
- "range)");
- return;
- }
+ if (bufferobj_range_mapped(bufObj, offset, length)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glInvalidateBufferSubData(intersection with mapped "
+ "range)");
+ return;
}
/* We don't actually do anything for this yet. Just return after
diff --git a/mesalib/src/mesa/main/bufferobj.h b/mesalib/src/mesa/main/bufferobj.h
index 0b898a21b..71988b0d9 100644
--- a/mesalib/src/mesa/main/bufferobj.h
+++ b/mesalib/src/mesa/main/bufferobj.h
@@ -57,10 +57,10 @@ _mesa_is_bufferobj(const struct gl_buffer_object *obj)
extern void
-_mesa_init_buffer_objects( struct gl_context *ctx );
+_mesa_init_buffer_objects(struct gl_context *ctx);
extern void
-_mesa_free_buffer_objects( struct gl_context *ctx );
+_mesa_free_buffer_objects(struct gl_context *ctx);
extern bool
_mesa_handle_bind_buffer_gen(struct gl_context *ctx,
@@ -77,9 +77,9 @@ extern struct gl_buffer_object *
_mesa_lookup_bufferobj(struct gl_context *ctx, GLuint buffer);
extern void
-_mesa_initialize_buffer_object( struct gl_context *ctx,
- struct gl_buffer_object *obj,
- GLuint name, GLenum target );
+_mesa_initialize_buffer_object(struct gl_context *ctx,
+ struct gl_buffer_object *obj,
+ GLuint name, GLenum target);
extern void
_mesa_reference_buffer_object_(struct gl_context *ctx,
@@ -105,55 +105,90 @@ _mesa_init_buffer_object_functions(struct dd_function_table *driver);
/*
* API functions
*/
-
void GLAPIENTRY
_mesa_BindBuffer(GLenum target, GLuint buffer);
+
void GLAPIENTRY
_mesa_DeleteBuffers(GLsizei n, const GLuint * buffer);
+
void GLAPIENTRY
_mesa_GenBuffers(GLsizei n, GLuint * buffer);
+
GLboolean GLAPIENTRY
_mesa_IsBuffer(GLuint buffer);
+
void GLAPIENTRY
-_mesa_BufferData(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
+_mesa_BufferData(GLenum target, GLsizeiptrARB size,
+ const GLvoid * data, GLenum usage);
+
void GLAPIENTRY
-_mesa_BufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data);
+_mesa_BufferSubData(GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, const GLvoid * data);
+
void GLAPIENTRY
-_mesa_GetBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data);
+_mesa_GetBufferSubData(GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, void * data);
+
+void GLAPIENTRY
+_mesa_ClearBufferData(GLenum target, GLenum internalformat,
+ GLenum format, GLenum type,
+ const GLvoid * data);
+
+void GLAPIENTRY
+_mesa_ClearBufferSubData(GLenum target, GLenum internalformat,
+ GLintptr offset, GLsizeiptr size,
+ GLenum format, GLenum type,
+ const GLvoid * data);
+
void * GLAPIENTRY
_mesa_MapBuffer(GLenum target, GLenum access);
+
GLboolean GLAPIENTRY
_mesa_UnmapBuffer(GLenum target);
+
void GLAPIENTRY
_mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params);
+
void GLAPIENTRY
_mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params);
+
void GLAPIENTRY
_mesa_GetBufferPointerv(GLenum target, GLenum pname, GLvoid **params);
+
void GLAPIENTRY
_mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
GLintptr readOffset, GLintptr writeOffset,
GLsizeiptr size);
+
void * GLAPIENTRY
_mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
GLbitfield access);
+
void GLAPIENTRY
-_mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length);
+_mesa_FlushMappedBufferRange(GLenum target,
+ GLintptr offset, GLsizeiptr length);
+
GLenum GLAPIENTRY
_mesa_ObjectPurgeableAPPLE(GLenum objectType, GLuint name, GLenum option);
+
GLenum GLAPIENTRY
_mesa_ObjectUnpurgeableAPPLE(GLenum objectType, GLuint name, GLenum option);
+
void GLAPIENTRY
-_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, GLenum pname,
- GLint* params);
+_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name,
+ GLenum pname, GLint* params);
+
void GLAPIENTRY
_mesa_BindBufferRange(GLenum target, GLuint index,
GLuint buffer, GLintptr offset, GLsizeiptr size);
+
void GLAPIENTRY
_mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer);
+
void GLAPIENTRY
_mesa_InvalidateBufferSubData(GLuint buffer, GLintptr offset,
GLsizeiptr length);
+
void GLAPIENTRY
_mesa_InvalidateBufferData(GLuint buffer);
diff --git a/mesalib/src/mesa/main/clear.c b/mesalib/src/mesa/main/clear.c
index 304d135d1..f0b525fa0 100644
--- a/mesalib/src/mesa/main/clear.c
+++ b/mesalib/src/mesa/main/clear.c
@@ -219,7 +219,25 @@ make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer)
const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
GLbitfield mask = 0x0;
- switch (drawbuffer) {
+ /* From the GL 4.0 specification:
+ * If buffer is COLOR, a particular draw buffer DRAW_BUFFERi is
+ * specified by passing i as the parameter drawbuffer, and value
+ * points to a four-element vector specifying the R, G, B, and A
+ * color to clear that draw buffer to. If the draw buffer is one
+ * of FRONT, BACK, LEFT, RIGHT, or FRONT_AND_BACK, identifying
+ * multiple buffers, each selected buffer is cleared to the same
+ * value.
+ *
+ * Note that "drawbuffer" and "draw buffer" have different meaning.
+ * "drawbuffer" specifies DRAW_BUFFERi, while "draw buffer" is what's
+ * assigned to DRAW_BUFFERi. It could be COLOR_ATTACHMENT0, FRONT, BACK,
+ * etc.
+ */
+ if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) {
+ return INVALID_MASK;
+ }
+
+ switch (ctx->DrawBuffer->ColorDrawBuffer[drawbuffer]) {
case GL_FRONT:
if (att[BUFFER_FRONT_LEFT].Renderbuffer)
mask |= BUFFER_BIT_FRONT_LEFT;
@@ -255,11 +273,12 @@ make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer)
mask |= BUFFER_BIT_BACK_RIGHT;
break;
default:
- if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) {
- mask = INVALID_MASK;
- }
- else if (att[BUFFER_COLOR0 + drawbuffer].Renderbuffer) {
- mask |= (BUFFER_BIT_COLOR0 << drawbuffer);
+ {
+ GLuint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer];
+
+ if (buf >= 0 && att[buf].Renderbuffer) {
+ mask |= 1 << buf;
+ }
}
}
diff --git a/mesalib/src/mesa/main/colortab.c b/mesalib/src/mesa/main/colortab.c
index 81e92d71c..a8edb03dd 100644
--- a/mesalib/src/mesa/main/colortab.c
+++ b/mesalib/src/mesa/main/colortab.c
@@ -44,7 +44,7 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat,
const GLvoid *data )
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable");
}
@@ -55,7 +55,7 @@ _mesa_ColorSubTable( GLenum target, GLsizei start,
const GLvoid *data )
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable");
}
@@ -65,7 +65,7 @@ _mesa_CopyColorTable(GLenum target, GLenum internalformat,
GLint x, GLint y, GLsizei width)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glCopyColorTable(target)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyColorTable");
}
@@ -75,7 +75,7 @@ _mesa_CopyColorSubTable(GLenum target, GLsizei start,
GLint x, GLint y, GLsizei width)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glCopyColorSubTable(target)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyColorSubTable");
}
@@ -85,7 +85,7 @@ _mesa_GetnColorTableARB( GLenum target, GLenum format, GLenum type,
GLsizei bufSize, GLvoid *data )
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetnColorTableARB(target)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetnColorTableARB");
}
@@ -94,7 +94,7 @@ _mesa_GetColorTable( GLenum target, GLenum format,
GLenum type, GLvoid *data )
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetColorTable");
}
@@ -103,7 +103,7 @@ _mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params)
{
/* no extensions use this function */
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(target)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTableParameterfv");
}
@@ -113,7 +113,7 @@ _mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
{
/* no extensions use this function */
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameteriv(target)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTableParameteriv");
}
@@ -122,7 +122,7 @@ void GLAPIENTRY
_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetColorTableParameterfv");
}
@@ -131,5 +131,5 @@ void GLAPIENTRY
_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetColorTableParameteriv");
}
diff --git a/mesalib/src/mesa/main/condrender.c b/mesalib/src/mesa/main/condrender.c
index 3d9b0eca1..2632f7a1a 100644
--- a/mesalib/src/mesa/main/condrender.c
+++ b/mesalib/src/mesa/main/condrender.c
@@ -72,7 +72,9 @@ _mesa_BeginConditionalRender(GLuint queryId, GLenum mode)
}
ASSERT(q->Id == queryId);
- if (q->Target != GL_SAMPLES_PASSED || q->Active) {
+ if ((q->Target != GL_SAMPLES_PASSED &&
+ q->Target != GL_ANY_SAMPLES_PASSED &&
+ q->Target != GL_ANY_SAMPLES_PASSED_CONSERVATIVE) || q->Active) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
return;
}
diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c
index 87a4a3545..658499fa4 100644
--- a/mesalib/src/mesa/main/context.c
+++ b/mesalib/src/mesa/main/context.c
@@ -1194,6 +1194,7 @@ _mesa_free_context_data( struct gl_context *ctx )
_mesa_free_sync_data(ctx);
_mesa_free_varray_data(ctx);
_mesa_free_transform_feedback(ctx);
+ _mesa_free_performance_monitors(ctx);
_mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
_mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
diff --git a/mesalib/src/mesa/main/convolve.c b/mesalib/src/mesa/main/convolve.c
index f44031a9b..b13b89535 100644
--- a/mesalib/src/mesa/main/convolve.c
+++ b/mesalib/src/mesa/main/convolve.c
@@ -45,7 +45,7 @@ _mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, G
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter1D");
}
void GLAPIENTRY
@@ -53,7 +53,7 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter2D");
}
@@ -62,7 +62,7 @@ _mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameterf");
}
@@ -71,7 +71,7 @@ _mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameterfv");
}
@@ -80,7 +80,7 @@ _mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameteri");
}
@@ -89,7 +89,7 @@ _mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameteriv");
}
@@ -98,7 +98,7 @@ _mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, GLi
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyConvolutionFilter1D");
}
@@ -107,7 +107,7 @@ _mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, GLi
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyConvolutionFilter2D");
}
@@ -134,7 +134,7 @@ _mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionParameterfv");
}
@@ -143,7 +143,7 @@ _mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionParameteriv");
}
@@ -155,7 +155,7 @@ _mesa_GetnSeparableFilterARB(GLenum target, GLenum format, GLenum type,
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetSeparableFilter");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetSeparableFilter");
}
@@ -173,5 +173,5 @@ _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLs
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D");
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glSeparableFilter2D");
}
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index b5b874f47..6e73691ea 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -375,6 +375,11 @@ struct dd_function_table {
GLsizei levels, GLsizei width,
GLsizei height, GLsizei depth);
+ /** Called as part of glTextureView to add views to origTexObj */
+ GLboolean (*TextureView)(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ struct gl_texture_object *origTexObj);
+
/**
* Map a renderbuffer into user space.
* \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT and
@@ -569,6 +574,12 @@ struct dd_function_table {
GLintptrARB offset, GLsizeiptrARB size,
GLvoid *data, struct gl_buffer_object *obj );
+ void (*ClearBufferSubData)( struct gl_context *ctx,
+ GLintptr offset, GLsizeiptr size,
+ const GLvoid *clearValue,
+ GLsizeiptr clearValueSize,
+ struct gl_buffer_object *obj );
+
void (*CopyBufferSubData)( struct gl_context *ctx,
struct gl_buffer_object *src,
struct gl_buffer_object *dst,
diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c
index 595641915..cb40ff4db 100644
--- a/mesalib/src/mesa/main/dlist.c
+++ b/mesalib/src/mesa/main/dlist.c
@@ -209,18 +209,6 @@ typedef enum
OPCODE_COLOR_MASK,
OPCODE_COLOR_MASK_INDEXED,
OPCODE_COLOR_MATERIAL,
- OPCODE_COLOR_TABLE,
- OPCODE_COLOR_TABLE_PARAMETER_FV,
- OPCODE_COLOR_TABLE_PARAMETER_IV,
- OPCODE_COLOR_SUB_TABLE,
- OPCODE_CONVOLUTION_FILTER_1D,
- OPCODE_CONVOLUTION_FILTER_2D,
- OPCODE_CONVOLUTION_PARAMETER_I,
- OPCODE_CONVOLUTION_PARAMETER_IV,
- OPCODE_CONVOLUTION_PARAMETER_F,
- OPCODE_CONVOLUTION_PARAMETER_FV,
- OPCODE_COPY_COLOR_SUB_TABLE,
- OPCODE_COPY_COLOR_TABLE,
OPCODE_COPY_PIXELS,
OPCODE_COPY_TEX_IMAGE1D,
OPCODE_COPY_TEX_IMAGE2D,
@@ -243,7 +231,6 @@ typedef enum
OPCODE_FRONT_FACE,
OPCODE_FRUSTUM,
OPCODE_HINT,
- OPCODE_HISTOGRAM,
OPCODE_INDEX_MASK,
OPCODE_INIT_NAMES,
OPCODE_LIGHT,
@@ -260,7 +247,6 @@ typedef enum
OPCODE_MAPGRID1,
OPCODE_MAPGRID2,
OPCODE_MATRIX_MODE,
- OPCODE_MIN_MAX,
OPCODE_MULT_MATRIX,
OPCODE_ORTHO,
OPCODE_PASSTHROUGH,
@@ -281,8 +267,6 @@ typedef enum
OPCODE_PUSH_NAME,
OPCODE_RASTER_POS,
OPCODE_READ_BUFFER,
- OPCODE_RESET_HISTOGRAM,
- OPCODE_RESET_MIN_MAX,
OPCODE_ROTATE,
OPCODE_SCALE,
OPCODE_SCISSOR,
@@ -486,6 +470,10 @@ typedef enum
* Each instruction in the display list is stored as a sequence of
* contiguous nodes in memory.
* Each node is the union of a variety of data types.
+ *
+ * Note, all of these members should be 4 bytes in size or less for the
+ * sake of compact display lists. We store 8-byte pointers in a pair of
+ * these nodes using the save/get_pointer() functions below.
*/
union gl_dlist_node
{
@@ -500,14 +488,61 @@ union gl_dlist_node
GLenum e;
GLfloat f;
GLsizei si;
- GLvoid *data;
- void *next; /* If prev node's opcode==OPCODE_CONTINUE */
};
typedef union gl_dlist_node Node;
+/** How many 4-byte dwords to store a pointer */
+#define POINTER_DWORDS (sizeof(void *) / 4)
+
+/* We want to keep sizeof(union gl_dlist_node) == 4 to minimize
+ * space for display lists. The following types and functions are
+ * used to help store 4- and 8-byte pointers in 1 or 2 dlist_nodes.
+ */
+union pointer
+{
+ void *ptr;
+ GLuint dwords[POINTER_DWORDS];
+};
+
+
+/**
+ * Save a 4 or 8-byte pointer at dest (and dest+1).
+ */
+static inline void
+save_pointer(union gl_dlist_node *dest, void *src)
+{
+ union pointer p;
+ unsigned i;
+
+ STATIC_ASSERT(POINTER_DWORDS == 1 || POINTER_DWORDS == 2);
+ STATIC_ASSERT(sizeof(union gl_dlist_node) == 4);
+
+ p.ptr = src;
+
+ for (i = 0; i < POINTER_DWORDS; i++)
+ dest[i].ui = p.dwords[i];
+}
+
+
+/**
+ * Retrieve a 4 or 8-byte pointer from node (node+1).
+ */
+static inline void *
+get_pointer(const union gl_dlist_node *node)
+{
+ union pointer p;
+ unsigned i;
+
+ for (i = 0; i < POINTER_DWORDS; i++)
+ p.dwords[i] = node[i].ui;
+
+ return p.ptr;
+}
+
+
/**
* Used to store a 64-bit uint in a pair of "Nodes" for the sake of 32-bit
* environment. In 64-bit env, sizeof(Node)==8 anyway.
@@ -520,9 +555,9 @@ union uint64_pair
/**
- * How many nodes to allocate at a time.
- *
- * \note Reduced now that we hold vertices etc. elsewhere.
+ * How many nodes to allocate at a time. Note that bulk vertex data
+ * from glBegin/glVertex/glEnd primitives will typically wind up in
+ * a VBO, and not directly in the display list itself.
*/
#define BLOCK_SIZE 256
@@ -538,14 +573,9 @@ static GLuint InstSize[OPCODE_END_OF_LIST + 1];
void mesa_print_display_list(GLuint list);
-/**********************************************************************/
-/***** Private *****/
-/**********************************************************************/
-
-
/**
- * Make an empty display list. This is used by glGenLists() to
- * reserve display list IDs.
+ * Allocate a gl_display_list object with an initial block of storage.
+ * \param count how many display list nodes/tokes to allocate
*/
static struct gl_display_list *
make_list(GLuint name, GLuint count)
@@ -637,91 +667,75 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
switch (opcode) {
/* for some commands, we need to free malloc'd memory */
case OPCODE_MAP1:
- free(n[6].data);
+ free(get_pointer(&n[6]));
n += InstSize[n[0].opcode];
break;
case OPCODE_MAP2:
- free(n[10].data);
+ free(get_pointer(&n[10]));
n += InstSize[n[0].opcode];
break;
case OPCODE_DRAW_PIXELS:
- free(n[5].data);
+ free(get_pointer(&n[5]));
n += InstSize[n[0].opcode];
break;
case OPCODE_BITMAP:
- free(n[7].data);
- n += InstSize[n[0].opcode];
- break;
- case OPCODE_COLOR_TABLE:
- free(n[6].data);
- n += InstSize[n[0].opcode];
- break;
- case OPCODE_COLOR_SUB_TABLE:
- free(n[6].data);
- n += InstSize[n[0].opcode];
- break;
- case OPCODE_CONVOLUTION_FILTER_1D:
- free(n[6].data);
- n += InstSize[n[0].opcode];
- break;
- case OPCODE_CONVOLUTION_FILTER_2D:
- free(n[7].data);
+ free(get_pointer(&n[7]));
n += InstSize[n[0].opcode];
break;
case OPCODE_POLYGON_STIPPLE:
- free(n[1].data);
+ free(get_pointer(&n[1]));
n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_IMAGE1D:
- free(n[8].data);
+ free(get_pointer(&n[8]));
n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_IMAGE2D:
- free(n[9].data);
+ free(get_pointer(&n[9]));
n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_IMAGE3D:
- free(n[10].data);
+ free(get_pointer(&n[10]));
n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_SUB_IMAGE1D:
- free(n[7].data);
+ free(get_pointer(&n[7]));
n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_SUB_IMAGE2D:
- free(n[9].data);
+ free(get_pointer(&n[9]));
n += InstSize[n[0].opcode];
break;
case OPCODE_TEX_SUB_IMAGE3D:
- free(n[11].data);
+ free(get_pointer(&n[11]));
n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_IMAGE_1D:
- free(n[7].data);
+ free(get_pointer(&n[7]));
n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_IMAGE_2D:
- free(n[8].data);
+ free(get_pointer(&n[8]));
n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_IMAGE_3D:
- free(n[9].data);
+ free(get_pointer(&n[9]));
n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D:
- free(n[7].data);
+ free(get_pointer(&n[7]));
n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D:
- free(n[9].data);
+ free(get_pointer(&n[9]));
n += InstSize[n[0].opcode];
break;
case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D:
- free(n[11].data);
+ free(get_pointer(&n[11]));
n += InstSize[n[0].opcode];
break;
case OPCODE_PROGRAM_STRING_ARB:
- free(n[4].data); /* program string */
+ free(get_pointer(&n[4])); /* program string */
n += InstSize[n[0].opcode];
break;
case OPCODE_UNIFORM_1FV:
@@ -736,7 +750,7 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
case OPCODE_UNIFORM_2UIV:
case OPCODE_UNIFORM_3UIV:
case OPCODE_UNIFORM_4UIV:
- free(n[3].data);
+ free(get_pointer(&n[3]));
n += InstSize[n[0].opcode];
break;
case OPCODE_UNIFORM_MATRIX22:
@@ -748,12 +762,15 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist)
case OPCODE_UNIFORM_MATRIX32:
case OPCODE_UNIFORM_MATRIX34:
case OPCODE_UNIFORM_MATRIX43:
- free(n[4].data);
+ free(get_pointer(&n[4]));
n += InstSize[n[0].opcode];
break;
+ case OPCODE_PIXEL_MAP:
+ free(get_pointer(&n[3]));
+ break;
case OPCODE_CONTINUE:
- n = (Node *) n[1].next;
+ n = (Node *) get_pointer(&n[1]);
free(block);
block = n;
break;
@@ -852,12 +869,6 @@ translate_id(GLsizei n, GLenum type, const GLvoid * list)
}
-
-
-/**********************************************************************/
-/***** Public *****/
-/**********************************************************************/
-
/**
* Wrapper for _mesa_unpack_image/bitmap() that handles pixel buffer objects.
* If width < 0 or height < 0 or format or type are invalid we'll just
@@ -929,6 +940,18 @@ unpack_image(struct gl_context *ctx, GLuint dimensions,
return NULL;
}
+
+/** Return copy of memory */
+static void *
+memdup(const void *src, GLsizei bytes)
+{
+ void *b = bytes >= 0 ? malloc(bytes) : NULL;
+ if (b)
+ memcpy(b, src, bytes);
+ return b;
+}
+
+
/**
* Allocate space for a display list instruction (opcode + payload space).
* \param opcode the instruction opcode (OPCODE_* value)
@@ -939,6 +962,7 @@ static Node *
dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes)
{
const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node);
+ const GLuint contNodes = 1 + POINTER_DWORDS; /* size of continue info */
Node *n;
if (opcode < (GLuint) OPCODE_EXT_0) {
@@ -952,7 +976,7 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes)
}
}
- if (ctx->ListState.CurrentPos + numNodes + 2 > BLOCK_SIZE) {
+ if (ctx->ListState.CurrentPos + numNodes + contNodes > BLOCK_SIZE) {
/* This block is full. Allocate a new block and chain to it */
Node *newblock;
n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos;
@@ -962,7 +986,7 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes)
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Building display list");
return NULL;
}
- n[1].next = (Node *) newblock;
+ save_pointer(&n[1], newblock);
ctx->ListState.CurrentBlock = newblock;
ctx->ListState.CurrentPos = 0;
}
@@ -1043,6 +1067,37 @@ alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams)
}
+/**
+ * Called by EndList to try to reduce memory used for the list.
+ */
+static void
+trim_list(struct gl_context *ctx)
+{
+ /* If the list we're ending only has one allocated block of nodes/tokens
+ * and its size isn't a full block size, realloc the block to use less
+ * memory. This is important for apps that create many small display
+ * lists and apps that use glXUseXFont (many lists each containing one
+ * glBitmap call).
+ * Note: we currently only trim display lists that allocated one block
+ * of tokens. That hits the short list case which is what we're mainly
+ * concerned with. Trimming longer lists would involve traversing the
+ * linked list of blocks.
+ */
+ struct gl_dlist_state *list = &ctx->ListState;
+
+ if ((list->CurrentList->Head == list->CurrentBlock) &&
+ (list->CurrentPos < BLOCK_SIZE)) {
+ /* There's only one block and it's not full, so realloc */
+ GLuint newSize = list->CurrentPos * sizeof(Node);
+ list->CurrentList->Head =
+ list->CurrentBlock = realloc(list->CurrentBlock, newSize);
+ if (!list->CurrentBlock) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEndList");
+ }
+ }
+}
+
+
/*
* Display List compilation functions
@@ -1106,7 +1161,7 @@ save_Bitmap(GLsizei width, GLsizei height,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_BITMAP, 7);
+ n = alloc_instruction(ctx, OPCODE_BITMAP, 6 + POINTER_DWORDS);
if (n) {
n[1].i = (GLint) width;
n[2].i = (GLint) height;
@@ -1114,8 +1169,9 @@ save_Bitmap(GLsizei width, GLsizei height,
n[4].f = yorig;
n[5].f = xmove;
n[6].f = ymove;
- n[7].data = unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX,
- GL_BITMAP, pixels, &ctx->Unpack);
+ save_pointer(&n[7],
+ unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX,
+ GL_BITMAP, pixels, &ctx->Unpack));
}
if (ctx->ExecuteFlag) {
CALL_Bitmap(ctx->Exec, (width, height,
@@ -1735,313 +1791,6 @@ save_ColorMaterial(GLenum face, GLenum mode)
static void GLAPIENTRY
-save_ColorTable(GLenum target, GLenum internalFormat,
- GLsizei width, GLenum format, GLenum type,
- const GLvoid * table)
-{
- GET_CURRENT_CONTEXT(ctx);
- if (_mesa_is_proxy_texture(target)) {
- /* execute immediately */
- CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
- format, type, table));
- }
- else {
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_COLOR_TABLE, 6);
- if (n) {
- n[1].e = target;
- n[2].e = internalFormat;
- n[3].i = width;
- n[4].e = format;
- n[5].e = type;
- n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, table,
- &ctx->Unpack);
- }
- if (ctx->ExecuteFlag) {
- CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
- format, type, table));
- }
- }
-}
-
-
-
-static void GLAPIENTRY
-save_ColorTableParameterfv(GLenum target, GLenum pname,
- const GLfloat *params)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
-
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-
- n = alloc_instruction(ctx, OPCODE_COLOR_TABLE_PARAMETER_FV, 6);
- if (n) {
- n[1].e = target;
- n[2].e = pname;
- n[3].f = params[0];
- if (pname == GL_COLOR_TABLE_SGI ||
- pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI ||
- pname == GL_TEXTURE_COLOR_TABLE_SGI) {
- n[4].f = params[1];
- n[5].f = params[2];
- n[6].f = params[3];
- }
- }
-
- if (ctx->ExecuteFlag) {
- CALL_ColorTableParameterfv(ctx->Exec, (target, pname, params));
- }
-}
-
-
-static void GLAPIENTRY
-save_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
-
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-
- n = alloc_instruction(ctx, OPCODE_COLOR_TABLE_PARAMETER_IV, 6);
- if (n) {
- n[1].e = target;
- n[2].e = pname;
- n[3].i = params[0];
- if (pname == GL_COLOR_TABLE_SGI ||
- pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI ||
- pname == GL_TEXTURE_COLOR_TABLE_SGI) {
- n[4].i = params[1];
- n[5].i = params[2];
- n[6].i = params[3];
- }
- }
-
- if (ctx->ExecuteFlag) {
- CALL_ColorTableParameteriv(ctx->Exec, (target, pname, params));
- }
-}
-
-
-
-static void GLAPIENTRY
-save_ColorSubTable(GLenum target, GLsizei start, GLsizei count,
- GLenum format, GLenum type, const GLvoid * table)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_COLOR_SUB_TABLE, 6);
- if (n) {
- n[1].e = target;
- n[2].i = start;
- n[3].i = count;
- n[4].e = format;
- n[5].e = type;
- n[6].data = unpack_image(ctx, 1, count, 1, 1, format, type, table,
- &ctx->Unpack);
- }
- if (ctx->ExecuteFlag) {
- CALL_ColorSubTable(ctx->Exec,
- (target, start, count, format, type, table));
- }
-}
-
-
-static void GLAPIENTRY
-save_CopyColorSubTable(GLenum target, GLsizei start,
- GLint x, GLint y, GLsizei width)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
-
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_COPY_COLOR_SUB_TABLE, 5);
- if (n) {
- n[1].e = target;
- n[2].i = start;
- n[3].i = x;
- n[4].i = y;
- n[5].i = width;
- }
- if (ctx->ExecuteFlag) {
- CALL_CopyColorSubTable(ctx->Exec, (target, start, x, y, width));
- }
-}
-
-
-static void GLAPIENTRY
-save_CopyColorTable(GLenum target, GLenum internalformat,
- GLint x, GLint y, GLsizei width)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
-
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_COPY_COLOR_TABLE, 5);
- if (n) {
- n[1].e = target;
- n[2].e = internalformat;
- n[3].i = x;
- n[4].i = y;
- n[5].i = width;
- }
- if (ctx->ExecuteFlag) {
- CALL_CopyColorTable(ctx->Exec, (target, internalformat, x, y, width));
- }
-}
-
-
-static void GLAPIENTRY
-save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
- GLenum format, GLenum type, const GLvoid * filter)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
-
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-
- n = alloc_instruction(ctx, OPCODE_CONVOLUTION_FILTER_1D, 6);
- if (n) {
- n[1].e = target;
- n[2].e = internalFormat;
- n[3].i = width;
- n[4].e = format;
- n[5].e = type;
- n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, filter,
- &ctx->Unpack);
- }
- if (ctx->ExecuteFlag) {
- CALL_ConvolutionFilter1D(ctx->Exec, (target, internalFormat, width,
- format, type, filter));
- }
-}
-
-
-static void GLAPIENTRY
-save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height, GLenum format,
- GLenum type, const GLvoid * filter)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
-
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
-
- n = alloc_instruction(ctx, OPCODE_CONVOLUTION_FILTER_2D, 7);
- if (n) {
- n[1].e = target;
- n[2].e = internalFormat;
- n[3].i = width;
- n[4].i = height;
- n[5].e = format;
- n[6].e = type;
- n[7].data = unpack_image(ctx, 2, width, height, 1, format, type, filter,
- &ctx->Unpack);
- }
- if (ctx->ExecuteFlag) {
- CALL_ConvolutionFilter2D(ctx->Exec,
- (target, internalFormat, width, height, format,
- type, filter));
- }
-}
-
-
-static void GLAPIENTRY
-save_ConvolutionParameteri(GLenum target, GLenum pname, GLint param)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_I, 3);
- if (n) {
- n[1].e = target;
- n[2].e = pname;
- n[3].i = param;
- }
- if (ctx->ExecuteFlag) {
- CALL_ConvolutionParameteri(ctx->Exec, (target, pname, param));
- }
-}
-
-
-static void GLAPIENTRY
-save_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6);
- if (n) {
- n[1].e = target;
- n[2].e = pname;
- n[3].i = params[0];
- if (pname == GL_CONVOLUTION_BORDER_COLOR ||
- pname == GL_CONVOLUTION_FILTER_SCALE ||
- pname == GL_CONVOLUTION_FILTER_BIAS) {
- n[4].i = params[1];
- n[5].i = params[2];
- n[6].i = params[3];
- }
- else {
- n[4].i = n[5].i = n[6].i = 0;
- }
- }
- if (ctx->ExecuteFlag) {
- CALL_ConvolutionParameteriv(ctx->Exec, (target, pname, params));
- }
-}
-
-
-static void GLAPIENTRY
-save_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_F, 3);
- if (n) {
- n[1].e = target;
- n[2].e = pname;
- n[3].f = param;
- }
- if (ctx->ExecuteFlag) {
- CALL_ConvolutionParameterf(ctx->Exec, (target, pname, param));
- }
-}
-
-
-static void GLAPIENTRY
-save_ConvolutionParameterfv(GLenum target, GLenum pname,
- const GLfloat *params)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_CONVOLUTION_PARAMETER_FV, 6);
- if (n) {
- n[1].e = target;
- n[2].e = pname;
- n[3].f = params[0];
- if (pname == GL_CONVOLUTION_BORDER_COLOR ||
- pname == GL_CONVOLUTION_FILTER_SCALE ||
- pname == GL_CONVOLUTION_FILTER_BIAS) {
- n[4].f = params[1];
- n[5].f = params[2];
- n[6].f = params[3];
- }
- else {
- n[4].f = n[5].f = n[6].f = 0.0F;
- }
- }
- if (ctx->ExecuteFlag) {
- CALL_ConvolutionParameterfv(ctx->Exec, (target, pname, params));
- }
-}
-
-
-static void GLAPIENTRY
save_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
{
GET_CURRENT_CONTEXT(ctx);
@@ -2314,14 +2063,15 @@ save_DrawPixels(GLsizei width, GLsizei height,
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_DRAW_PIXELS, 5);
+ n = alloc_instruction(ctx, OPCODE_DRAW_PIXELS, 4 + POINTER_DWORDS);
if (n) {
n[1].i = width;
n[2].i = height;
n[3].e = format;
n[4].e = type;
- n[5].data = unpack_image(ctx, 2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
+ save_pointer(&n[5],
+ unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack));
}
if (ctx->ExecuteFlag) {
CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels));
@@ -2530,27 +2280,6 @@ save_Hint(GLenum target, GLenum mode)
static void GLAPIENTRY
-save_Histogram(GLenum target, GLsizei width, GLenum internalFormat,
- GLboolean sink)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
-
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_HISTOGRAM, 4);
- if (n) {
- n[1].e = target;
- n[2].i = width;
- n[3].e = internalFormat;
- n[4].b = sink;
- }
- if (ctx->ExecuteFlag) {
- CALL_Histogram(ctx->Exec, (target, width, internalFormat, sink));
- }
-}
-
-
-static void GLAPIENTRY
save_IndexMask(GLuint mask)
{
GET_CURRENT_CONTEXT(ctx);
@@ -2890,7 +2619,7 @@ save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_MAP1, 6);
+ n = alloc_instruction(ctx, OPCODE_MAP1, 5 + POINTER_DWORDS);
if (n) {
GLfloat *pnts = _mesa_copy_map_points1d(target, stride, order, points);
n[1].e = target;
@@ -2898,7 +2627,7 @@ save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
n[3].f = (GLfloat) u2;
n[4].i = _mesa_evaluator_components(target); /* stride */
n[5].i = order;
- n[6].data = (void *) pnts;
+ save_pointer(&n[6], pnts);
}
if (ctx->ExecuteFlag) {
CALL_Map1d(ctx->Exec, (target, u1, u2, stride, order, points));
@@ -2912,7 +2641,7 @@ save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_MAP1, 6);
+ n = alloc_instruction(ctx, OPCODE_MAP1, 5 + POINTER_DWORDS);
if (n) {
GLfloat *pnts = _mesa_copy_map_points1f(target, stride, order, points);
n[1].e = target;
@@ -2920,7 +2649,7 @@ save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
n[3].f = u2;
n[4].i = _mesa_evaluator_components(target); /* stride */
n[5].i = order;
- n[6].data = (void *) pnts;
+ save_pointer(&n[6], pnts);
}
if (ctx->ExecuteFlag) {
CALL_Map1f(ctx->Exec, (target, u1, u2, stride, order, points));
@@ -2937,7 +2666,7 @@ save_Map2d(GLenum target,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_MAP2, 10);
+ n = alloc_instruction(ctx, OPCODE_MAP2, 9 + POINTER_DWORDS);
if (n) {
GLfloat *pnts = _mesa_copy_map_points2d(target, ustride, uorder,
vstride, vorder, points);
@@ -2951,7 +2680,7 @@ save_Map2d(GLenum target,
n[7].i = _mesa_evaluator_components(target); /*vstride */
n[8].i = uorder;
n[9].i = vorder;
- n[10].data = (void *) pnts;
+ save_pointer(&n[10], pnts);
}
if (ctx->ExecuteFlag) {
CALL_Map2d(ctx->Exec, (target,
@@ -2970,7 +2699,7 @@ save_Map2f(GLenum target,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_MAP2, 10);
+ n = alloc_instruction(ctx, OPCODE_MAP2, 9 + POINTER_DWORDS);
if (n) {
GLfloat *pnts = _mesa_copy_map_points2f(target, ustride, uorder,
vstride, vorder, points);
@@ -2984,7 +2713,7 @@ save_Map2f(GLenum target,
n[7].i = _mesa_evaluator_components(target); /*vstride */
n[8].i = uorder;
n[9].i = vorder;
- n[10].data = (void *) pnts;
+ save_pointer(&n[10], pnts);
}
if (ctx->ExecuteFlag) {
CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder,
@@ -3067,25 +2796,6 @@ save_MatrixMode(GLenum mode)
static void GLAPIENTRY
-save_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
-
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_MIN_MAX, 3);
- if (n) {
- n[1].e = target;
- n[2].e = internalFormat;
- n[3].b = sink;
- }
- if (ctx->ExecuteFlag) {
- CALL_Minmax(ctx->Exec, (target, internalFormat, sink));
- }
-}
-
-
-static void GLAPIENTRY
save_MultMatrixf(const GLfloat * m)
{
GET_CURRENT_CONTEXT(ctx);
@@ -3156,12 +2866,11 @@ save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_PIXEL_MAP, 3);
+ n = alloc_instruction(ctx, OPCODE_PIXEL_MAP, 2 + POINTER_DWORDS);
if (n) {
n[1].e = map;
n[2].i = mapsize;
- n[3].data = malloc(mapsize * sizeof(GLfloat));
- memcpy(n[3].data, (void *) values, mapsize * sizeof(GLfloat));
+ save_pointer(&n[3], memdup(values, mapsize * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_PixelMapfv(ctx->Exec, (map, mapsize, values));
@@ -3336,10 +3045,11 @@ save_PolygonStipple(const GLubyte * pattern)
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_POLYGON_STIPPLE, 1);
+ n = alloc_instruction(ctx, OPCODE_POLYGON_STIPPLE, POINTER_DWORDS);
if (n) {
- n[1].data = unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
- pattern, &ctx->Unpack);
+ save_pointer(&n[1],
+ unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
+ pattern, &ctx->Unpack));
}
if (ctx->ExecuteFlag) {
CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern));
@@ -3667,38 +3377,6 @@ save_ReadBuffer(GLenum mode)
static void GLAPIENTRY
-save_ResetHistogram(GLenum target)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_RESET_HISTOGRAM, 1);
- if (n) {
- n[1].e = target;
- }
- if (ctx->ExecuteFlag) {
- CALL_ResetHistogram(ctx->Exec, (target));
- }
-}
-
-
-static void GLAPIENTRY
-save_ResetMinmax(GLenum target)
-{
- GET_CURRENT_CONTEXT(ctx);
- Node *n;
- ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_RESET_MIN_MAX, 1);
- if (n) {
- n[1].e = target;
- }
- if (ctx->ExecuteFlag) {
- CALL_ResetMinmax(ctx->Exec, (target));
- }
-}
-
-
-static void GLAPIENTRY
save_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
GET_CURRENT_CONTEXT(ctx);
@@ -4140,7 +3818,7 @@ save_TexImage1D(GLenum target,
else {
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_TEX_IMAGE1D, 8);
+ n = alloc_instruction(ctx, OPCODE_TEX_IMAGE1D, 7 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4149,8 +3827,9 @@ save_TexImage1D(GLenum target,
n[5].i = border;
n[6].e = format;
n[7].e = type;
- n[8].data = unpack_image(ctx, 1, width, 1, 1, format, type,
- pixels, &ctx->Unpack);
+ save_pointer(&n[8],
+ unpack_image(ctx, 1, width, 1, 1, format, type,
+ pixels, &ctx->Unpack));
}
if (ctx->ExecuteFlag) {
CALL_TexImage1D(ctx->Exec, (target, level, components, width,
@@ -4175,7 +3854,7 @@ save_TexImage2D(GLenum target,
else {
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_TEX_IMAGE2D, 9);
+ n = alloc_instruction(ctx, OPCODE_TEX_IMAGE2D, 8 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4185,8 +3864,9 @@ save_TexImage2D(GLenum target,
n[6].i = border;
n[7].e = format;
n[8].e = type;
- n[9].data = unpack_image(ctx, 2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
+ save_pointer(&n[9],
+ unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack));
}
if (ctx->ExecuteFlag) {
CALL_TexImage2D(ctx->Exec, (target, level, components, width,
@@ -4213,7 +3893,7 @@ save_TexImage3D(GLenum target,
else {
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_TEX_IMAGE3D, 10);
+ n = alloc_instruction(ctx, OPCODE_TEX_IMAGE3D, 9 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4224,8 +3904,9 @@ save_TexImage3D(GLenum target,
n[7].i = border;
n[8].e = format;
n[9].e = type;
- n[10].data = unpack_image(ctx, 3, width, height, depth, format, type,
- pixels, &ctx->Unpack);
+ save_pointer(&n[10],
+ unpack_image(ctx, 3, width, height, depth, format, type,
+ pixels, &ctx->Unpack));
}
if (ctx->ExecuteFlag) {
CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width,
@@ -4246,7 +3927,7 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE1D, 7);
+ n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE1D, 6 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4254,8 +3935,9 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
n[4].i = (GLint) width;
n[5].e = format;
n[6].e = type;
- n[7].data = unpack_image(ctx, 1, width, 1, 1, format, type,
- pixels, &ctx->Unpack);
+ save_pointer(&n[7],
+ unpack_image(ctx, 1, width, 1, 1, format, type,
+ pixels, &ctx->Unpack));
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage1D(ctx->Exec, (target, level, xoffset, width,
@@ -4275,7 +3957,7 @@ save_TexSubImage2D(GLenum target, GLint level,
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE2D, 9);
+ n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE2D, 8 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4285,8 +3967,9 @@ save_TexSubImage2D(GLenum target, GLint level,
n[6].i = (GLint) height;
n[7].e = format;
n[8].e = type;
- n[9].data = unpack_image(ctx, 2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
+ save_pointer(&n[9],
+ unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack));
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
@@ -4306,7 +3989,7 @@ save_TexSubImage3D(GLenum target, GLint level,
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE3D, 11);
+ n = alloc_instruction(ctx, OPCODE_TEX_SUB_IMAGE3D, 10 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4318,8 +4001,9 @@ save_TexSubImage3D(GLenum target, GLint level,
n[8].i = (GLint) depth;
n[9].e = format;
n[10].e = type;
- n[11].data = unpack_image(ctx, 3, width, height, depth, format, type,
- pixels, &ctx->Unpack);
+ save_pointer(&n[11],
+ unpack_image(ctx, 3, width, height, depth, format, type,
+ pixels, &ctx->Unpack));
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage3D(ctx->Exec, (target, level,
@@ -4626,7 +4310,8 @@ save_CompressedTexImage1DARB(GLenum target, GLint level,
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 7);
+ n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D,
+ 6 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4634,7 +4319,8 @@ save_CompressedTexImage1DARB(GLenum target, GLint level,
n[4].i = (GLint) width;
n[5].i = border;
n[6].i = imageSize;
- n[7].data = copy_data(data, imageSize, "glCompressedTexImage1DARB");
+ save_pointer(&n[7],
+ copy_data(data, imageSize, "glCompressedTexImage1DARB"));
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexImage1D(ctx->Exec,
@@ -4662,7 +4348,8 @@ save_CompressedTexImage2DARB(GLenum target, GLint level,
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 8);
+ n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D,
+ 7 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4671,7 +4358,8 @@ save_CompressedTexImage2DARB(GLenum target, GLint level,
n[5].i = (GLint) height;
n[6].i = border;
n[7].i = imageSize;
- n[8].data = copy_data(data, imageSize, "glCompressedTexImage2DARB");
+ save_pointer(&n[8],
+ copy_data(data, imageSize, "glCompressedTexImage2DARB"));
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexImage2D(ctx->Exec,
@@ -4699,7 +4387,8 @@ save_CompressedTexImage3DARB(GLenum target, GLint level,
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 9);
+ n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D,
+ 8 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4709,7 +4398,8 @@ save_CompressedTexImage3DARB(GLenum target, GLint level,
n[6].i = (GLint) depth;
n[7].i = border;
n[8].i = imageSize;
- n[9].data = copy_data(data, imageSize, "glCompressedTexImage3DARB");
+ save_pointer(&n[9],
+ copy_data(data, imageSize, "glCompressedTexImage3DARB"));
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexImage3D(ctx->Exec,
@@ -4730,7 +4420,8 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 7);
+ n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D,
+ 6 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4738,7 +4429,8 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
n[4].i = (GLint) width;
n[5].e = format;
n[6].i = imageSize;
- n[7].data = copy_data(data, imageSize, "glCompressedTexSubImage1DARB");
+ save_pointer(&n[7],
+ copy_data(data, imageSize, "glCompressedTexSubImage1DARB"));
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexSubImage1D(ctx->Exec, (target, level, xoffset,
@@ -4758,7 +4450,8 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 9);
+ n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D,
+ 8 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4768,7 +4461,8 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
n[6].i = (GLint) height;
n[7].e = format;
n[8].i = imageSize;
- n[9].data = copy_data(data, imageSize, "glCompressedTexSubImage2DARB");
+ save_pointer(&n[9],
+ copy_data(data, imageSize, "glCompressedTexSubImage2DARB"));
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexSubImage2D(ctx->Exec,
@@ -4788,7 +4482,8 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 11);
+ n = alloc_instruction(ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D,
+ 10 + POINTER_DWORDS);
if (n) {
n[1].e = target;
n[2].i = level;
@@ -4800,7 +4495,8 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
n[8].i = (GLint) depth;
n[9].e = format;
n[10].i = imageSize;
- n[11].data = copy_data(data, imageSize, "glCompressedTexSubImage3DARB");
+ save_pointer(&n[11],
+ copy_data(data, imageSize, "glCompressedTexSubImage3DARB"));
}
if (ctx->ExecuteFlag) {
CALL_CompressedTexSubImage3D(ctx->Exec,
@@ -5098,7 +4794,7 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_PROGRAM_STRING_ARB, 4);
+ n = alloc_instruction(ctx, OPCODE_PROGRAM_STRING_ARB, 3 + POINTER_DWORDS);
if (n) {
GLubyte *programCopy = malloc(len);
if (!programCopy) {
@@ -5109,7 +4805,7 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
n[1].e = target;
n[2].e = format;
n[3].i = len;
- n[4].data = programCopy;
+ save_pointer(&n[4], programCopy);
}
if (ctx->ExecuteFlag) {
CALL_ProgramStringARB(ctx->Exec, (target, format, len, string));
@@ -6284,28 +5980,17 @@ save_Uniform4fARB(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
}
-/** Return copy of memory */
-static void *
-memdup(const void *src, GLsizei bytes)
-{
- void *b = bytes >= 0 ? malloc(bytes) : NULL;
- if (b)
- memcpy(b, src, bytes);
- return b;
-}
-
-
static void GLAPIENTRY
save_Uniform1fvARB(GLint location, GLsizei count, const GLfloat *v)
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_1FV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_1FV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 1 * sizeof(GLfloat));
+ save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_Uniform1fv(ctx->Exec, (location, count, v));
@@ -6318,11 +6003,11 @@ save_Uniform2fvARB(GLint location, GLsizei count, const GLfloat *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_2FV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_2FV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 2 * sizeof(GLfloat));
+ save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_Uniform2fv(ctx->Exec, (location, count, v));
@@ -6335,11 +6020,11 @@ save_Uniform3fvARB(GLint location, GLsizei count, const GLfloat *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_3FV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_3FV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 3 * sizeof(GLfloat));
+ save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_Uniform3fv(ctx->Exec, (location, count, v));
@@ -6352,11 +6037,11 @@ save_Uniform4fvARB(GLint location, GLsizei count, const GLfloat *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_4FV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_4FV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 4 * sizeof(GLfloat));
+ save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_Uniform4fv(ctx->Exec, (location, count, v));
@@ -6442,11 +6127,11 @@ save_Uniform1ivARB(GLint location, GLsizei count, const GLint *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_1IV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_1IV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 1 * sizeof(GLint));
+ save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLint)));
}
if (ctx->ExecuteFlag) {
CALL_Uniform1iv(ctx->Exec, (location, count, v));
@@ -6459,11 +6144,11 @@ save_Uniform2ivARB(GLint location, GLsizei count, const GLint *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_2IV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_2IV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 2 * sizeof(GLint));
+ save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLint)));
}
if (ctx->ExecuteFlag) {
CALL_Uniform2iv(ctx->Exec, (location, count, v));
@@ -6476,11 +6161,11 @@ save_Uniform3ivARB(GLint location, GLsizei count, const GLint *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_3IV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_3IV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 3 * sizeof(GLint));
+ save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLint)));
}
if (ctx->ExecuteFlag) {
CALL_Uniform3iv(ctx->Exec, (location, count, v));
@@ -6493,11 +6178,11 @@ save_Uniform4ivARB(GLint location, GLsizei count, const GLint *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_4IV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_4IV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 4 * sizeof(GLfloat));
+ save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_Uniform4iv(ctx->Exec, (location, count, v));
@@ -6584,11 +6269,11 @@ save_Uniform1uiv(GLint location, GLsizei count, const GLuint *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_1UIV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_1UIV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 1 * sizeof(*v));
+ save_pointer(&n[3], memdup(v, count * 1 * sizeof(*v)));
}
if (ctx->ExecuteFlag) {
/*CALL_Uniform1uiv(ctx->Exec, (location, count, v));*/
@@ -6601,11 +6286,11 @@ save_Uniform2uiv(GLint location, GLsizei count, const GLuint *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_2UIV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_2UIV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 2 * sizeof(*v));
+ save_pointer(&n[3], memdup(v, count * 2 * sizeof(*v)));
}
if (ctx->ExecuteFlag) {
/*CALL_Uniform2uiv(ctx->Exec, (location, count, v));*/
@@ -6618,11 +6303,11 @@ save_Uniform3uiv(GLint location, GLsizei count, const GLuint *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_3UIV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_3UIV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 3 * sizeof(*v));
+ save_pointer(&n[3], memdup(v, count * 3 * sizeof(*v)));
}
if (ctx->ExecuteFlag) {
/*CALL_Uniform3uiv(ctx->Exec, (location, count, v));*/
@@ -6635,11 +6320,11 @@ save_Uniform4uiv(GLint location, GLsizei count, const GLuint *v)
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_4UIV, 3);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_4UIV, 2 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
- n[3].data = memdup(v, count * 4 * sizeof(*v));
+ save_pointer(&n[3], memdup(v, count * 4 * sizeof(*v)));
}
if (ctx->ExecuteFlag) {
/*CALL_Uniform4uiv(ctx->Exec, (location, count, v));*/
@@ -6655,12 +6340,12 @@ save_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX22, 4);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX22, 3 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
n[3].b = transpose;
- n[4].data = memdup(m, count * 2 * 2 * sizeof(GLfloat));
+ save_pointer(&n[4], memdup(m, count * 2 * 2 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_UniformMatrix2fv(ctx->Exec, (location, count, transpose, m));
@@ -6674,12 +6359,12 @@ save_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX33, 4);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX33, 3 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
n[3].b = transpose;
- n[4].data = memdup(m, count * 3 * 3 * sizeof(GLfloat));
+ save_pointer(&n[4], memdup(m, count * 3 * 3 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_UniformMatrix3fv(ctx->Exec, (location, count, transpose, m));
@@ -6693,12 +6378,12 @@ save_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX44, 4);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX44, 3 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
n[3].b = transpose;
- n[4].data = memdup(m, count * 4 * 4 * sizeof(GLfloat));
+ save_pointer(&n[4], memdup(m, count * 4 * 4 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_UniformMatrix4fv(ctx->Exec, (location, count, transpose, m));
@@ -6713,12 +6398,12 @@ save_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX23, 4);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX23, 3 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
n[3].b = transpose;
- n[4].data = memdup(m, count * 2 * 3 * sizeof(GLfloat));
+ save_pointer(&n[4], memdup(m, count * 2 * 3 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_UniformMatrix2x3fv(ctx->Exec, (location, count, transpose, m));
@@ -6732,12 +6417,12 @@ save_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX32, 4);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX32, 3 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
n[3].b = transpose;
- n[4].data = memdup(m, count * 3 * 2 * sizeof(GLfloat));
+ save_pointer(&n[4], memdup(m, count * 3 * 2 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_UniformMatrix3x2fv(ctx->Exec, (location, count, transpose, m));
@@ -6752,12 +6437,12 @@ save_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX24, 4);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX24, 3 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
n[3].b = transpose;
- n[4].data = memdup(m, count * 2 * 4 * sizeof(GLfloat));
+ save_pointer(&n[4], memdup(m, count * 2 * 4 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_UniformMatrix2x4fv(ctx->Exec, (location, count, transpose, m));
@@ -6771,12 +6456,12 @@ save_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX42, 4);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX42, 3 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
n[3].b = transpose;
- n[4].data = memdup(m, count * 4 * 2 * sizeof(GLfloat));
+ save_pointer(&n[4], memdup(m, count * 4 * 2 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_UniformMatrix4x2fv(ctx->Exec, (location, count, transpose, m));
@@ -6791,12 +6476,12 @@ save_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX34, 4);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX34, 3 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
n[3].b = transpose;
- n[4].data = memdup(m, count * 3 * 4 * sizeof(GLfloat));
+ save_pointer(&n[4], memdup(m, count * 3 * 4 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_UniformMatrix3x4fv(ctx->Exec, (location, count, transpose, m));
@@ -6810,12 +6495,12 @@ save_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
GET_CURRENT_CONTEXT(ctx);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
- n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX43, 4);
+ n = alloc_instruction(ctx, OPCODE_UNIFORM_MATRIX43, 3 + POINTER_DWORDS);
if (n) {
n[1].i = location;
n[2].i = count;
n[3].b = transpose;
- n[4].data = memdup(m, count * 4 * 3 * sizeof(GLfloat));
+ save_pointer(&n[4], memdup(m, count * 4 * 3 * sizeof(GLfloat)));
}
if (ctx->ExecuteFlag) {
CALL_UniformMatrix4x3fv(ctx->Exec, (location, count, transpose, m));
@@ -7185,10 +6870,10 @@ save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
if (n) {
union uint64_pair p;
p.uint64 = timeout;
- n[1].data = sync;
- n[2].e = flags;
- n[3].ui = p.uint32[0];
- n[4].ui = p.uint32[1];
+ n[1].bf = flags;
+ n[2].ui = p.uint32[0];
+ n[3].ui = p.uint32[1];
+ save_pointer(&n[4], sync);
}
if (ctx->ExecuteFlag) {
CALL_WaitSync(ctx->Exec, (sync, flags, timeout));
@@ -7252,10 +6937,14 @@ static void
save_error(struct gl_context *ctx, GLenum error, const char *s)
{
Node *n;
- n = alloc_instruction(ctx, OPCODE_ERROR, 2);
+ n = alloc_instruction(ctx, OPCODE_ERROR, 1 + POINTER_DWORDS);
if (n) {
n[1].e = error;
- n[2].data = (void *) s;
+ save_pointer(&n[2], (void *) s);
+ /* note: the data/string here doesn't have to be freed in
+ * _mesa_delete_list() since the string is never dynamically
+ * allocated.
+ */
}
}
@@ -7336,7 +7025,7 @@ execute_list(struct gl_context *ctx, GLuint list)
else {
switch (opcode) {
case OPCODE_ERROR:
- _mesa_error(ctx, n[1].e, "%s", (const char *) n[2].data);
+ _mesa_error(ctx, n[1].e, "%s", (const char *) get_pointer(&n[2]));
break;
case OPCODE_ACCUM:
CALL_Accum(ctx->Exec, (n[1].e, n[2].f));
@@ -7353,7 +7042,7 @@ execute_list(struct gl_context *ctx, GLuint list)
ctx->Unpack = ctx->DefaultPacking;
CALL_Bitmap(ctx->Exec, ((GLsizei) n[1].i, (GLsizei) n[2].i,
n[3].f, n[4].f, n[5].f, n[6].f,
- (const GLubyte *) n[7].data));
+ get_pointer(&n[7])));
ctx->Unpack = save; /* restore */
}
break;
@@ -7478,102 +7167,6 @@ execute_list(struct gl_context *ctx, GLuint list)
case OPCODE_COLOR_MATERIAL:
CALL_ColorMaterial(ctx->Exec, (n[1].e, n[2].e));
break;
- case OPCODE_COLOR_TABLE:
- {
- const struct gl_pixelstore_attrib save = ctx->Unpack;
- ctx->Unpack = ctx->DefaultPacking;
- CALL_ColorTable(ctx->Exec, (n[1].e, n[2].e, n[3].i, n[4].e,
- n[5].e, n[6].data));
- ctx->Unpack = save; /* restore */
- }
- break;
- case OPCODE_COLOR_TABLE_PARAMETER_FV:
- {
- GLfloat params[4];
- params[0] = n[3].f;
- params[1] = n[4].f;
- params[2] = n[5].f;
- params[3] = n[6].f;
- CALL_ColorTableParameterfv(ctx->Exec,
- (n[1].e, n[2].e, params));
- }
- break;
- case OPCODE_COLOR_TABLE_PARAMETER_IV:
- {
- GLint params[4];
- params[0] = n[3].i;
- params[1] = n[4].i;
- params[2] = n[5].i;
- params[3] = n[6].i;
- CALL_ColorTableParameteriv(ctx->Exec,
- (n[1].e, n[2].e, params));
- }
- break;
- case OPCODE_COLOR_SUB_TABLE:
- {
- const struct gl_pixelstore_attrib save = ctx->Unpack;
- ctx->Unpack = ctx->DefaultPacking;
- CALL_ColorSubTable(ctx->Exec, (n[1].e, n[2].i, n[3].i,
- n[4].e, n[5].e, n[6].data));
- ctx->Unpack = save; /* restore */
- }
- break;
- case OPCODE_CONVOLUTION_FILTER_1D:
- {
- const struct gl_pixelstore_attrib save = ctx->Unpack;
- ctx->Unpack = ctx->DefaultPacking;
- CALL_ConvolutionFilter1D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
- n[4].e, n[5].e,
- n[6].data));
- ctx->Unpack = save; /* restore */
- }
- break;
- case OPCODE_CONVOLUTION_FILTER_2D:
- {
- const struct gl_pixelstore_attrib save = ctx->Unpack;
- ctx->Unpack = ctx->DefaultPacking;
- CALL_ConvolutionFilter2D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
- n[4].i, n[5].e, n[6].e,
- n[7].data));
- ctx->Unpack = save; /* restore */
- }
- break;
- case OPCODE_CONVOLUTION_PARAMETER_I:
- CALL_ConvolutionParameteri(ctx->Exec, (n[1].e, n[2].e, n[3].i));
- break;
- case OPCODE_CONVOLUTION_PARAMETER_IV:
- {
- GLint params[4];
- params[0] = n[3].i;
- params[1] = n[4].i;
- params[2] = n[5].i;
- params[3] = n[6].i;
- CALL_ConvolutionParameteriv(ctx->Exec,
- (n[1].e, n[2].e, params));
- }
- break;
- case OPCODE_CONVOLUTION_PARAMETER_F:
- CALL_ConvolutionParameterf(ctx->Exec, (n[1].e, n[2].e, n[3].f));
- break;
- case OPCODE_CONVOLUTION_PARAMETER_FV:
- {
- GLfloat params[4];
- params[0] = n[3].f;
- params[1] = n[4].f;
- params[2] = n[5].f;
- params[3] = n[6].f;
- CALL_ConvolutionParameterfv(ctx->Exec,
- (n[1].e, n[2].e, params));
- }
- break;
- case OPCODE_COPY_COLOR_SUB_TABLE:
- CALL_CopyColorSubTable(ctx->Exec, (n[1].e, n[2].i,
- n[3].i, n[4].i, n[5].i));
- break;
- case OPCODE_COPY_COLOR_TABLE:
- CALL_CopyColorSubTable(ctx->Exec, (n[1].e, n[2].i,
- n[3].i, n[4].i, n[5].i));
- break;
case OPCODE_COPY_PIXELS:
CALL_CopyPixels(ctx->Exec, (n[1].i, n[2].i,
(GLsizei) n[3].i, (GLsizei) n[4].i,
@@ -7628,7 +7221,7 @@ execute_list(struct gl_context *ctx, GLuint list)
const struct gl_pixelstore_attrib save = ctx->Unpack;
ctx->Unpack = ctx->DefaultPacking;
CALL_DrawPixels(ctx->Exec, (n[1].i, n[2].i, n[3].e, n[4].e,
- n[5].data));
+ get_pointer(&n[5])));
ctx->Unpack = save; /* restore */
}
break;
@@ -7665,9 +7258,6 @@ execute_list(struct gl_context *ctx, GLuint list)
case OPCODE_HINT:
CALL_Hint(ctx->Exec, (n[1].e, n[2].e));
break;
- case OPCODE_HISTOGRAM:
- CALL_Histogram(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].b));
- break;
case OPCODE_INDEX_MASK:
CALL_IndexMask(ctx->Exec, (n[1].ui));
break;
@@ -7733,7 +7323,7 @@ execute_list(struct gl_context *ctx, GLuint list)
GLfloat u1 = n[2].f;
GLfloat u2 = n[3].f;
CALL_Map1f(ctx->Exec, (target, u1, u2, ustride, uorder,
- (GLfloat *) n[6].data));
+ (GLfloat *) get_pointer(&n[6])));
}
break;
case OPCODE_MAP2:
@@ -7749,7 +7339,7 @@ execute_list(struct gl_context *ctx, GLuint list)
GLint vorder = n[9].i;
CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder,
v1, v2, vstride, vorder,
- (GLfloat *) n[10].data));
+ (GLfloat *) get_pointer(&n[10])));
}
break;
case OPCODE_MAPGRID1:
@@ -7762,9 +7352,6 @@ execute_list(struct gl_context *ctx, GLuint list)
case OPCODE_MATRIX_MODE:
CALL_MatrixMode(ctx->Exec, (n[1].e));
break;
- case OPCODE_MIN_MAX:
- CALL_Minmax(ctx->Exec, (n[1].e, n[2].e, n[3].b));
- break;
case OPCODE_MULT_MATRIX:
if (sizeof(Node) == sizeof(GLfloat)) {
CALL_MultMatrixf(ctx->Exec, (&n[1].f));
@@ -7787,7 +7374,7 @@ execute_list(struct gl_context *ctx, GLuint list)
break;
case OPCODE_PIXEL_MAP:
CALL_PixelMapfv(ctx->Exec,
- (n[1].e, n[2].i, (GLfloat *) n[3].data));
+ (n[1].e, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_PIXEL_TRANSFER:
CALL_PixelTransferf(ctx->Exec, (n[1].e, n[2].f));
@@ -7814,7 +7401,7 @@ execute_list(struct gl_context *ctx, GLuint list)
{
const struct gl_pixelstore_attrib save = ctx->Unpack;
ctx->Unpack = ctx->DefaultPacking;
- CALL_PolygonStipple(ctx->Exec, ((GLubyte *) n[1].data));
+ CALL_PolygonStipple(ctx->Exec, (get_pointer(&n[1])));
ctx->Unpack = save; /* restore */
}
break;
@@ -7848,12 +7435,6 @@ execute_list(struct gl_context *ctx, GLuint list)
case OPCODE_READ_BUFFER:
CALL_ReadBuffer(ctx->Exec, (n[1].e));
break;
- case OPCODE_RESET_HISTOGRAM:
- CALL_ResetHistogram(ctx->Exec, (n[1].e));
- break;
- case OPCODE_RESET_MIN_MAX:
- CALL_ResetMinmax(ctx->Exec, (n[1].e));
- break;
case OPCODE_ROTATE:
CALL_Rotatef(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f));
break;
@@ -7930,7 +7511,7 @@ execute_list(struct gl_context *ctx, GLuint list)
n[5].e, /* border */
n[6].e, /* format */
n[7].e, /* type */
- n[8].data));
+ get_pointer(&n[8])));
ctx->Unpack = save; /* restore */
}
break;
@@ -7946,7 +7527,7 @@ execute_list(struct gl_context *ctx, GLuint list)
n[6].e, /* border */
n[7].e, /* format */
n[8].e, /* type */
- n[9].data));
+ get_pointer(&n[9])));
ctx->Unpack = save; /* restore */
}
break;
@@ -7963,7 +7544,7 @@ execute_list(struct gl_context *ctx, GLuint list)
n[7].e, /* border */
n[8].e, /* format */
n[9].e, /* type */
- n[10].data));
+ get_pointer(&n[10])));
ctx->Unpack = save; /* restore */
}
break;
@@ -7973,7 +7554,7 @@ execute_list(struct gl_context *ctx, GLuint list)
ctx->Unpack = ctx->DefaultPacking;
CALL_TexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
n[4].i, n[5].e,
- n[6].e, n[7].data));
+ n[6].e, get_pointer(&n[7])));
ctx->Unpack = save; /* restore */
}
break;
@@ -7984,7 +7565,7 @@ execute_list(struct gl_context *ctx, GLuint list)
CALL_TexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
n[4].i, n[5].e,
n[6].i, n[7].e, n[8].e,
- n[9].data));
+ get_pointer(&n[9])));
ctx->Unpack = save; /* restore */
}
break;
@@ -7995,7 +7576,7 @@ execute_list(struct gl_context *ctx, GLuint list)
CALL_TexSubImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].i,
n[4].i, n[5].i, n[6].i, n[7].i,
n[8].i, n[9].e, n[10].e,
- n[11].data));
+ get_pointer(&n[11])));
ctx->Unpack = save; /* restore */
}
break;
@@ -8014,36 +7595,38 @@ execute_list(struct gl_context *ctx, GLuint list)
break;
case OPCODE_COMPRESSED_TEX_IMAGE_1D: /* GL_ARB_texture_compression */
CALL_CompressedTexImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].e,
- n[4].i, n[5].i, n[6].i,
- n[7].data));
+ n[4].i, n[5].i, n[6].i,
+ get_pointer(&n[7])));
break;
case OPCODE_COMPRESSED_TEX_IMAGE_2D: /* GL_ARB_texture_compression */
CALL_CompressedTexImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].e,
- n[4].i, n[5].i, n[6].i,
- n[7].i, n[8].data));
+ n[4].i, n[5].i, n[6].i,
+ n[7].i, get_pointer(&n[8])));
break;
case OPCODE_COMPRESSED_TEX_IMAGE_3D: /* GL_ARB_texture_compression */
CALL_CompressedTexImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].e,
- n[4].i, n[5].i, n[6].i,
- n[7].i, n[8].i,
- n[9].data));
+ n[4].i, n[5].i, n[6].i,
+ n[7].i, n[8].i,
+ get_pointer(&n[9])));
break;
case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: /* GL_ARB_texture_compress */
CALL_CompressedTexSubImage1D(ctx->Exec,
(n[1].e, n[2].i, n[3].i, n[4].i,
- n[5].e, n[6].i, n[7].data));
+ n[5].e, n[6].i,
+ get_pointer(&n[7])));
break;
case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: /* GL_ARB_texture_compress */
CALL_CompressedTexSubImage2D(ctx->Exec,
(n[1].e, n[2].i, n[3].i, n[4].i,
n[5].i, n[6].i, n[7].e, n[8].i,
- n[9].data));
+ get_pointer(&n[9])));
break;
case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: /* GL_ARB_texture_compress */
CALL_CompressedTexSubImage3D(ctx->Exec,
(n[1].e, n[2].i, n[3].i, n[4].i,
n[5].i, n[6].i, n[7].i, n[8].i,
- n[9].e, n[10].i, n[11].data));
+ n[9].e, n[10].i,
+ get_pointer(&n[11])));
break;
case OPCODE_SAMPLE_COVERAGE: /* GL_ARB_multisample */
CALL_SampleCoverage(ctx->Exec, (n[1].f, n[2].b));
@@ -8067,7 +7650,8 @@ execute_list(struct gl_context *ctx, GLuint list)
break;
case OPCODE_PROGRAM_STRING_ARB:
CALL_ProgramStringARB(ctx->Exec,
- (n[1].e, n[2].e, n[3].i, n[4].data));
+ (n[1].e, n[2].e, n[3].i,
+ get_pointer(&n[4])));
break;
case OPCODE_PROGRAM_ENV_PARAMETER_ARB:
CALL_ProgramEnvParameter4fARB(ctx->Exec, (n[1].e, n[2].ui, n[3].f,
@@ -8126,16 +7710,16 @@ execute_list(struct gl_context *ctx, GLuint list)
(n[1].i, n[2].f, n[3].f, n[4].f, n[5].f));
break;
case OPCODE_UNIFORM_1FV:
- CALL_Uniform1fv(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ CALL_Uniform1fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_2FV:
- CALL_Uniform2fv(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ CALL_Uniform2fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_3FV:
- CALL_Uniform3fv(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ CALL_Uniform3fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_4FV:
- CALL_Uniform4fv(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ CALL_Uniform4fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_1I:
CALL_Uniform1i(ctx->Exec, (n[1].i, n[2].i));
@@ -8151,16 +7735,16 @@ execute_list(struct gl_context *ctx, GLuint list)
(n[1].i, n[2].i, n[3].i, n[4].i, n[5].i));
break;
case OPCODE_UNIFORM_1IV:
- CALL_Uniform1iv(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ CALL_Uniform1iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_2IV:
- CALL_Uniform2iv(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ CALL_Uniform2iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_3IV:
- CALL_Uniform3iv(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ CALL_Uniform3iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_4IV:
- CALL_Uniform4iv(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ CALL_Uniform4iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3])));
break;
case OPCODE_UNIFORM_1UI:
/*CALL_Uniform1uiARB(ctx->Exec, (n[1].i, n[2].i));*/
@@ -8177,52 +7761,56 @@ execute_list(struct gl_context *ctx, GLuint list)
*/
break;
case OPCODE_UNIFORM_1UIV:
- /*CALL_Uniform1uivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));*/
+ /*CALL_Uniform1uivARB(ctx->Exec, (n[1].i, n[2].i,
+ get_pointer(&n[3])));*/
break;
case OPCODE_UNIFORM_2UIV:
- /*CALL_Uniform2uivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));*/
+ /*CALL_Uniform2uivARB(ctx->Exec, (n[1].i, n[2].i,
+ get_pointer(&n[3])));*/
break;
case OPCODE_UNIFORM_3UIV:
- /*CALL_Uniform3uivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));*/
+ /*CALL_Uniform3uivARB(ctx->Exec, (n[1].i, n[2].i,
+ get_pointer(&n[3])));*/
break;
case OPCODE_UNIFORM_4UIV:
- /*CALL_Uniform4uivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));*/
+ /*CALL_Uniform4uivARB(ctx->Exec, (n[1].i, n[2].i,
+ get_pointer(&n[3])));*/
break;
case OPCODE_UNIFORM_MATRIX22:
CALL_UniformMatrix2fv(ctx->Exec,
- (n[1].i, n[2].i, n[3].b, n[4].data));
+ (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
break;
case OPCODE_UNIFORM_MATRIX33:
CALL_UniformMatrix3fv(ctx->Exec,
- (n[1].i, n[2].i, n[3].b, n[4].data));
+ (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
break;
case OPCODE_UNIFORM_MATRIX44:
CALL_UniformMatrix4fv(ctx->Exec,
- (n[1].i, n[2].i, n[3].b, n[4].data));
+ (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
break;
case OPCODE_UNIFORM_MATRIX23:
CALL_UniformMatrix2x3fv(ctx->Exec,
- (n[1].i, n[2].i, n[3].b, n[4].data));
+ (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
break;
case OPCODE_UNIFORM_MATRIX32:
CALL_UniformMatrix3x2fv(ctx->Exec,
- (n[1].i, n[2].i, n[3].b, n[4].data));
+ (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
break;
case OPCODE_UNIFORM_MATRIX24:
CALL_UniformMatrix2x4fv(ctx->Exec,
- (n[1].i, n[2].i, n[3].b, n[4].data));
+ (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
break;
case OPCODE_UNIFORM_MATRIX42:
CALL_UniformMatrix4x2fv(ctx->Exec,
- (n[1].i, n[2].i, n[3].b, n[4].data));
+ (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
break;
case OPCODE_UNIFORM_MATRIX34:
CALL_UniformMatrix3x4fv(ctx->Exec,
- (n[1].i, n[2].i, n[3].b, n[4].data));
+ (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
break;
case OPCODE_UNIFORM_MATRIX43:
CALL_UniformMatrix4x3fv(ctx->Exec,
- (n[1].i, n[2].i, n[3].b, n[4].data));
+ (n[1].i, n[2].i, n[3].b, get_pointer(&n[4])));
break;
case OPCODE_CLAMP_COLOR:
@@ -8476,9 +8064,10 @@ execute_list(struct gl_context *ctx, GLuint list)
case OPCODE_WAIT_SYNC:
{
union uint64_pair p;
- p.uint32[0] = n[3].ui;
- p.uint32[1] = n[4].ui;
- CALL_WaitSync(ctx->Exec, (n[1].data, n[2].bf, p.uint64));
+ p.uint32[0] = n[2].ui;
+ p.uint32[1] = n[3].ui;
+ CALL_WaitSync(ctx->Exec,
+ (get_pointer(&n[4]), n[1].bf, p.uint64));
}
break;
@@ -8495,7 +8084,7 @@ execute_list(struct gl_context *ctx, GLuint list)
break;
case OPCODE_CONTINUE:
- n = (Node *) n[1].next;
+ n = (Node *) get_pointer(&n[1]);
break;
case OPCODE_END_OF_LIST:
done = GL_TRUE;
@@ -8684,6 +8273,8 @@ _mesa_EndList(void)
(void) alloc_instruction(ctx, OPCODE_END_OF_LIST, 0);
+ trim_list(ctx);
+
/* Destroy old list, if any */
destroy_list(ctx, ctx->ListState.CurrentList->Name);
@@ -8697,6 +8288,8 @@ _mesa_EndList(void)
mesa_print_display_list(ctx->ListState.CurrentList->Name);
ctx->ListState.CurrentList = NULL;
+ ctx->ListState.CurrentBlock = NULL;
+ ctx->ListState.CurrentPos = 0;
ctx->ExecuteFlag = GL_TRUE;
ctx->CompileFlag = GL_FALSE;
@@ -8998,22 +8591,6 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
/* Not all are supported */
SET_BlendColor(table, save_BlendColor);
SET_BlendEquation(table, save_BlendEquation);
- SET_ColorSubTable(table, save_ColorSubTable);
- SET_ColorTable(table, save_ColorTable);
- SET_ColorTableParameterfv(table, save_ColorTableParameterfv);
- SET_ColorTableParameteriv(table, save_ColorTableParameteriv);
- SET_ConvolutionFilter1D(table, save_ConvolutionFilter1D);
- SET_ConvolutionFilter2D(table, save_ConvolutionFilter2D);
- SET_ConvolutionParameterf(table, save_ConvolutionParameterf);
- SET_ConvolutionParameterfv(table, save_ConvolutionParameterfv);
- SET_ConvolutionParameteri(table, save_ConvolutionParameteri);
- SET_ConvolutionParameteriv(table, save_ConvolutionParameteriv);
- SET_CopyColorSubTable(table, save_CopyColorSubTable);
- SET_CopyColorTable(table, save_CopyColorTable);
- SET_Histogram(table, save_Histogram);
- SET_Minmax(table, save_Minmax);
- SET_ResetHistogram(table, save_ResetHistogram);
- SET_ResetMinmax(table, save_ResetMinmax);
/* 2. GL_EXT_blend_color */
#if 0
@@ -9030,12 +8607,6 @@ _mesa_initialize_save_table(const struct gl_context *ctx)
SET_TexSubImage3DEXT(table, save_TexSubImage3D);
#endif
- /* 14. GL_SGI_color_table */
-#if 0
- SET_ColorTableSGI(table, save_ColorTable);
- SET_ColorSubTableSGI(table, save_ColorSubTable);
-#endif
-
/* 37. GL_EXT_blend_minmax */
#if 0
SET_BlendEquationEXT(table, save_BlendEquationEXT);
@@ -9332,7 +8903,8 @@ print_list(struct gl_context *ctx, GLuint list)
break;
case OPCODE_BITMAP:
printf("Bitmap %d %d %g %g %g %g %p\n", n[1].i, n[2].i,
- n[3].f, n[4].f, n[5].f, n[6].f, (void *) n[7].data);
+ n[3].f, n[4].f, n[5].f, n[6].f,
+ get_pointer(&n[7]));
break;
case OPCODE_CALL_LIST:
printf("CallList %d\n", (int) n[1].ui);
@@ -9341,16 +8913,6 @@ print_list(struct gl_context *ctx, GLuint list)
printf("CallList %d + offset %u = %u\n", (int) n[1].ui,
ctx->List.ListBase, ctx->List.ListBase + n[1].ui);
break;
- case OPCODE_COLOR_TABLE_PARAMETER_FV:
- printf("ColorTableParameterfv %s %s %f %f %f %f\n",
- enum_string(n[1].e), enum_string(n[2].e),
- n[3].f, n[4].f, n[5].f, n[6].f);
- break;
- case OPCODE_COLOR_TABLE_PARAMETER_IV:
- printf("ColorTableParameteriv %s %s %d %d %d %d\n",
- enum_string(n[1].e), enum_string(n[2].e),
- n[3].i, n[4].i, n[5].i, n[6].i);
- break;
case OPCODE_DISABLE:
printf("Disable %s\n", enum_string(n[1].e));
break;
@@ -9525,12 +9087,12 @@ print_list(struct gl_context *ctx, GLuint list)
* meta opcodes/commands
*/
case OPCODE_ERROR:
- printf("Error: %s %s\n",
- enum_string(n[1].e), (const char *) n[2].data);
+ printf("Error: %s %s\n", enum_string(n[1].e),
+ (const char *) get_pointer(&n[2]));
break;
case OPCODE_CONTINUE:
printf("DISPLAY-LIST-CONTINUE\n");
- n = (Node *) n[1].next;
+ n = (Node *) get_pointer(&n[1]);
break;
case OPCODE_END_OF_LIST:
printf("END-LIST %u\n", list);
diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c
index c047f5df2..bb4a23c91 100644
--- a/mesalib/src/mesa/main/enable.c
+++ b/mesalib/src/mesa/main/enable.c
@@ -934,25 +934,6 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state)
ctx->ATIFragmentShader.Enabled = state;
break;
- /* GL_MESA_texture_array */
- case GL_TEXTURE_1D_ARRAY_EXT:
- if (ctx->API != API_OPENGL_COMPAT)
- goto invalid_enum_error;
- CHECK_EXTENSION(MESA_texture_array, cap);
- if (!enable_texture(ctx, state, TEXTURE_1D_ARRAY_BIT)) {
- return;
- }
- break;
-
- case GL_TEXTURE_2D_ARRAY_EXT:
- if (ctx->API != API_OPENGL_COMPAT)
- goto invalid_enum_error;
- CHECK_EXTENSION(MESA_texture_array, cap);
- if (!enable_texture(ctx, state, TEXTURE_2D_ARRAY_BIT)) {
- return;
- }
- break;
-
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
if (!_mesa_is_desktop_gl(ctx))
goto invalid_enum_error;
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 42da9057c..f0e1858e4 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -82,6 +82,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_ES3_compatibility", o(ARB_ES3_compatibility), GL, 2012 },
{ "GL_ARB_base_instance", o(ARB_base_instance), GL, 2011 },
{ "GL_ARB_blend_func_extended", o(ARB_blend_func_extended), GL, 2009 },
+ { "GL_ARB_clear_buffer_object", o(dummy_true), GL, 2012 },
{ "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), GL, 2004 },
{ "GL_ARB_copy_buffer", o(dummy_true), GL, 2008 },
{ "GL_ARB_conservative_depth", o(ARB_conservative_depth), GL, 2011 },
@@ -158,6 +159,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_texture_rg", o(ARB_texture_rg), GL, 2008 },
{ "GL_ARB_texture_storage", o(dummy_true), GL, 2011 },
{ "GL_ARB_texture_storage_multisample", o(ARB_texture_multisample), GL, 2012 },
+ { "GL_ARB_texture_view", o(ARB_texture_view), GL, 2012 },
{ "GL_ARB_texture_swizzle", o(EXT_texture_swizzle), GL, 2008 },
{ "GL_ARB_timer_query", o(ARB_timer_query), GL, 2010 },
{ "GL_ARB_transform_feedback2", o(ARB_transform_feedback2), GL, 2010 },
@@ -199,7 +201,7 @@ static const struct extension extension_table[] = {
{ "GL_EXT_gpu_shader4", o(EXT_gpu_shader4), GL, 2006 },
{ "GL_EXT_map_buffer_range", o(ARB_map_buffer_range), ES1 | ES2, 2012 },
{ "GL_EXT_multi_draw_arrays", o(dummy_true), GLL | ES1 | ES2, 1999 },
- { "GL_EXT_packed_depth_stencil", o(EXT_packed_depth_stencil), GL, 2005 },
+ { "GL_EXT_packed_depth_stencil", o(dummy_true), GL, 2005 },
{ "GL_EXT_packed_float", o(EXT_packed_float), GL, 2004 },
{ "GL_EXT_packed_pixels", o(dummy_true), GLL, 1997 },
{ "GL_EXT_pixel_buffer_object", o(EXT_pixel_buffer_object), GL, 2004 },
@@ -272,7 +274,7 @@ static const struct extension extension_table[] = {
{ "GL_OES_framebuffer_object", o(dummy_true), ES1, 2005 },
{ "GL_OES_get_program_binary", o(dummy_true), ES2, 2008 },
{ "GL_OES_mapbuffer", o(dummy_true), ES1 | ES2, 2005 },
- { "GL_OES_packed_depth_stencil", o(EXT_packed_depth_stencil), ES1 | ES2, 2007 },
+ { "GL_OES_packed_depth_stencil", o(dummy_true), ES1 | ES2, 2007 },
{ "GL_OES_point_size_array", o(dummy_true), ES1, 2004 },
{ "GL_OES_point_sprite", o(ARB_point_sprite), ES1, 2004 },
{ "GL_OES_query_matrix", o(dummy_true), ES1, 2003 },
@@ -302,7 +304,7 @@ static const struct extension extension_table[] = {
{ "GL_AMD_performance_monitor", o(AMD_performance_monitor), GL, 2007 },
{ "GL_AMD_seamless_cubemap_per_texture", o(AMD_seamless_cubemap_per_texture), GL, 2009 },
{ "GL_AMD_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 },
- { "GL_AMD_vertex_shader_layer", o(AMD_vertex_shader_layer), GL, 2012 },
+ { "GL_AMD_vertex_shader_layer", o(AMD_vertex_shader_layer), GLC, 2012 },
{ "GL_APPLE_object_purgeable", o(APPLE_object_purgeable), GL, 2006 },
{ "GL_APPLE_packed_pixels", o(dummy_true), GLL, 2002 },
{ "GL_APPLE_texture_max_level", o(dummy_true), ES1 | ES2, 2009 },
@@ -321,7 +323,6 @@ static const struct extension extension_table[] = {
{ "GL_IBM_texture_mirrored_repeat", o(dummy_true), GLL, 1998 },
{ "GL_INGR_blend_func_separate", o(EXT_blend_func_separate), GLL, 1999 },
{ "GL_MESA_pack_invert", o(MESA_pack_invert), GL, 2002 },
- { "GL_MESA_texture_array", o(MESA_texture_array), GLL, 2007 },
{ "GL_MESA_texture_signed_rgba", o(EXT_texture_snorm), GL, 2009 },
{ "GL_MESA_window_pos", o(dummy_true), GLL, 2000 },
{ "GL_MESA_ycbcr_texture", o(MESA_ycbcr_texture), GL, 2002 },
@@ -333,7 +334,7 @@ static const struct extension extension_table[] = {
{ "GL_NV_fog_distance", o(NV_fog_distance), GLL, 2001 },
{ "GL_NV_fragment_program_option", o(NV_fragment_program_option), GLL, 2005 },
{ "GL_NV_light_max_exponent", o(dummy_true), GLL, 1999 },
- { "GL_NV_packed_depth_stencil", o(EXT_packed_depth_stencil), GL, 2000 },
+ { "GL_NV_packed_depth_stencil", o(dummy_true), GL, 2000 },
{ "GL_NV_point_sprite", o(NV_point_sprite), GL, 2001 },
{ "GL_NV_primitive_restart", o(NV_primitive_restart), GLL, 2002 },
{ "GL_NV_read_buffer", o(dummy_true), ES2, 2011 },
@@ -436,7 +437,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
ctx->Extensions.EXT_depth_bounds_test = GL_TRUE;
ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
- ctx->Extensions.EXT_packed_depth_stencil = GL_TRUE;
ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE;
ctx->Extensions.EXT_point_parameters = GL_TRUE;
ctx->Extensions.EXT_provoking_vertex = GL_TRUE;
@@ -453,7 +453,6 @@ _mesa_enable_sw_extensions(struct gl_context *ctx)
/*ctx->Extensions.EXT_transform_feedback = GL_TRUE;*/
ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE;
ctx->Extensions.MESA_pack_invert = GL_TRUE;
- ctx->Extensions.MESA_texture_array = GL_TRUE;
ctx->Extensions.MESA_ycbcr_texture = GL_TRUE;
ctx->Extensions.NV_conditional_render = GL_TRUE;
ctx->Extensions.NV_point_sprite = GL_TRUE;
@@ -480,7 +479,8 @@ set_extension( struct gl_context *ctx, const char *name, GLboolean state )
if (ctx->Extensions.String) {
/* The string was already queried - can't change it now! */
- _mesa_problem(ctx, "Trying to enable/disable extension after glGetString(GL_EXTENSIONS): %s", name);
+ _mesa_problem(ctx, "Trying to enable/disable extension after "
+ "glGetString(GL_EXTENSIONS): %s", name);
return GL_FALSE;
}
@@ -679,10 +679,10 @@ _mesa_make_extension_string(struct gl_context *ctx)
return NULL;
}
- /* Sort extensions in chronological order because certain old applications (e.g.,
- * Quake3 demo) store the extension list in a static size buffer so chronologically
- * order ensure that the extensions that such applications expect will fit into
- * that buffer.
+ /* Sort extensions in chronological order because certain old applications
+ * (e.g., Quake3 demo) store the extension list in a static size buffer so
+ * chronologically order ensure that the extensions that such applications
+ * expect will fit into that buffer.
*/
j = 0;
for (i = extension_table; i->name != 0; ++i) {
@@ -693,7 +693,8 @@ _mesa_make_extension_string(struct gl_context *ctx)
}
}
assert(j == count);
- qsort(extension_indices, count, sizeof *extension_indices, extension_compare);
+ qsort(extension_indices, count,
+ sizeof *extension_indices, extension_compare);
/* Build the extension string.*/
for (j = 0; j < count; ++j) {
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 861885dd3..2892784f8 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -781,9 +781,8 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format,
if (baseFormat == GL_DEPTH_COMPONENT) {
/* OK */
}
- else if (ctx->Extensions.EXT_packed_depth_stencil &&
- ctx->Extensions.ARB_depth_texture &&
- baseFormat == GL_DEPTH_STENCIL_EXT) {
+ else if (ctx->Extensions.ARB_depth_texture &&
+ baseFormat == GL_DEPTH_STENCIL) {
/* OK */
}
else {
@@ -794,9 +793,8 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format,
}
else {
ASSERT(format == GL_STENCIL);
- if (ctx->Extensions.EXT_packed_depth_stencil &&
- ctx->Extensions.ARB_depth_texture &&
- baseFormat == GL_DEPTH_STENCIL_EXT) {
+ if (ctx->Extensions.ARB_depth_texture &&
+ baseFormat == GL_DEPTH_STENCIL) {
/* OK */
}
else {
@@ -830,8 +828,7 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format,
if (baseFormat == GL_DEPTH_COMPONENT) {
/* OK */
}
- else if (ctx->Extensions.EXT_packed_depth_stencil &&
- baseFormat == GL_DEPTH_STENCIL_EXT) {
+ else if (baseFormat == GL_DEPTH_STENCIL) {
/* OK */
}
else {
@@ -842,11 +839,8 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format,
}
else {
assert(format == GL_STENCIL);
- if (baseFormat == GL_STENCIL_INDEX) {
- /* OK */
- }
- else if (ctx->Extensions.EXT_packed_depth_stencil &&
- baseFormat == GL_DEPTH_STENCIL_EXT) {
+ if (baseFormat == GL_STENCIL_INDEX ||
+ baseFormat == GL_DEPTH_STENCIL) {
/* OK */
}
else {
@@ -1457,13 +1451,10 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
return GL_DEPTH_COMPONENT;
- case GL_DEPTH_STENCIL_EXT:
- return _mesa_is_desktop_gl(ctx)
- && ctx->Extensions.EXT_packed_depth_stencil
- ? GL_DEPTH_STENCIL_EXT : 0;
- case GL_DEPTH24_STENCIL8_EXT:
- return ctx->Extensions.EXT_packed_depth_stencil
- ? GL_DEPTH_STENCIL_EXT : 0;
+ case GL_DEPTH_STENCIL:
+ return _mesa_is_desktop_gl(ctx) ? GL_DEPTH_STENCIL : 0;
+ case GL_DEPTH24_STENCIL8:
+ return GL_DEPTH_STENCIL;
case GL_DEPTH_COMPONENT32F:
return ctx->Version >= 30
|| (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_buffer_float)
diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp
index 01edd3ff8..ba6258d89 100644
--- a/mesalib/src/mesa/main/ff_fragment_shader.cpp
+++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp
@@ -543,7 +543,8 @@ get_current_attrib(texenv_fragment_program *p, GLuint attrib)
ir_rvalue *val;
current = p->shader->symbols->get_variable("gl_CurrentAttribFragMESA");
- current->max_array_access = MAX2(current->max_array_access, attrib);
+ assert(current);
+ current->data.max_array_access = MAX2(current->data.max_array_access, attrib);
val = new(p->mem_ctx) ir_dereference_variable(current);
ir_rvalue *index = new(p->mem_ctx) ir_constant(attrib);
return new(p->mem_ctx) ir_dereference_array(val, index);
@@ -587,7 +588,7 @@ get_source(texenv_fragment_program *p,
var = p->shader->symbols->get_variable("gl_TextureEnvColor");
assert(var);
deref = new(p->mem_ctx) ir_dereference_variable(var);
- var->max_array_access = MAX2(var->max_array_access, unit);
+ var->data.max_array_access = MAX2(var->data.max_array_access, unit);
return new(p->mem_ctx) ir_dereference_array(deref,
new(p->mem_ctx) ir_constant(unit));
@@ -927,7 +928,7 @@ static void load_texture( texenv_fragment_program *p, GLuint unit )
texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array);
ir_rvalue *index = new(p->mem_ctx) ir_constant(unit);
texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index);
- tc_array->max_array_access = MAX2(tc_array->max_array_access, unit);
+ tc_array->data.max_array_access = MAX2(tc_array->data.max_array_access, unit);
}
if (!p->state->unit[unit].enabled) {
@@ -1096,14 +1097,16 @@ load_texunit_bumpmap( texenv_fragment_program *p, GLuint unit )
ir_variable *rot_mat_0, *rot_mat_1;
rot_mat_0 = p->shader->symbols->get_variable("gl_BumpRotMatrix0MESA");
+ assert(rot_mat_0);
rot_mat_1 = p->shader->symbols->get_variable("gl_BumpRotMatrix1MESA");
+ assert(rot_mat_1);
ir_variable *tc_array = p->shader->symbols->get_variable("gl_TexCoord");
assert(tc_array);
texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array);
ir_rvalue *index = new(p->mem_ctx) ir_constant(bumpedUnitNr);
texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index);
- tc_array->max_array_access = MAX2(tc_array->max_array_access, unit);
+ tc_array->data.max_array_access = MAX2(tc_array->data.max_array_access, unit);
load_texenv_source( p, unit + SRC_TEXTURE0, unit );
@@ -1157,8 +1160,11 @@ emit_fog_instructions(texenv_fragment_program *p,
fragcolor = swizzle_xyz(fog_result);
oparams = p->shader->symbols->get_variable("gl_FogParamsOptimizedMESA");
+ assert(oparams);
fogcoord = p->shader->symbols->get_variable("gl_FogFragCoord");
+ assert(fogcoord);
params = p->shader->symbols->get_variable("gl_Fog");
+ assert(params);
f = new(p->mem_ctx) ir_dereference_variable(fogcoord);
ir_variable *f_var = p->make_temp(glsl_type::float_type, "fog_factor");
@@ -1344,7 +1350,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key)
p.shader->CompileStatus = true;
p.shader->Version = state->language_version;
- p.shader->num_builtins_to_link = state->num_builtins_to_link;
+ p.shader->uses_builtin_functions = state->uses_builtin_functions;
p.shader_program->Shaders =
(gl_shader **)malloc(sizeof(*p.shader_program->Shaders));
p.shader_program->Shaders[0] = p.shader;
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index 7f233409e..691380898 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -327,8 +327,8 @@ static const int extra_EXT_framebuffer_sRGB_and_new_buffers[] = {
EXTRA_END
};
-static const int extra_MESA_texture_array_es3[] = {
- EXT(MESA_texture_array),
+static const int extra_EXT_texture_array_es3[] = {
+ EXT(EXT_texture_array),
EXTRA_API_ES3,
EXTRA_END
};
@@ -339,7 +339,7 @@ static const int extra_ARB_shader_atomic_counters_and_geometry_shader[] = {
};
EXTRA_EXT(ARB_texture_cube_map);
-EXTRA_EXT(MESA_texture_array);
+EXTRA_EXT(EXT_texture_array);
EXTRA_EXT(NV_fog_distance);
EXTRA_EXT(EXT_texture_filter_anisotropic);
EXTRA_EXT(NV_point_sprite);
@@ -565,8 +565,6 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_3D:
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_TEXTURE_2D_ARRAY_EXT:
case GL_TEXTURE_CUBE_MAP_ARB:
case GL_TEXTURE_RECTANGLE_NV:
case GL_TEXTURE_EXTERNAL_OES:
diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py
index 781b796ee..653bf6256 100644
--- a/mesalib/src/mesa/main/get_hash_params.py
+++ b/mesalib/src/mesa/main/get_hash_params.py
@@ -376,8 +376,8 @@ descriptor=[
[ "PIXEL_UNPACK_BUFFER_BINDING_EXT", "LOC_CUSTOM, TYPE_INT, 0, extra_EXT_pixel_buffer_object" ],
# GL_EXT_texture_array
- [ "TEXTURE_BINDING_2D_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_ARRAY_INDEX, extra_MESA_texture_array_es3" ],
- [ "MAX_ARRAY_TEXTURE_LAYERS_EXT", "CONTEXT_INT(Const.MaxArrayTextureLayers), extra_MESA_texture_array_es3" ],
+ [ "TEXTURE_BINDING_2D_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_ARRAY_INDEX, extra_EXT_texture_array_es3" ],
+ [ "MAX_ARRAY_TEXTURE_LAYERS_EXT", "CONTEXT_INT(Const.MaxArrayTextureLayers), extra_EXT_texture_array_es3" ],
# GL_EXT_transform_feedback
[ "TRANSFORM_FEEDBACK_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_EXT_transform_feedback" ],
@@ -504,10 +504,8 @@ descriptor=[
[ "STEREO", "BUFFER_INT(Visual.stereoMode), NO_EXTRA" ],
[ "TEXTURE_1D", "LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA" ],
[ "TEXTURE_3D", "LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA" ],
- [ "TEXTURE_1D_ARRAY_EXT", "LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA" ],
- [ "TEXTURE_2D_ARRAY_EXT", "LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA" ],
[ "TEXTURE_BINDING_1D", "LOC_CUSTOM, TYPE_INT, TEXTURE_1D_INDEX, NO_EXTRA" ],
- [ "TEXTURE_BINDING_1D_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_1D_ARRAY_INDEX, extra_MESA_texture_array" ],
+ [ "TEXTURE_BINDING_1D_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_1D_ARRAY_INDEX, extra_EXT_texture_array" ],
[ "TEXTURE_GEN_S", "LOC_TEXUNIT, TYPE_BIT_0, offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA" ],
[ "TEXTURE_GEN_T", "LOC_TEXUNIT, TYPE_BIT_1, offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA" ],
[ "TEXTURE_GEN_R", "LOC_TEXUNIT, TYPE_BIT_2, offsetof(struct gl_texture_unit, TexGenEnabled), NO_EXTRA" ],
diff --git a/mesalib/src/mesa/main/getstring.c b/mesalib/src/mesa/main/getstring.c
index d8189115a..b66e24788 100644
--- a/mesalib/src/mesa/main/getstring.c
+++ b/mesalib/src/mesa/main/getstring.c
@@ -42,8 +42,6 @@ shading_language_version(struct gl_context *ctx)
case API_OPENGL_COMPAT:
case API_OPENGL_CORE:
switch (ctx->Const.GLSLVersion) {
- case 110:
- return (const GLubyte *) "1.10";
case 120:
return (const GLubyte *) "1.20";
case 130:
diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c
index 740faa890..bec7a9bbb 100644
--- a/mesalib/src/mesa/main/glformats.c
+++ b/mesalib/src/mesa/main/glformats.c
@@ -1301,9 +1301,6 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
return GL_INVALID_OPERATION;
case GL_UNSIGNED_INT_24_8:
- if (!ctx->Extensions.EXT_packed_depth_stencil) {
- return GL_INVALID_ENUM;
- }
if (format != GL_DEPTH_STENCIL) {
return GL_INVALID_OPERATION;
}
@@ -1484,9 +1481,8 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
else
return GL_INVALID_OPERATION;
- case GL_DEPTH_STENCIL_EXT:
- if (ctx->Extensions.EXT_packed_depth_stencil &&
- type == GL_UNSIGNED_INT_24_8)
+ case GL_DEPTH_STENCIL:
+ if (type == GL_UNSIGNED_INT_24_8)
return GL_NO_ERROR;
else if (ctx->Extensions.ARB_depth_buffer_float &&
type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
@@ -1694,8 +1690,6 @@ GLenum
_mesa_es3_error_check_format_and_type(GLenum format, GLenum type,
GLenum internalFormat)
{
- GLboolean type_valid = GL_TRUE;
-
switch (format) {
case GL_RGBA:
switch (type) {
@@ -2116,5 +2110,5 @@ _mesa_es3_error_check_format_and_type(GLenum format, GLenum type,
break;
}
- return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION;
+ return GL_NO_ERROR;
}
diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c
index 277e9476a..4afe156b0 100644
--- a/mesalib/src/mesa/main/imports.c
+++ b/mesalib/src/mesa/main/imports.c
@@ -168,6 +168,8 @@ _mesa_align_calloc(size_t bytes, unsigned long alignment)
* \param ptr pointer to the memory to be freed.
* The actual address to free is stored in the word immediately before the
* address the client sees.
+ * Note that it is legal to pass NULL pointer to this function and will be
+ * handled accordingly.
*/
void
_mesa_align_free(void *ptr)
@@ -177,9 +179,11 @@ _mesa_align_free(void *ptr)
#elif defined(_WIN32) && defined(_MSC_VER)
_aligned_free(ptr);
#else
- void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
- void *realAddr = *cubbyHole;
- free(realAddr);
+ if (ptr) {
+ void **cubbyHole = (void **) ((char *) ptr - sizeof(void *));
+ void *realAddr = *cubbyHole;
+ free(realAddr);
+ }
#endif /* defined(HAVE_POSIX_MEMALIGN) */
}
@@ -199,8 +203,8 @@ _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
if (newBuf && oldBuffer && copySize > 0) {
memcpy(newBuf, oldBuffer, copySize);
}
- if (oldBuffer)
- _mesa_align_free(oldBuffer);
+
+ _mesa_align_free(oldBuffer);
return newBuf;
#endif
}
diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c
index 180f89116..033015780 100644
--- a/mesalib/src/mesa/main/mipmap.c
+++ b/mesalib/src/mesa/main/mipmap.c
@@ -1767,8 +1767,8 @@ _mesa_generate_mipmap_level(GLenum target,
* compute next (level+1) image size
* \return GL_FALSE if no smaller size can be generated (eg. src is 1x1x1 size)
*/
-static GLboolean
-next_mipmap_level_size(GLenum target, GLint border,
+GLboolean
+_mesa_next_mipmap_level_size(GLenum target, GLint border,
GLint srcWidth, GLint srcHeight, GLint srcDepth,
GLint *dstWidth, GLint *dstHeight, GLint *dstDepth)
{
@@ -1911,7 +1911,7 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
srcDepth = srcImage->Depth;
border = srcImage->Border;
- nextLevel = next_mipmap_level_size(target, border,
+ nextLevel = _mesa_next_mipmap_level_size(target, border,
srcWidth, srcHeight, srcDepth,
&dstWidth, &dstHeight, &dstDepth);
if (!nextLevel)
@@ -2102,7 +2102,7 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
srcDepth = srcImage->Depth;
border = srcImage->Border;
- nextLevel = next_mipmap_level_size(target, border,
+ nextLevel = _mesa_next_mipmap_level_size(target, border,
srcWidth, srcHeight, srcDepth,
&dstWidth, &dstHeight, &dstDepth);
if (!nextLevel)
diff --git a/mesalib/src/mesa/main/mipmap.h b/mesalib/src/mesa/main/mipmap.h
index d5bd1d83d..ee91df006 100644
--- a/mesalib/src/mesa/main/mipmap.h
+++ b/mesalib/src/mesa/main/mipmap.h
@@ -51,5 +51,9 @@ extern void
_mesa_generate_mipmap(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj);
+extern GLboolean
+_mesa_next_mipmap_level_size(GLenum target, GLint border,
+ GLint srcWidth, GLint srcHeight, GLint srcDepth,
+ GLint *dstWidth, GLint *dstHeight, GLint *dstDepth);
#endif /* MIPMAP_H */
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index b4b432f40..f93bb5641 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -280,6 +280,7 @@ typedef enum
*/
#define SYSTEM_BIT_SAMPLE_ID BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_ID)
#define SYSTEM_BIT_SAMPLE_POS BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_POS)
+#define SYSTEM_BIT_SAMPLE_MASK_IN BITFIELD64_BIT(SYSTEM_VALUE_SAMPLE_MASK_IN)
/**
* Determine if the given gl_varying_slot appears in the fragment shader.
@@ -1193,6 +1194,11 @@ struct gl_texture_object
pressure? */
GLboolean Immutable; /**< GL_ARB_texture_storage */
+ GLuint MinLevel; /**< GL_ARB_texture_view */
+ GLuint MinLayer; /**< GL_ARB_texture_view */
+ GLuint NumLevels; /**< GL_ARB_texture_view */
+ GLuint NumLayers; /**< GL_ARB_texture_view */
+
/** Actual texture images, indexed by [cube face] and [mipmap level] */
struct gl_texture_image *Image[MAX_FACES][MAX_TEXTURE_LEVELS];
@@ -1968,12 +1974,13 @@ typedef enum
*/
typedef enum
{
- SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */
- SYSTEM_VALUE_VERTEX_ID, /**< Vertex shader only */
- SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */
- SYSTEM_VALUE_SAMPLE_ID, /**< Fragment shader only */
- SYSTEM_VALUE_SAMPLE_POS, /**< Fragment shader only */
- SYSTEM_VALUE_MAX /**< Number of values */
+ SYSTEM_VALUE_FRONT_FACE, /**< Fragment shader only (not done yet) */
+ SYSTEM_VALUE_VERTEX_ID, /**< Vertex shader only */
+ SYSTEM_VALUE_INSTANCE_ID, /**< Vertex shader only */
+ SYSTEM_VALUE_SAMPLE_ID, /**< Fragment shader only */
+ SYSTEM_VALUE_SAMPLE_POS, /**< Fragment shader only */
+ SYSTEM_VALUE_SAMPLE_MASK_IN, /**< Fragment shader only */
+ SYSTEM_VALUE_MAX /**< Number of values */
} gl_system_value;
@@ -2132,6 +2139,12 @@ struct gl_fragment_program
* uses centroid interpolation, 0 otherwise. Unused inputs are 0.
*/
GLbitfield64 IsCentroid;
+
+ /**
+ * Bitfield indicating, for each fragment shader input, 1 if that input
+ * uses sample interpolation, 0 otherwise. Unused inputs are 0.
+ */
+ GLbitfield64 IsSample;
};
@@ -2352,9 +2365,7 @@ struct gl_shader
struct exec_list *ir;
struct glsl_symbol_table *symbols;
- /** Shaders containing built-in functions that are used for linking. */
- struct gl_shader *builtins_to_link[16];
- unsigned num_builtins_to_link;
+ bool uses_builtin_functions;
/**
* Geometry shader state from GLSL 1.50 layout qualifiers.
@@ -2388,9 +2399,10 @@ typedef enum
MESA_SHADER_VERTEX = 0,
MESA_SHADER_GEOMETRY = 1,
MESA_SHADER_FRAGMENT = 2,
- MESA_SHADER_TYPES = 3
} gl_shader_type;
+#define MESA_SHADER_TYPES (MESA_SHADER_FRAGMENT + 1)
+
struct gl_uniform_buffer_variable
{
@@ -3374,6 +3386,7 @@ struct gl_extensions
GLboolean ARB_texture_query_lod;
GLboolean ARB_texture_rg;
GLboolean ARB_texture_rgb10_a2ui;
+ GLboolean ARB_texture_view;
GLboolean ARB_timer_query;
GLboolean ARB_transform_feedback2;
GLboolean ARB_transform_feedback3;
@@ -3395,7 +3408,6 @@ struct gl_extensions
GLboolean EXT_framebuffer_sRGB;
GLboolean EXT_gpu_program_parameters;
GLboolean EXT_gpu_shader4;
- GLboolean EXT_packed_depth_stencil;
GLboolean EXT_packed_float;
GLboolean EXT_pixel_buffer_object;
GLboolean EXT_point_parameters;
@@ -3432,7 +3444,6 @@ struct gl_extensions
GLboolean ATI_fragment_shader;
GLboolean ATI_separate_stencil;
GLboolean MESA_pack_invert;
- GLboolean MESA_texture_array;
GLboolean MESA_ycbcr_texture;
GLboolean NV_conditional_render;
GLboolean NV_fog_distance;
diff --git a/mesalib/src/mesa/main/performance_monitor.c b/mesalib/src/mesa/main/performance_monitor.c
index 4981e6fb2..e62f77012 100644
--- a/mesalib/src/mesa/main/performance_monitor.c
+++ b/mesalib/src/mesa/main/performance_monitor.c
@@ -93,6 +93,25 @@ fail:
return NULL;
}
+static void
+free_performance_monitor(GLuint key, void *data, void *user)
+{
+ struct gl_perf_monitor_object *m = data;
+ struct gl_context *ctx = user;
+
+ ralloc_free(m->ActiveGroups);
+ ralloc_free(m->ActiveCounters);
+ ctx->Driver.DeletePerfMonitor(ctx, m);
+}
+
+void
+_mesa_free_performance_monitors(struct gl_context *ctx)
+{
+ _mesa_HashDeleteAll(ctx->PerfMonitor.Monitors,
+ free_performance_monitor, ctx);
+ _mesa_DeleteHashTable(ctx->PerfMonitor.Monitors);
+}
+
static inline struct gl_perf_monitor_object *
lookup_monitor(struct gl_context *ctx, GLuint id)
{
diff --git a/mesalib/src/mesa/main/performance_monitor.h b/mesalib/src/mesa/main/performance_monitor.h
index a852a4184..76234e5c1 100644
--- a/mesalib/src/mesa/main/performance_monitor.h
+++ b/mesalib/src/mesa/main/performance_monitor.h
@@ -35,6 +35,9 @@
extern void
_mesa_init_performance_monitors(struct gl_context *ctx);
+extern void
+_mesa_free_performance_monitors(struct gl_context *ctx);
+
extern void GLAPIENTRY
_mesa_GetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize,
GLuint *groups);
diff --git a/mesalib/src/mesa/main/shader_query.cpp b/mesalib/src/mesa/main/shader_query.cpp
index 3014a9778..f14e1a562 100644
--- a/mesalib/src/mesa/main/shader_query.cpp
+++ b/mesalib/src/mesa/main/shader_query.cpp
@@ -106,8 +106,8 @@ _mesa_GetActiveAttrib(GLhandleARB program, GLuint desired_index,
const ir_variable *const var = ((ir_instruction *) node)->as_variable();
if (var == NULL
- || var->mode != ir_var_shader_in
- || var->location == -1)
+ || var->data.mode != ir_var_shader_in
+ || var->data.location == -1)
continue;
if (current_index == desired_index) {
@@ -169,13 +169,13 @@ _mesa_GetAttribLocation(GLhandleARB program, const GLcharARB * name)
* attribute, or if an error occurs, -1 will be returned."
*/
if (var == NULL
- || var->mode != ir_var_shader_in
- || var->location == -1
- || var->location < VERT_ATTRIB_GENERIC0)
+ || var->data.mode != ir_var_shader_in
+ || var->data.location == -1
+ || var->data.location < VERT_ATTRIB_GENERIC0)
continue;
if (strcmp(var->name, name) == 0)
- return var->location - VERT_ATTRIB_GENERIC0;
+ return var->data.location - VERT_ATTRIB_GENERIC0;
}
return -1;
@@ -197,8 +197,8 @@ _mesa_count_active_attribs(struct gl_shader_program *shProg)
const ir_variable *const var = ((ir_instruction *) node)->as_variable();
if (var == NULL
- || var->mode != ir_var_shader_in
- || var->location == -1)
+ || var->data.mode != ir_var_shader_in
+ || var->data.location == -1)
continue;
i++;
@@ -223,8 +223,8 @@ _mesa_longest_attribute_name_length(struct gl_shader_program *shProg)
const ir_variable *const var = ((ir_instruction *) node)->as_variable();
if (var == NULL
- || var->mode != ir_var_shader_in
- || var->location == -1)
+ || var->data.mode != ir_var_shader_in
+ || var->data.location == -1)
continue;
const size_t len = strlen(var->name);
@@ -333,13 +333,13 @@ _mesa_GetFragDataIndex(GLuint program, const GLchar *name)
* attribute, or if an error occurs, -1 will be returned."
*/
if (var == NULL
- || var->mode != ir_var_shader_out
- || var->location == -1
- || var->location < FRAG_RESULT_DATA0)
+ || var->data.mode != ir_var_shader_out
+ || var->data.location == -1
+ || var->data.location < FRAG_RESULT_DATA0)
continue;
if (strcmp(var->name, name) == 0)
- return var->index;
+ return var->data.index;
}
return -1;
@@ -389,13 +389,13 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
* attribute, or if an error occurs, -1 will be returned."
*/
if (var == NULL
- || var->mode != ir_var_shader_out
- || var->location == -1
- || var->location < FRAG_RESULT_DATA0)
+ || var->data.mode != ir_var_shader_out
+ || var->data.location == -1
+ || var->data.location < FRAG_RESULT_DATA0)
continue;
if (strcmp(var->name, name) == 0)
- return var->location - FRAG_RESULT_DATA0;
+ return var->data.location - FRAG_RESULT_DATA0;
}
return -1;
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index 1d9aac39d..4f3be68a4 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -414,7 +414,7 @@ detach_shader(struct gl_context *ctx, GLuint program, GLuint shader)
err = GL_INVALID_OPERATION;
else
err = GL_INVALID_VALUE;
- _mesa_error(ctx, err, "glDetachProgram(shader)");
+ _mesa_error(ctx, err, "glDetachShader(shader)");
return;
}
}
diff --git a/mesalib/src/mesa/main/shaderobj.h b/mesalib/src/mesa/main/shaderobj.h
index de1c9fcaf..aff178f26 100644
--- a/mesalib/src/mesa/main/shaderobj.h
+++ b/mesalib/src/mesa/main/shaderobj.h
@@ -113,7 +113,7 @@ _mesa_shader_type_to_index(GLenum v)
return MESA_SHADER_GEOMETRY;
default:
ASSERT(0 && "bad value in _mesa_shader_type_to_index()");
- return MESA_SHADER_TYPES;
+ return MESA_SHADER_VERTEX;
}
}
diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c
index d66ca1abc..200d29c2f 100644
--- a/mesalib/src/mesa/main/texgetimage.c
+++ b/mesalib/src/mesa/main/texgetimage.c
@@ -759,8 +759,7 @@ legal_getteximage_target(struct gl_context *ctx, GLenum target)
return ctx->Extensions.NV_texture_rectangle;
case GL_TEXTURE_1D_ARRAY_EXT:
case GL_TEXTURE_2D_ARRAY_EXT:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return ctx->Extensions.EXT_texture_array;
case GL_TEXTURE_CUBE_MAP_ARRAY:
return ctx->Extensions.ARB_texture_cube_map_array;
default:
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 793c5d382..9c3f1e86e 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -48,6 +48,7 @@
#include "texobj.h"
#include "texstate.h"
#include "texstorage.h"
+#include "textureview.h"
#include "mtypes.h"
#include "glformats.h"
@@ -300,14 +301,12 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
}
}
- if (ctx->Extensions.EXT_packed_depth_stencil) {
- switch (internalFormat) {
- case GL_DEPTH_STENCIL_EXT:
- case GL_DEPTH24_STENCIL8_EXT:
- return GL_DEPTH_STENCIL_EXT;
- default:
- ; /* fallthrough */
- }
+ switch (internalFormat) {
+ case GL_DEPTH_STENCIL:
+ case GL_DEPTH24_STENCIL8:
+ return GL_DEPTH_STENCIL;
+ default:
+ ; /* fallthrough */
}
if (ctx->Extensions.EXT_texture_sRGB) {
@@ -752,8 +751,7 @@ _mesa_select_tex_object(struct gl_context *ctx,
const struct gl_texture_unit *texUnit,
GLenum target)
{
- const GLboolean arrayTex = (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ const GLboolean arrayTex = ctx->Extensions.EXT_texture_array;
switch (target) {
case GL_TEXTURE_1D:
@@ -1018,8 +1016,7 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
case GL_TEXTURE_2D_ARRAY_EXT:
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array)
+ return ctx->Extensions.EXT_texture_array
? ctx->Const.MaxTextureLevels : 0;
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
@@ -1726,8 +1723,7 @@ target_can_be_compressed(const struct gl_context *ctx, GLenum target,
return ctx->Extensions.ARB_texture_cube_map;
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
case GL_TEXTURE_2D_ARRAY_EXT:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return ctx->Extensions.EXT_texture_array;
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
case GL_TEXTURE_CUBE_MAP_ARRAY:
return ctx->Extensions.ARB_texture_cube_map_array;
@@ -1775,9 +1771,7 @@ legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
&& ctx->Extensions.NV_texture_rectangle;
case GL_TEXTURE_1D_ARRAY_EXT:
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
- return _mesa_is_desktop_gl(ctx)
- && (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array;
default:
return GL_FALSE;
}
@@ -1788,14 +1782,10 @@ legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
case GL_PROXY_TEXTURE_3D:
return _mesa_is_desktop_gl(ctx);
case GL_TEXTURE_2D_ARRAY_EXT:
- return (_mesa_is_desktop_gl(ctx)
- && (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array))
+ return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array)
|| _mesa_is_gles3(ctx);
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
- return _mesa_is_desktop_gl(ctx)
- && (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array;
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
return ctx->Extensions.ARB_texture_cube_map_array;
@@ -1836,9 +1826,7 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
return _mesa_is_desktop_gl(ctx)
&& ctx->Extensions.NV_texture_rectangle;
case GL_TEXTURE_1D_ARRAY_EXT:
- return _mesa_is_desktop_gl(ctx)
- && (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array;
default:
return GL_FALSE;
}
@@ -1847,9 +1835,7 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
case GL_TEXTURE_3D:
return GL_TRUE;
case GL_TEXTURE_2D_ARRAY_EXT:
- return (_mesa_is_desktop_gl(ctx)
- && (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array))
+ return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array)
|| _mesa_is_gles3(ctx);
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
@@ -2870,7 +2856,7 @@ _mesa_choose_texture_format(struct gl_context *ctx,
}
/* If the application requested compression to an S3TC format but we don't
- * have the DTXn library, force a generic compressed format instead.
+ * have the DXTn library, force a generic compressed format instead.
*/
if (internalFormat != format && format != GL_NONE) {
const GLenum before = internalFormat;
@@ -3892,87 +3878,108 @@ _mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,
static gl_format
get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
{
+ if (ctx->API != API_OPENGL_CORE) {
+ switch (internalFormat) {
+ case GL_ALPHA8:
+ return MESA_FORMAT_A8;
+ case GL_ALPHA16:
+ return MESA_FORMAT_A16;
+ case GL_ALPHA16F_ARB:
+ return MESA_FORMAT_ALPHA_FLOAT16;
+ case GL_ALPHA32F_ARB:
+ return MESA_FORMAT_ALPHA_FLOAT32;
+ case GL_ALPHA8I_EXT:
+ return MESA_FORMAT_ALPHA_INT8;
+ case GL_ALPHA16I_EXT:
+ return MESA_FORMAT_ALPHA_INT16;
+ case GL_ALPHA32I_EXT:
+ return MESA_FORMAT_ALPHA_INT32;
+ case GL_ALPHA8UI_EXT:
+ return MESA_FORMAT_ALPHA_UINT8;
+ case GL_ALPHA16UI_EXT:
+ return MESA_FORMAT_ALPHA_UINT16;
+ case GL_ALPHA32UI_EXT:
+ return MESA_FORMAT_ALPHA_UINT32;
+ case GL_LUMINANCE8:
+ return MESA_FORMAT_L8;
+ case GL_LUMINANCE16:
+ return MESA_FORMAT_L16;
+ case GL_LUMINANCE16F_ARB:
+ return MESA_FORMAT_LUMINANCE_FLOAT16;
+ case GL_LUMINANCE32F_ARB:
+ return MESA_FORMAT_LUMINANCE_FLOAT32;
+ case GL_LUMINANCE8I_EXT:
+ return MESA_FORMAT_LUMINANCE_INT8;
+ case GL_LUMINANCE16I_EXT:
+ return MESA_FORMAT_LUMINANCE_INT16;
+ case GL_LUMINANCE32I_EXT:
+ return MESA_FORMAT_LUMINANCE_INT32;
+ case GL_LUMINANCE8UI_EXT:
+ return MESA_FORMAT_LUMINANCE_UINT8;
+ case GL_LUMINANCE16UI_EXT:
+ return MESA_FORMAT_LUMINANCE_UINT16;
+ case GL_LUMINANCE32UI_EXT:
+ return MESA_FORMAT_LUMINANCE_UINT32;
+ case GL_LUMINANCE8_ALPHA8:
+ return MESA_FORMAT_AL88;
+ case GL_LUMINANCE16_ALPHA16:
+ return MESA_FORMAT_AL1616;
+ case GL_LUMINANCE_ALPHA16F_ARB:
+ return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
+ case GL_LUMINANCE_ALPHA32F_ARB:
+ return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
+ case GL_LUMINANCE_ALPHA8I_EXT:
+ return MESA_FORMAT_LUMINANCE_ALPHA_INT8;
+ case GL_LUMINANCE_ALPHA16I_EXT:
+ return MESA_FORMAT_LUMINANCE_ALPHA_INT8;
+ case GL_LUMINANCE_ALPHA32I_EXT:
+ return MESA_FORMAT_LUMINANCE_ALPHA_INT16;
+ case GL_LUMINANCE_ALPHA8UI_EXT:
+ return MESA_FORMAT_LUMINANCE_ALPHA_UINT8;
+ case GL_LUMINANCE_ALPHA16UI_EXT:
+ return MESA_FORMAT_LUMINANCE_ALPHA_UINT16;
+ case GL_LUMINANCE_ALPHA32UI_EXT:
+ return MESA_FORMAT_LUMINANCE_ALPHA_UINT32;
+ case GL_INTENSITY8:
+ return MESA_FORMAT_I8;
+ case GL_INTENSITY16:
+ return MESA_FORMAT_I16;
+ case GL_INTENSITY16F_ARB:
+ return MESA_FORMAT_INTENSITY_FLOAT16;
+ case GL_INTENSITY32F_ARB:
+ return MESA_FORMAT_INTENSITY_FLOAT32;
+ case GL_INTENSITY8I_EXT:
+ return MESA_FORMAT_INTENSITY_INT8;
+ case GL_INTENSITY16I_EXT:
+ return MESA_FORMAT_INTENSITY_INT16;
+ case GL_INTENSITY32I_EXT:
+ return MESA_FORMAT_INTENSITY_INT32;
+ case GL_INTENSITY8UI_EXT:
+ return MESA_FORMAT_INTENSITY_UINT8;
+ case GL_INTENSITY16UI_EXT:
+ return MESA_FORMAT_INTENSITY_UINT16;
+ case GL_INTENSITY32UI_EXT:
+ return MESA_FORMAT_INTENSITY_UINT32;
+ default:
+ break;
+ }
+ }
+
+ if (ctx->API == API_OPENGL_CORE &&
+ ctx->Extensions.ARB_texture_buffer_object_rgb32) {
+ switch (internalFormat) {
+ case GL_RGB32F:
+ return MESA_FORMAT_RGB_FLOAT32;
+ case GL_RGB32UI:
+ return MESA_FORMAT_RGB_UINT32;
+ case GL_RGB32I:
+ return MESA_FORMAT_RGB_INT32;
+ default:
+ break;
+ }
+ }
+
switch (internalFormat) {
- case GL_ALPHA8:
- return MESA_FORMAT_A8;
- case GL_ALPHA16:
- return MESA_FORMAT_A16;
- case GL_ALPHA16F_ARB:
- return MESA_FORMAT_ALPHA_FLOAT16;
- case GL_ALPHA32F_ARB:
- return MESA_FORMAT_ALPHA_FLOAT32;
- case GL_ALPHA8I_EXT:
- return MESA_FORMAT_ALPHA_INT8;
- case GL_ALPHA16I_EXT:
- return MESA_FORMAT_ALPHA_INT16;
- case GL_ALPHA32I_EXT:
- return MESA_FORMAT_ALPHA_INT32;
- case GL_ALPHA8UI_EXT:
- return MESA_FORMAT_ALPHA_UINT8;
- case GL_ALPHA16UI_EXT:
- return MESA_FORMAT_ALPHA_UINT16;
- case GL_ALPHA32UI_EXT:
- return MESA_FORMAT_ALPHA_UINT32;
- case GL_LUMINANCE8:
- return MESA_FORMAT_L8;
- case GL_LUMINANCE16:
- return MESA_FORMAT_L16;
- case GL_LUMINANCE16F_ARB:
- return MESA_FORMAT_LUMINANCE_FLOAT16;
- case GL_LUMINANCE32F_ARB:
- return MESA_FORMAT_LUMINANCE_FLOAT32;
- case GL_LUMINANCE8I_EXT:
- return MESA_FORMAT_LUMINANCE_INT8;
- case GL_LUMINANCE16I_EXT:
- return MESA_FORMAT_LUMINANCE_INT16;
- case GL_LUMINANCE32I_EXT:
- return MESA_FORMAT_LUMINANCE_INT32;
- case GL_LUMINANCE8UI_EXT:
- return MESA_FORMAT_LUMINANCE_UINT8;
- case GL_LUMINANCE16UI_EXT:
- return MESA_FORMAT_LUMINANCE_UINT16;
- case GL_LUMINANCE32UI_EXT:
- return MESA_FORMAT_LUMINANCE_UINT32;
- case GL_LUMINANCE8_ALPHA8:
- return MESA_FORMAT_AL88;
- case GL_LUMINANCE16_ALPHA16:
- return MESA_FORMAT_AL1616;
- case GL_LUMINANCE_ALPHA16F_ARB:
- return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
- case GL_LUMINANCE_ALPHA32F_ARB:
- return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
- case GL_LUMINANCE_ALPHA8I_EXT:
- return MESA_FORMAT_LUMINANCE_ALPHA_INT8;
- case GL_LUMINANCE_ALPHA16I_EXT:
- return MESA_FORMAT_LUMINANCE_ALPHA_INT8;
- case GL_LUMINANCE_ALPHA32I_EXT:
- return MESA_FORMAT_LUMINANCE_ALPHA_INT16;
- case GL_LUMINANCE_ALPHA8UI_EXT:
- return MESA_FORMAT_LUMINANCE_ALPHA_UINT8;
- case GL_LUMINANCE_ALPHA16UI_EXT:
- return MESA_FORMAT_LUMINANCE_ALPHA_UINT16;
- case GL_LUMINANCE_ALPHA32UI_EXT:
- return MESA_FORMAT_LUMINANCE_ALPHA_UINT32;
- case GL_INTENSITY8:
- return MESA_FORMAT_I8;
- case GL_INTENSITY16:
- return MESA_FORMAT_I16;
- case GL_INTENSITY16F_ARB:
- return MESA_FORMAT_INTENSITY_FLOAT16;
- case GL_INTENSITY32F_ARB:
- return MESA_FORMAT_INTENSITY_FLOAT32;
- case GL_INTENSITY8I_EXT:
- return MESA_FORMAT_INTENSITY_INT8;
- case GL_INTENSITY16I_EXT:
- return MESA_FORMAT_INTENSITY_INT16;
- case GL_INTENSITY32I_EXT:
- return MESA_FORMAT_INTENSITY_INT32;
- case GL_INTENSITY8UI_EXT:
- return MESA_FORMAT_INTENSITY_UINT8;
- case GL_INTENSITY16UI_EXT:
- return MESA_FORMAT_INTENSITY_UINT16;
- case GL_INTENSITY32UI_EXT:
- return MESA_FORMAT_INTENSITY_UINT32;
case GL_RGBA8:
return MESA_FORMAT_RGBA8888_REV;
case GL_RGBA16:
@@ -4036,21 +4043,15 @@ get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
case GL_R32UI:
return MESA_FORMAT_R_UINT32;
- case GL_RGB32F:
- return MESA_FORMAT_RGB_FLOAT32;
- case GL_RGB32UI:
- return MESA_FORMAT_RGB_UINT32;
- case GL_RGB32I:
- return MESA_FORMAT_RGB_INT32;
-
default:
return MESA_FORMAT_NONE;
}
}
-static gl_format
-validate_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
+gl_format
+_mesa_validate_texbuffer_format(const struct gl_context *ctx,
+ GLenum internalFormat)
{
gl_format format = get_texbuffer_format(ctx, internalFormat);
GLenum datatype;
@@ -4065,15 +4066,10 @@ validate_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
if (datatype == GL_HALF_FLOAT && !ctx->Extensions.ARB_half_float_pixel)
return MESA_FORMAT_NONE;
- /* The GL_ARB_texture_rg and GL_ARB_texture_buffer_object specs don't make
- * any mention of R/RG formats, but they appear in the GL 3.1 core
- * specification.
- */
- if (ctx->Version <= 30) {
+ if (!ctx->Extensions.ARB_texture_rg) {
GLenum base_format = _mesa_get_format_base_format(format);
-
if (base_format == GL_R || base_format == GL_RG)
- return MESA_FORMAT_NONE;
+ return MESA_FORMAT_NONE;
}
if (!ctx->Extensions.ARB_texture_buffer_object_rgb32) {
@@ -4100,7 +4096,7 @@ texbufferrange(struct gl_context *ctx, GLenum target, GLenum internalFormat,
return;
}
- format = validate_texbuffer_format(ctx, internalFormat);
+ format = _mesa_validate_texbuffer_format(ctx, internalFormat);
if (format == MESA_FORMAT_NONE) {
_mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(internalFormat 0x%x)",
internalFormat);
@@ -4348,6 +4344,11 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
}
texObj->Immutable = immutable;
+
+ if (immutable) {
+ _mesa_set_texture_view_state(ctx, texObj, target, 1);
+ }
+
_mesa_update_fbo_texture(ctx, texObj, 0, 0);
}
}
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 792383d2f..0b5786340 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -147,6 +147,10 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
GLint level, GLint width, GLint height,
GLint depth, GLint border);
+extern gl_format
+_mesa_validate_texbuffer_format(const struct gl_context *ctx,
+ GLenum internalFormat);
+
/**
* Lock a texture for updating. See also _mesa_lock_context_textures().
*/
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index abd30c563..d6510fefd 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -552,7 +552,7 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
t->_MaxLevel = MIN3(t->MaxLevel,
/* 'p' in the GL spec */
- baseLevel + baseImage->MaxNumLevels - 1,
+ (int) (baseLevel + baseImage->MaxNumLevels - 1),
/* 'q' in the GL spec */
maxLevels - 1);
@@ -889,6 +889,8 @@ count_tex_size(GLuint key, void *data, void *userData)
(const struct gl_texture_object *) data;
GLuint *total = (GLuint *) userData;
+ (void) key;
+
*total = *total + texture_size(texObj);
}
@@ -1171,7 +1173,7 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
* \return TEXTURE_x_INDEX or -1 if target is invalid
*/
static GLint
-target_enum_to_index(struct gl_context *ctx, GLenum target)
+target_enum_to_index(const struct gl_context *ctx, GLenum target)
{
switch (target) {
case GL_TEXTURE_1D:
@@ -1179,25 +1181,21 @@ target_enum_to_index(struct gl_context *ctx, GLenum target)
case GL_TEXTURE_2D:
return TEXTURE_2D_INDEX;
case GL_TEXTURE_3D:
- return TEXTURE_3D_INDEX;
- case GL_TEXTURE_CUBE_MAP_ARB:
+ return ctx->API != API_OPENGLES ? TEXTURE_3D_INDEX : -1;
+ case GL_TEXTURE_CUBE_MAP:
return ctx->Extensions.ARB_texture_cube_map
? TEXTURE_CUBE_INDEX : -1;
- case GL_TEXTURE_RECTANGLE_NV:
+ case GL_TEXTURE_RECTANGLE:
return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle
? TEXTURE_RECT_INDEX : -1;
- case GL_TEXTURE_1D_ARRAY_EXT:
- return _mesa_is_desktop_gl(ctx)
- && (ctx->Extensions.EXT_texture_array
- || ctx->Extensions.MESA_texture_array)
+ case GL_TEXTURE_1D_ARRAY:
+ return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array
? TEXTURE_1D_ARRAY_INDEX : -1;
- case GL_TEXTURE_2D_ARRAY_EXT:
- return (_mesa_is_desktop_gl(ctx)
- && (ctx->Extensions.EXT_texture_array
- || ctx->Extensions.MESA_texture_array))
+ case GL_TEXTURE_2D_ARRAY:
+ return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array)
|| _mesa_is_gles3(ctx)
? TEXTURE_2D_ARRAY_INDEX : -1;
- case GL_TEXTURE_BUFFER_ARB:
+ case GL_TEXTURE_BUFFER:
return ctx->API == API_OPENGL_CORE &&
ctx->Extensions.ARB_texture_buffer_object ?
TEXTURE_BUFFER_INDEX : -1;
@@ -1205,7 +1203,8 @@ target_enum_to_index(struct gl_context *ctx, GLenum target)
return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external
? TEXTURE_EXTERNAL_INDEX : -1;
case GL_TEXTURE_CUBE_MAP_ARRAY:
- return TEXTURE_CUBE_ARRAY_INDEX;
+ return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_cube_map_array
+ ? TEXTURE_CUBE_ARRAY_INDEX : -1;
case GL_TEXTURE_2D_MULTISAMPLE:
return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
? TEXTURE_2D_MULTISAMPLE_INDEX: -1;
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index 7092c630b..94e498d20 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -158,16 +158,13 @@ get_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
}
break;
case GL_TEXTURE_1D_ARRAY_EXT:
- if (_mesa_is_desktop_gl(ctx)
- && (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array)) {
+ if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array) {
return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
}
break;
case GL_TEXTURE_2D_ARRAY_EXT:
if ((_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx))
- && (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array)) {
+ && ctx->Extensions.EXT_texture_array) {
return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
}
break;
@@ -1046,8 +1043,7 @@ legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target)
case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
case GL_TEXTURE_2D_ARRAY_EXT:
case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return ctx->Extensions.EXT_texture_array;
case GL_TEXTURE_BUFFER:
/* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts,
* but not in earlier versions that expose ARB_texture_buffer_object.
@@ -1166,10 +1162,7 @@ get_tex_level_parameter_image(struct gl_context *ctx,
goto invalid_pname;
*params = _mesa_get_format_bits(texFormat, pname);
break;
- case GL_TEXTURE_STENCIL_SIZE_EXT:
- if (!ctx->Extensions.EXT_packed_depth_stencil &&
- !ctx->Extensions.ARB_framebuffer_object)
- goto invalid_pname;
+ case GL_TEXTURE_STENCIL_SIZE:
*params = _mesa_get_format_bits(texFormat, pname);
break;
case GL_TEXTURE_SHARED_SIZE:
@@ -1562,9 +1555,35 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
break;
case GL_TEXTURE_IMMUTABLE_LEVELS:
- if (!_mesa_is_gles3(ctx))
+ if (_mesa_is_gles3(ctx) ||
+ (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
+ *params = (GLfloat) obj->ImmutableLevels;
+ else
goto invalid_pname;
- *params = (GLfloat) obj->ImmutableLevels;
+ break;
+
+ case GL_TEXTURE_VIEW_MIN_LEVEL:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLfloat) obj->MinLevel;
+ break;
+
+ case GL_TEXTURE_VIEW_NUM_LEVELS:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLfloat) obj->NumLevels;
+ break;
+
+ case GL_TEXTURE_VIEW_MIN_LAYER:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLfloat) obj->MinLayer;
+ break;
+
+ case GL_TEXTURE_VIEW_NUM_LAYERS:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLfloat) obj->NumLayers;
break;
case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
@@ -1746,9 +1765,35 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
break;
case GL_TEXTURE_IMMUTABLE_LEVELS:
- if (!_mesa_is_gles3(ctx))
+ if (_mesa_is_gles3(ctx) ||
+ (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
+ *params = obj->ImmutableLevels;
+ else
+ goto invalid_pname;
+ break;
+
+ case GL_TEXTURE_VIEW_MIN_LEVEL:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLint) obj->MinLevel;
+ break;
+
+ case GL_TEXTURE_VIEW_NUM_LEVELS:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLint) obj->NumLevels;
+ break;
+
+ case GL_TEXTURE_VIEW_MIN_LAYER:
+ if (!ctx->Extensions.ARB_texture_view)
+ goto invalid_pname;
+ *params = (GLint) obj->MinLayer;
+ break;
+
+ case GL_TEXTURE_VIEW_NUM_LAYERS:
+ if (!ctx->Extensions.ARB_texture_view)
goto invalid_pname;
- *params = obj->ImmutableLevels;
+ *params = (GLint) obj->NumLayers;
break;
case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c
index 84b8f8224..5062fdb4f 100644
--- a/mesalib/src/mesa/main/texstorage.c
+++ b/mesalib/src/mesa/main/texstorage.c
@@ -37,7 +37,9 @@
#include "macros.h"
#include "teximage.h"
#include "texobj.h"
+#include "mipmap.h"
#include "texstorage.h"
+#include "textureview.h"
#include "mtypes.h"
@@ -73,8 +75,7 @@ legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target)
return ctx->Extensions.NV_texture_rectangle;
case GL_TEXTURE_1D_ARRAY:
case GL_PROXY_TEXTURE_1D_ARRAY:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return ctx->Extensions.EXT_texture_array;
default:
return GL_FALSE;
}
@@ -85,8 +86,7 @@ legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target)
return GL_TRUE;
case GL_TEXTURE_2D_ARRAY:
case GL_PROXY_TEXTURE_2D_ARRAY:
- return (ctx->Extensions.MESA_texture_array ||
- ctx->Extensions.EXT_texture_array);
+ return ctx->Extensions.EXT_texture_array;
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
return ctx->Extensions.ARB_texture_cube_map_array;
@@ -100,27 +100,6 @@ legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target)
}
-/**
- * Compute the size of the next mipmap level.
- */
-static void
-next_mipmap_level_size(GLenum target,
- GLint *width, GLint *height, GLint *depth)
-{
- if (*width > 1) {
- *width /= 2;
- }
-
- if ((*height > 1) && (target != GL_TEXTURE_1D_ARRAY)) {
- *height /= 2;
- }
-
- if ((*depth > 1) && (target != GL_TEXTURE_2D_ARRAY)) {
- *depth /= 2;
- }
-}
-
-
/** Helper to get a particular texture image in a texture object */
static struct gl_texture_image *
get_tex_image(struct gl_context *ctx,
@@ -164,7 +143,8 @@ initialize_texture_fields(struct gl_context *ctx,
0, internalFormat, texFormat);
}
- next_mipmap_level_size(target, &levelWidth, &levelHeight, &levelDepth);
+ _mesa_next_mipmap_level_size(target, 0, levelWidth, levelHeight, levelDepth,
+ &levelWidth, &levelHeight, &levelDepth);
}
return GL_TRUE;
}
@@ -436,8 +416,8 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
return;
}
- texObj->Immutable = GL_TRUE;
- texObj->ImmutableLevels = levels;
+ _mesa_set_texture_view_state(ctx, texObj, target, levels);
+
}
}
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c
index 76d8d9ba3..5adbd5dc9 100644
--- a/mesalib/src/mesa/main/texstore.c
+++ b/mesalib/src/mesa/main/texstore.c
@@ -3864,6 +3864,7 @@ _mesa_texstore_memcpy(TEXSTORE_PARAMS)
/**
* Store user data into texture memory.
* Called via glTex[Sub]Image1/2/3D()
+ * \return GL_TRUE for success, GL_FALSE for failure (out of memory).
*/
GLboolean
_mesa_texstore(TEXSTORE_PARAMS)
diff --git a/mesalib/src/mesa/main/textureview.c b/mesalib/src/mesa/main/textureview.c
new file mode 100644
index 000000000..5f88a4171
--- /dev/null
+++ b/mesalib/src/mesa/main/textureview.c
@@ -0,0 +1,668 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Courtney Goeltzenleuchter <courtney@lunarg.com>
+ */
+
+
+/**
+ * \file textureview.c
+ * GL_ARB_texture_view functions
+ */
+
+#include "glheader.h"
+#include "context.h"
+#include "enums.h"
+#include "imports.h"
+#include "macros.h"
+#include "teximage.h"
+#include "texobj.h"
+#include "mipmap.h"
+#include "texstorage.h"
+#include "textureview.h"
+#include "stdbool.h"
+#include "mtypes.h"
+
+/* Table 3.X.2 (Compatible internal formats for TextureView)
+ ---------------------------------------------------------------------------
+ | Class | Internal formats |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_128_BITS | RGBA32F, RGBA32UI, RGBA32I |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_96_BITS | RGB32F, RGB32UI, RGB32I |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_64_BITS | RGBA16F, RG32F, RGBA16UI, RG32UI, RGBA16I, |
+ | | RG32I, RGBA16, RGBA16_SNORM |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_48_BITS | RGB16, RGB16_SNORM, RGB16F, RGB16UI, RGB16I |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_32_BITS | RG16F, R11F_G11F_B10F, R32F, |
+ | | RGB10_A2UI, RGBA8UI, RG16UI, R32UI, |
+ | | RGBA8I, RG16I, R32I, RGB10_A2, RGBA8, RG16, |
+ | | RGBA8_SNORM, RG16_SNORM, SRGB8_ALPHA8, RGB9_E5 |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_24_BITS | RGB8, RGB8_SNORM, SRGB8, RGB8UI, RGB8I |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_16_BITS | R16F, RG8UI, R16UI, RG8I, R16I, RG8, R16, |
+ | | RG8_SNORM, R16_SNORM |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_8_BITS | R8UI, R8I, R8, R8_SNORM |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_RGTC1_RED | COMPRESSED_RED_RGTC1, |
+ | | COMPRESSED_SIGNED_RED_RGTC1 |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_RGTC2_RG | COMPRESSED_RG_RGTC2, |
+ | | COMPRESSED_SIGNED_RG_RGTC2 |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_BPTC_UNORM | COMPRESSED_RGBA_BPTC_UNORM, |
+ | | COMPRESSED_SRGB_ALPHA_BPTC_UNORM |
+ ---------------------------------------------------------------------------
+ | VIEW_CLASS_BPTC_FLOAT | COMPRESSED_RGB_BPTC_SIGNED_FLOAT, |
+ | | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT |
+ ---------------------------------------------------------------------------
+ */
+struct internal_format_class_info {
+ GLenum view_class;
+ GLenum internal_format;
+};
+static const struct internal_format_class_info compatible_internal_formats[] = {
+ {GL_VIEW_CLASS_128_BITS, GL_RGBA32F},
+ {GL_VIEW_CLASS_128_BITS, GL_RGBA32UI},
+ {GL_VIEW_CLASS_128_BITS, GL_RGBA32I},
+ {GL_VIEW_CLASS_96_BITS, GL_RGB32F},
+ {GL_VIEW_CLASS_96_BITS, GL_RGB32UI},
+ {GL_VIEW_CLASS_96_BITS, GL_RGB32I},
+ {GL_VIEW_CLASS_64_BITS, GL_RGBA16F},
+ {GL_VIEW_CLASS_64_BITS, GL_RG32F},
+ {GL_VIEW_CLASS_64_BITS, GL_RGBA16UI},
+ {GL_VIEW_CLASS_64_BITS, GL_RG32UI},
+ {GL_VIEW_CLASS_64_BITS, GL_RGBA16I},
+ {GL_VIEW_CLASS_64_BITS, GL_RG32I},
+ {GL_VIEW_CLASS_64_BITS, GL_RGBA16},
+ {GL_VIEW_CLASS_64_BITS, GL_RGBA16_SNORM},
+ {GL_VIEW_CLASS_48_BITS, GL_RGB16},
+ {GL_VIEW_CLASS_48_BITS, GL_RGB16_SNORM},
+ {GL_VIEW_CLASS_48_BITS, GL_RGB16F},
+ {GL_VIEW_CLASS_48_BITS, GL_RGB16UI},
+ {GL_VIEW_CLASS_48_BITS, GL_RGB16I},
+ {GL_VIEW_CLASS_32_BITS, GL_RG16F},
+ {GL_VIEW_CLASS_32_BITS, GL_R11F_G11F_B10F},
+ {GL_VIEW_CLASS_32_BITS, GL_R32F},
+ {GL_VIEW_CLASS_32_BITS, GL_RGB10_A2UI},
+ {GL_VIEW_CLASS_32_BITS, GL_RGBA8UI},
+ {GL_VIEW_CLASS_32_BITS, GL_RG16UI},
+ {GL_VIEW_CLASS_32_BITS, GL_R32UI},
+ {GL_VIEW_CLASS_32_BITS, GL_RGBA8I},
+ {GL_VIEW_CLASS_32_BITS, GL_RG16I},
+ {GL_VIEW_CLASS_32_BITS, GL_R32I},
+ {GL_VIEW_CLASS_32_BITS, GL_RGB10_A2},
+ {GL_VIEW_CLASS_32_BITS, GL_RGBA8},
+ {GL_VIEW_CLASS_32_BITS, GL_RG16},
+ {GL_VIEW_CLASS_32_BITS, GL_RGBA8_SNORM},
+ {GL_VIEW_CLASS_32_BITS, GL_RG16_SNORM},
+ {GL_VIEW_CLASS_32_BITS, GL_SRGB8_ALPHA8},
+ {GL_VIEW_CLASS_32_BITS, GL_RGB9_E5},
+ {GL_VIEW_CLASS_24_BITS, GL_RGB8},
+ {GL_VIEW_CLASS_24_BITS, GL_RGB8_SNORM},
+ {GL_VIEW_CLASS_24_BITS, GL_SRGB8},
+ {GL_VIEW_CLASS_24_BITS, GL_RGB8UI},
+ {GL_VIEW_CLASS_24_BITS, GL_RGB8I},
+ {GL_VIEW_CLASS_16_BITS, GL_R16F},
+ {GL_VIEW_CLASS_16_BITS, GL_RG8UI},
+ {GL_VIEW_CLASS_16_BITS, GL_R16UI},
+ {GL_VIEW_CLASS_16_BITS, GL_RG8I},
+ {GL_VIEW_CLASS_16_BITS, GL_R16I},
+ {GL_VIEW_CLASS_16_BITS, GL_RG8},
+ {GL_VIEW_CLASS_16_BITS, GL_R16},
+ {GL_VIEW_CLASS_16_BITS, GL_RG8_SNORM},
+ {GL_VIEW_CLASS_16_BITS, GL_R16_SNORM},
+ {GL_VIEW_CLASS_8_BITS, GL_R8UI},
+ {GL_VIEW_CLASS_8_BITS, GL_R8I},
+ {GL_VIEW_CLASS_8_BITS, GL_R8},
+ {GL_VIEW_CLASS_8_BITS, GL_R8_SNORM},
+ {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_RED_RGTC1},
+ {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_SIGNED_RED_RGTC1},
+ {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_RG_RGTC2},
+ {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_SIGNED_RG_RGTC2},
+ {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB},
+ {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB},
+ {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB},
+ {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB},
+};
+
+static const struct internal_format_class_info s3tc_compatible_internal_formats[] = {
+ {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_RGB_S3TC_DXT1_EXT},
+ {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT},
+ {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT},
+ {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT},
+ {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT},
+ {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT},
+ {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT},
+ {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT},
+};
+
+/**
+ * Lookup format view class based on internalformat
+ * \return VIEW_CLASS if internalformat found in table, false otherwise.
+ */
+static GLenum
+lookup_view_class(struct gl_context *ctx, GLenum internalformat)
+{
+ GLuint i;
+
+ for (i = 0; i < ARRAY_SIZE(compatible_internal_formats); i++) {
+ if (compatible_internal_formats[i].internal_format == internalformat)
+ return compatible_internal_formats[i].view_class;
+ }
+
+ if (ctx->Extensions.EXT_texture_compression_s3tc && ctx->Extensions.EXT_texture_sRGB) {
+ for (i = 0; i < ARRAY_SIZE(s3tc_compatible_internal_formats); i++) {
+ if (s3tc_compatible_internal_formats[i].internal_format == internalformat)
+ return s3tc_compatible_internal_formats[i].view_class;
+ }
+ }
+ return GL_FALSE;
+}
+
+/**
+ * Initialize new texture's gl_texture_image structures. Will not call driver
+ * to allocate new space, simply record relevant layer, face, format, etc.
+ * \return GL_FALSE if any error, GL_TRUE otherwise.
+ */
+static GLboolean
+initialize_texture_fields(struct gl_context *ctx,
+ GLenum target,
+ struct gl_texture_object *texObj,
+ GLint levels,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum internalFormat, gl_format texFormat)
+{
+ const GLuint numFaces = _mesa_num_tex_faces(target);
+ GLint level, levelWidth = width, levelHeight = height, levelDepth = depth;
+ GLuint face;
+
+ /* Pretend we are bound to initialize the gl_texture_image structs */
+ texObj->Target = target;
+
+ /* Set up all the texture object's gl_texture_images */
+ for (level = 0; level < levels; level++) {
+ for (face = 0; face < numFaces; face++) {
+ struct gl_texture_image *texImage;
+ GLenum faceTarget = target;
+
+ if (target == GL_TEXTURE_CUBE_MAP)
+ faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
+
+ texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, level);
+
+ if (!texImage) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
+ return GL_FALSE;
+ }
+
+ _mesa_init_teximage_fields(ctx, texImage,
+ levelWidth, levelHeight, levelDepth,
+ 0, internalFormat, texFormat);
+ }
+
+ _mesa_next_mipmap_level_size(target, 0, levelWidth, levelHeight, levelDepth,
+ &levelWidth, &levelHeight, &levelDepth);
+ }
+
+ /* "unbind" */
+ texObj->Target = 0;
+
+ return GL_TRUE;
+}
+
+#define RETURN_IF_SUPPORTED(t) do { \
+ if (newTarget == GL_ ## t) \
+ return true; \
+} while (0)
+
+/**
+ * Check for compatible target
+ * If an error is found, record it with _mesa_error()
+ * \return false if any error, true otherwise.
+ */
+static bool
+target_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget)
+{
+ /*
+ * From ARB_texture_view spec:
+ ---------------------------------------------------------------------------------------------------------
+ | Original target | Valid new targets |
+ ---------------------------------------------------------------------------------------------------------
+ | TEXTURE_1D | TEXTURE_1D, TEXTURE_1D_ARRAY |
+ | ------------------------------------------------------------------------------------------------------- |
+ | TEXTURE_2D | TEXTURE_2D, TEXTURE_2D_ARRAY |
+ | ------------------------------------------------------------------------------------------------------- |
+ | TEXTURE_3D | TEXTURE_3D |
+ | ------------------------------------------------------------------------------------------------------- |
+ | TEXTURE_CUBE_MAP | TEXTURE_CUBE_MAP, TEXTURE_2D, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY |
+ | ------------------------------------------------------------------------------------------------------- |
+ | TEXTURE_RECTANGLE | TEXTURE_RECTANGLE |
+ | ------------------------------------------------------------------------------------------------------- |
+ | TEXTURE_BUFFER | <none> |
+ | ------------------------------------------------------------------------------------------------------- |
+ | TEXTURE_1D_ARRAY | TEXTURE_1D_ARRAY, TEXTURE_1D |
+ | ------------------------------------------------------------------------------------------------------- |
+ | TEXTURE_2D_ARRAY | TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP, TEXTURE_CUBE_MAP_ARRAY |
+ | ------------------------------------------------------------------------------------------------------- |
+ | TEXTURE_CUBE_MAP_ARRAY | TEXTURE_CUBE_MAP_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP |
+ | ------------------------------------------------------------------------------------------------------- |
+ | TEXTURE_2D_MULTISAMPLE | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY |
+ | ------------------------------------------------------------------------------------------------------- |
+ | TEXTURE_2D_MULTISAMPLE_ARRAY | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY |
+ ---------------------------------------------------------------------------------------------------------
+ */
+
+ switch (origTarget) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_1D_ARRAY:
+ RETURN_IF_SUPPORTED(TEXTURE_1D);
+ RETURN_IF_SUPPORTED(TEXTURE_1D_ARRAY);
+ break;
+ case GL_TEXTURE_2D:
+ RETURN_IF_SUPPORTED(TEXTURE_2D);
+ RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY);
+ break;
+ case GL_TEXTURE_3D:
+ RETURN_IF_SUPPORTED(TEXTURE_3D);
+ break;
+ case GL_TEXTURE_RECTANGLE:
+ RETURN_IF_SUPPORTED(TEXTURE_RECTANGLE);
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ RETURN_IF_SUPPORTED(TEXTURE_2D);
+ RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY);
+ RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP);
+ RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP_ARRAY);
+ break;
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE);
+ RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE_ARRAY);
+ break;
+ }
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(illegal target=%s)",
+ _mesa_lookup_enum_by_nr(newTarget));
+ return false;
+}
+#undef RETURN_IF_SUPPORTED
+
+/**
+ * Check for compatible format
+ * If an error is found, record it with _mesa_error()
+ * \return false if any error, true otherwise.
+ */
+static bool
+compatible_format(struct gl_context *ctx, const struct gl_texture_object *origTexObj,
+ GLenum internalformat)
+{
+ /* Level 0 of a texture created by glTextureStorage or glTextureView
+ * is always defined.
+ */
+ struct gl_texture_image *texImage = origTexObj->Image[0][0];
+ GLint origInternalFormat = texImage->InternalFormat;
+ unsigned int origViewClass, newViewClass;
+
+ /* The two textures' internal formats must be compatible according to
+ * Table 3.X.2 (Compatible internal formats for TextureView)
+ * if the internal format exists in that table the view class must match.
+ * The internal formats must be identical if not in that table,
+ * or an INVALID_OPERATION error is generated.
+ */
+ if (origInternalFormat == internalformat)
+ return true;
+
+ origViewClass = lookup_view_class(ctx, origInternalFormat);
+ newViewClass = lookup_view_class(ctx, internalformat);
+ if ((origViewClass == newViewClass) && origViewClass != false)
+ return true;
+
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glTextureView(internalformat %s not compatible with origtexture %s)",
+ _mesa_lookup_enum_by_nr(internalformat),
+ _mesa_lookup_enum_by_nr(origInternalFormat));
+ return false;
+}
+/**
+ * Helper function for TexStorage and teximagemultisample to set immutable
+ * texture state needed by ARB_texture_view.
+ */
+void
+_mesa_set_texture_view_state(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLenum target, GLuint levels)
+{
+ struct gl_texture_image *texImage;
+
+ /* Get a reference to what will become this View's base level */
+ texImage = _mesa_select_tex_image(ctx, texObj, target, 0);
+
+ /* When an immutable texture is created via glTexStorage or glTexImageMultisample,
+ * TEXTURE_IMMUTABLE_FORMAT becomes TRUE.
+ * TEXTURE_IMMUTABLE_LEVELS and TEXTURE_VIEW_NUM_LEVELS become levels.
+ * If the texture target is TEXTURE_1D_ARRAY then
+ * TEXTURE_VIEW_NUM_LAYERS becomes height.
+ * If the texture target is TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY,
+ * or TEXTURE_2D_MULTISAMPLE_ARRAY then TEXTURE_VIEW_NUM_LAYERS becomes depth.
+ * If the texture target is TEXTURE_CUBE_MAP, then
+ * TEXTURE_VIEW_NUM_LAYERS becomes 6.
+ * For any other texture target, TEXTURE_VIEW_NUM_LAYERS becomes 1.
+ *
+ * ARB_texture_multisample: Multisample textures do
+ * not have multiple image levels.
+ */
+
+ texObj->Immutable = GL_TRUE;
+ texObj->ImmutableLevels = levels;
+ texObj->MinLevel = 0;
+ texObj->NumLevels = levels;
+ texObj->MinLayer = 0;
+ texObj->NumLayers = 1;
+ switch (target) {
+ case GL_TEXTURE_1D_ARRAY:
+ texObj->NumLayers = texImage->Height;
+ break;
+
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ texObj->NumLevels = 1;
+ texObj->ImmutableLevels = 1;
+ break;
+
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ texObj->NumLevels = 1;
+ texObj->ImmutableLevels = 1;
+ /* fall through to set NumLayers */
+
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ texObj->NumLayers = texImage->Depth;
+ break;
+
+ case GL_TEXTURE_CUBE_MAP:
+ texObj->NumLayers = 6;
+ break;
+
+ }
+}
+
+/**
+ * glTextureView (ARB_texture_view)
+ * If an error is found, record it with _mesa_error()
+ * \return none.
+ */
+void GLAPIENTRY
+_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
+ GLenum internalformat,
+ GLuint minlevel, GLuint numlevels,
+ GLuint minlayer, GLuint numlayers)
+{
+ struct gl_texture_object *texObj;
+ struct gl_texture_object *origTexObj;
+ struct gl_texture_image *origTexImage;
+ GLuint newViewMinLevel, newViewMinLayer;
+ GLuint newViewNumLevels, newViewNumLayers;
+ GLsizei width, height, depth;
+ gl_format texFormat;
+ GLboolean sizeOK, dimensionsOK;
+ GLenum faceTarget;
+
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTextureView %d %s %d %s %d %d %d %d\n",
+ texture, _mesa_lookup_enum_by_nr(target), origtexture,
+ _mesa_lookup_enum_by_nr(internalformat),
+ minlevel, numlevels, minlayer, numlayers);
+
+ if (origtexture == 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", origtexture);
+ return;
+ }
+
+ /* Need original texture information to validate arguments */
+ origTexObj = _mesa_lookup_texture(ctx, origtexture);
+
+ /* If <origtexture> is not the name of a texture, INVALID_VALUE is generated. */
+ if (!origTexObj) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", origtexture);
+ return;
+ }
+
+ /* If <origtexture>'s TEXTURE_IMMUTABLE_FORMAT value is not TRUE,
+ * INVALID_OPERATION is generated.
+ */
+ if (!origTexObj->Immutable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(origtexture not immutable)");
+ return;
+ }
+
+ /* If <texture> is 0, INVALID_VALUE is generated. */
+ if (texture == 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(texture = 0)");
+ return;
+ }
+
+ /* If <texture> is not a valid name returned by GenTextures,
+ * the error INVALID_OPERATION is generated.
+ */
+ texObj = _mesa_lookup_texture(ctx, texture);
+ if (texObj == NULL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(texture = %u non-gen name)", texture);
+ return;
+ }
+
+ /* If <texture> has already been bound and given a target, then
+ * the error INVALID_OPERATION is generated.
+ */
+ if (texObj->Target) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(texture = %u already bound)", texture);
+ return;
+ }
+
+ /* Check for compatible target */
+ if (!target_valid(ctx, origTexObj->Target, target)) {
+ return; /* error was recorded */
+ }
+
+ /* minlevel and minlayer are relative to the view of origtexture
+ * If minlevel or minlayer is greater than level or layer, respectively,
+ * of origtexture return INVALID_VALUE.
+ */
+ newViewMinLevel = origTexObj->MinLevel + minlevel;
+ newViewMinLayer = origTexObj->MinLayer + minlayer;
+ if (newViewMinLevel >= (origTexObj->MinLevel + origTexObj->NumLevels)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTextureView(new minlevel (%d) > orig minlevel (%d) + orig numlevels (%d))",
+ newViewMinLevel, origTexObj->MinLevel, origTexObj->NumLevels);
+ return;
+ }
+
+ if (newViewMinLayer >= (origTexObj->MinLayer + origTexObj->NumLayers)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTextureView(new minlayer (%d) > orig minlayer (%d) + orig numlayers (%d))",
+ newViewMinLayer, origTexObj->MinLayer, origTexObj->NumLayers);
+ return;
+ }
+
+ if (!compatible_format(ctx, origTexObj, internalformat)) {
+ return; /* Error logged */
+ }
+
+ texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
+ internalformat, GL_NONE, GL_NONE);
+ assert(texFormat != MESA_FORMAT_NONE);
+ if (texFormat == MESA_FORMAT_NONE) return;
+
+ newViewNumLevels = MIN2(numlevels, origTexObj->NumLevels - minlevel);
+ newViewNumLayers = MIN2(numlayers, origTexObj->NumLayers - minlayer);
+
+ faceTarget = origTexObj->Target;
+ if (faceTarget == GL_TEXTURE_CUBE_MAP)
+ faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + minlayer;
+
+ /* Get a reference to what will become this View's base level */
+ origTexImage = _mesa_select_tex_image(ctx, origTexObj,
+ faceTarget, minlevel);
+ width = origTexImage->Width;
+ height = origTexImage->Height;
+ depth = origTexImage->Depth;
+
+ /* Adjust width, height, depth to be appropriate for new target */
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_3D:
+ break;
+
+ case GL_TEXTURE_1D_ARRAY:
+ height = (GLsizei) newViewNumLayers;
+ break;
+
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_CUBE_MAP:
+ depth = 1;
+ break;
+
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ depth = newViewNumLayers;
+ break;
+ }
+
+ /* If the dimensions of the original texture are larger than the maximum
+ * supported dimensions of the new target, the error INVALID_OPERATION is
+ * generated. For example, if the original texture has a TEXTURE_2D_ARRAY
+ * target and its width is greater than MAX_CUBE_MAP_TEXTURE_SIZE, an error
+ * will be generated if TextureView is called to create a TEXTURE_CUBE_MAP
+ * view.
+ */
+ dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
+ width, height, depth, 0);
+ if (!dimensionsOK) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid width or height or depth)");
+ return;
+ }
+
+ sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat,
+ width, height, depth, 0);
+ if (!sizeOK) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid texture size)");
+ return;
+ }
+
+ /* If <target> is TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_RECTANGLE,
+ * or TEXTURE_2D_MULTISAMPLE and <numlayers> does not equal 1, the error
+ * INVALID_VALUE is generated.
+ */
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ if (numlayers != 1) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)", numlayers);
+ return;
+ }
+ break;
+
+ case GL_TEXTURE_CUBE_MAP:
+ /* If the new texture's target is TEXTURE_CUBE_MAP, the clamped <numlayers>
+ * must be equal to 6.
+ */
+ if (newViewNumLayers != 6) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(clamped numlayers %d != 6)",
+ newViewNumLayers);
+ return;
+ }
+ break;
+
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ /* If the new texture's target is TEXTURE_CUBE_MAP_ARRAY,
+ * then <numlayers> counts layer-faces rather than layers,
+ * and the clamped <numlayers> must be a multiple of 6.
+ * Otherwise, the error INVALID_VALUE is generated.
+ */
+ if ((newViewNumLayers % 6) != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glTextureView(clamped numlayers %d is not a multiple of 6)",
+ newViewNumLayers);
+ return;
+ }
+ break;
+ }
+
+ /* If the new texture's target is TEXTURE_CUBE_MAP or
+ * TEXTURE_CUBE_MAP_ARRAY, the width and height of the original texture's
+ * levels must be equal otherwise the error INVALID_OPERATION is generated.
+ */
+ if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
+ (origTexImage->Width != origTexImage->Height)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(origtexture width (%d) != height (%d))",
+ origTexImage->Width, origTexImage->Height);
+ return;
+ }
+
+ /* When the original texture's target is TEXTURE_CUBE_MAP, the layer
+ * parameters are interpreted in the same order as if it were a
+ * TEXTURE_CUBE_MAP_ARRAY with 6 layer-faces.
+ */
+
+ /* If the internal format does not exactly match the internal format of the
+ * original texture, the contents of the memory are reinterpreted in the
+ * same manner as for image bindings described in
+ * section 3.9.20 (Texture Image Loads and Stores).
+ */
+
+ /* TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL are interpreted
+ * relative to the view and not relative to the original data store.
+ */
+
+ if (!initialize_texture_fields(ctx, target, texObj, newViewNumLevels,
+ width, height, depth,
+ internalformat, texFormat)) {
+ return; /* Already recorded error */
+ }
+
+ texObj->MinLevel = newViewMinLevel;
+ texObj->MinLayer = newViewMinLayer;
+ texObj->NumLevels = newViewNumLevels;
+ texObj->NumLayers = newViewNumLayers;
+ texObj->Immutable = GL_TRUE;
+ texObj->ImmutableLevels = origTexObj->ImmutableLevels;
+ texObj->Target = target;
+
+ if (ctx->Driver.TextureView != NULL && !ctx->Driver.TextureView(ctx, texObj, origTexObj)) {
+ return; /* driver recorded error */
+ }
+}
diff --git a/mesalib/src/mesa/main/textureview.h b/mesalib/src/mesa/main/textureview.h
new file mode 100644
index 000000000..3088ac193
--- /dev/null
+++ b/mesalib/src/mesa/main/textureview.h
@@ -0,0 +1,43 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2012-2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Courtney Goeltzenleuchter <courtney@lunarg.com>
+ */
+
+
+#ifndef TEXTUREVIEW_H
+#define TEXTUREVIEW_H
+
+
+extern void GLAPIENTRY
+_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
+ GLenum internalformat,
+ GLuint minlevel, GLuint numlevels,
+ GLuint minlayer, GLuint numlayers);
+
+extern void
+_mesa_set_texture_view_state(struct gl_context *ctx, struct gl_texture_object *texObj,
+ GLenum target, GLuint levels);
+
+#endif /* TEXTUREVIEW_H */
diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c
index 55411faf8..00eeca764 100644
--- a/mesalib/src/mesa/main/version.c
+++ b/mesalib/src/mesa/main/version.c
@@ -224,7 +224,6 @@ compute_version(struct gl_context *ctx)
(ctx->Extensions.EXT_stencil_two_side
|| ctx->Extensions.ATI_separate_stencil));
const GLboolean ver_2_1 = (ver_2_0 &&
- ctx->Const.GLSLVersion >= 120 &&
ctx->Extensions.EXT_pixel_buffer_object &&
ctx->Extensions.EXT_texture_sRGB);
const GLboolean ver_3_0 = (ver_2_1 &&
diff --git a/mesalib/src/mesa/math/m_matrix.c b/mesalib/src/mesa/math/m_matrix.c
index 290231527..274f969d2 100644
--- a/mesalib/src/mesa/math/m_matrix.c
+++ b/mesalib/src/mesa/math/m_matrix.c
@@ -1488,14 +1488,11 @@ _math_matrix_ctr( GLmatrix *m )
void
_math_matrix_dtr( GLmatrix *m )
{
- if (m->m) {
- _mesa_align_free( m->m );
- m->m = NULL;
- }
- if (m->inv) {
- _mesa_align_free( m->inv );
- m->inv = NULL;
- }
+ _mesa_align_free( m->m );
+ m->m = NULL;
+
+ _mesa_align_free( m->inv );
+ m->inv = NULL;
}
/*@}*/
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index c833a12f2..23d479c32 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -681,11 +681,11 @@ ir_to_mesa_visitor::visit(ir_variable *ir)
if (strcmp(ir->name, "gl_FragCoord") == 0) {
struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
- fp->OriginUpperLeft = ir->origin_upper_left;
- fp->PixelCenterInteger = ir->pixel_center_integer;
+ fp->OriginUpperLeft = ir->data.origin_upper_left;
+ fp->PixelCenterInteger = ir->data.pixel_center_integer;
}
- if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
+ if (ir->data.mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
unsigned int i;
const ir_state_slot *const slots = ir->state_slots;
assert(ir->state_slots != NULL);
@@ -759,49 +759,10 @@ ir_to_mesa_visitor::visit(ir_variable *ir)
void
ir_to_mesa_visitor::visit(ir_loop *ir)
{
- ir_dereference_variable *counter = NULL;
-
- if (ir->counter != NULL)
- counter = new(mem_ctx) ir_dereference_variable(ir->counter);
-
- if (ir->from != NULL) {
- assert(ir->counter != NULL);
-
- ir_assignment *a =
- new(mem_ctx) ir_assignment(counter, ir->from, NULL);
-
- a->accept(this);
- }
-
emit(NULL, OPCODE_BGNLOOP);
- if (ir->to) {
- ir_expression *e =
- new(mem_ctx) ir_expression(ir->cmp, glsl_type::bool_type,
- counter, ir->to);
- ir_if *if_stmt = new(mem_ctx) ir_if(e);
-
- ir_loop_jump *brk =
- new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_break);
-
- if_stmt->then_instructions.push_tail(brk);
-
- if_stmt->accept(this);
- }
-
visit_exec_list(&ir->body_instructions, this);
- if (ir->increment) {
- ir_expression *e =
- new(mem_ctx) ir_expression(ir_binop_add, counter->type,
- counter, ir->increment);
-
- ir_assignment *a =
- new(mem_ctx) ir_assignment(counter, e, NULL);
-
- a->accept(this);
- }
-
emit(NULL, OPCODE_ENDLOOP);
}
@@ -1567,10 +1528,10 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
ir_variable *var = ir->var;
if (!entry) {
- switch (var->mode) {
+ switch (var->data.mode) {
case ir_var_uniform:
entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM,
- var->location);
+ var->data.location);
this->variables.push_tail(entry);
break;
case ir_var_shader_in:
@@ -1579,21 +1540,21 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
* user-assigned generic attributes (glBindVertexLocation),
* and user-defined varyings.
*/
- assert(var->location != -1);
+ assert(var->data.location != -1);
entry = new(mem_ctx) variable_storage(var,
PROGRAM_INPUT,
- var->location);
+ var->data.location);
break;
case ir_var_shader_out:
- assert(var->location != -1);
+ assert(var->data.location != -1);
entry = new(mem_ctx) variable_storage(var,
PROGRAM_OUTPUT,
- var->location);
+ var->data.location);
break;
case ir_var_system_value:
entry = new(mem_ctx) variable_storage(var,
PROGRAM_SYSTEM_VALUE,
- var->location);
+ var->data.location);
break;
case ir_var_auto:
case ir_var_temporary:
@@ -2443,7 +2404,7 @@ public:
this->idx = -1;
this->program_resource_visitor::process(var);
- var->location = this->idx;
+ var->data.location = this->idx;
}
private:
@@ -2538,7 +2499,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
foreach_list(node, sh->ir) {
ir_variable *var = ((ir_instruction *) node)->as_variable();
- if ((var == NULL) || (var->mode != ir_var_uniform)
+ if ((var == NULL) || (var->data.mode != ir_var_uniform)
|| var->is_in_uniform_block() || (strncmp(var->name, "gl_", 3) == 0))
continue;
diff --git a/mesalib/src/mesa/program/prog_parameter.c b/mesalib/src/mesa/program/prog_parameter.c
index 4d9cf08d2..54531d255 100644
--- a/mesalib/src/mesa/program/prog_parameter.c
+++ b/mesalib/src/mesa/program/prog_parameter.c
@@ -83,8 +83,7 @@ _mesa_free_parameter_list(struct gl_program_parameter_list *paramList)
free((void *)paramList->Parameters[i].Name);
}
free(paramList->Parameters);
- if (paramList->ParameterValues)
- _mesa_align_free(paramList->ParameterValues);
+ _mesa_align_free(paramList->ParameterValues);
free(paramList);
}
diff --git a/mesalib/src/mesa/program/program.c b/mesalib/src/mesa/program/program.c
index 01f8c6f11..cdf1c03fa 100644
--- a/mesalib/src/mesa/program/program.c
+++ b/mesalib/src/mesa/program/program.c
@@ -1049,6 +1049,14 @@ _mesa_get_min_invocations_per_fragment(struct gl_context *ctx,
* has no effect."
*/
if (ctx->Multisample.Enabled) {
+ /* The ARB_gpu_shader5 specification says:
+ *
+ * "Use of the "sample" qualifier on a fragment shader input
+ * forces per-sample shading"
+ */
+ if (prog->IsSample)
+ return MAX2(ctx->DrawBuffer->Visual.samples, 1);
+
if (prog->Base.SystemValuesRead & (SYSTEM_BIT_SAMPLE_ID |
SYSTEM_BIT_SAMPLE_POS))
return MAX2(ctx->DrawBuffer->Visual.samples, 1);
diff --git a/mesalib/src/mesa/program/program_parse_extra.c b/mesalib/src/mesa/program/program_parse_extra.c
index e8e1912eb..a9e364045 100644
--- a/mesalib/src/mesa/program/program_parse_extra.c
+++ b/mesalib/src/mesa/program/program_parse_extra.c
@@ -256,15 +256,6 @@ _mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
return 1;
}
}
- } else if (strncmp(option, "MESA_", 5) == 0) {
- option += 5;
-
- if (strcmp(option, "texture_array") == 0) {
- if (state->ctx->Extensions.MESA_texture_array) {
- state->option.TexArray = 1;
- return 1;
- }
- }
}
return 0;
diff --git a/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c b/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c
index c752640f4..51f079cda 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -44,56 +44,6 @@
/**
- * When doing GL render to texture, we have to be sure that finalize_texture()
- * didn't yank out the pipe_resource that we earlier created a surface for.
- * Check for that here and create a new surface if needed.
- */
-static void
-update_renderbuffer_surface(struct st_context *st,
- struct st_renderbuffer *strb)
-{
- struct pipe_context *pipe = st->pipe;
- struct pipe_resource *resource = strb->rtt ? strb->rtt->pt : strb->texture;
- int rtt_width = strb->Base.Width;
- int rtt_height = strb->Base.Height;
- enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format : util_format_linear(resource->format);
-
- if (!strb->surface ||
- strb->surface->texture->nr_samples != strb->Base.NumSamples ||
- strb->surface->format != format ||
- strb->surface->texture != resource ||
- strb->surface->width != rtt_width ||
- strb->surface->height != rtt_height) {
- GLuint level;
- /* find matching mipmap level size */
- for (level = 0; level <= resource->last_level; level++) {
- if (u_minify(resource->width0, level) == rtt_width &&
- u_minify(resource->height0, level) == rtt_height) {
- struct pipe_surface surf_tmpl;
- memset(&surf_tmpl, 0, sizeof(surf_tmpl));
- surf_tmpl.format = format;
- surf_tmpl.u.tex.level = level;
- surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
- surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
-
- pipe_surface_reference(&strb->surface, NULL);
-
- strb->surface = pipe->create_surface(pipe,
- resource,
- &surf_tmpl);
-#if 0
- printf("-- alloc new surface %d x %d into tex %p\n",
- strb->surface->width, strb->surface->height,
- texture);
-#endif
- break;
- }
- }
- }
-}
-
-
-/**
* Update framebuffer state (color, depth, stencil, etc. buffers)
*/
static void
@@ -121,10 +71,10 @@ update_framebuffer_state( struct st_context *st )
if (strb) {
/*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/
- if (strb->rtt ||
+ if (strb->is_rtt ||
(strb->texture && util_format_is_srgb(strb->texture->format))) {
/* rendering to a GL texture, may have to update surface */
- update_renderbuffer_surface(st, strb);
+ st_update_renderbuffer_surface(st, strb);
}
if (strb->surface) {
@@ -144,9 +94,9 @@ update_framebuffer_state( struct st_context *st )
*/
strb = st_renderbuffer(fb->Attachment[BUFFER_DEPTH].Renderbuffer);
if (strb) {
- if (strb->rtt) {
+ if (strb->is_rtt) {
/* rendering to a GL texture, may have to update surface */
- update_renderbuffer_surface(st, strb);
+ st_update_renderbuffer_surface(st, strb);
}
pipe_surface_reference(&framebuffer->zsbuf, strb->surface);
}
diff --git a/mesalib/src/mesa/state_tracker/st_atom_sampler.c b/mesalib/src/mesa/state_tracker/st_atom_sampler.c
index 302e12981..57670ce25 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_sampler.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_sampler.c
@@ -130,15 +130,20 @@ convert_sampler(struct st_context *st,
struct pipe_sampler_state *sampler,
GLuint texUnit)
{
- struct gl_texture_object *texobj;
+ const struct gl_texture_object *texobj;
struct gl_context *ctx = st->ctx;
struct gl_sampler_object *msamp;
+ const struct gl_texture_image *teximg;
+ GLenum texBaseFormat;
texobj = ctx->Texture.Unit[texUnit]._Current;
if (!texobj) {
texobj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX);
}
+ teximg = texobj->Image[0][texobj->BaseLevel];
+ texBaseFormat = teximg ? teximg->_BaseFormat : GL_RGBA;
+
msamp = _mesa_get_samplerobj(ctx, texUnit);
memset(sampler, 0, sizeof(*sampler));
@@ -170,21 +175,15 @@ convert_sampler(struct st_context *st,
assert(sampler->min_lod <= sampler->max_lod);
}
+ /* For non-black borders... */
if (msamp->BorderColor.ui[0] ||
msamp->BorderColor.ui[1] ||
msamp->BorderColor.ui[2] ||
msamp->BorderColor.ui[3]) {
- struct st_texture_object *stobj = st_texture_object(texobj);
- struct gl_texture_image *teximg;
- GLboolean is_integer = GL_FALSE;
+ const struct st_texture_object *stobj = st_texture_object_const(texobj);
+ const GLboolean is_integer = texobj->_IsIntegerFormat;
union pipe_color_union border_color;
- teximg = texobj->Image[0][texobj->BaseLevel];
-
- if (teximg) {
- is_integer = _mesa_is_enum_format_integer(teximg->InternalFormat);
- }
-
if (st->apply_texture_swizzle_to_border_color && stobj->sampler_view) {
const unsigned char swz[4] =
{
@@ -196,25 +195,26 @@ convert_sampler(struct st_context *st,
st_translate_color(&msamp->BorderColor,
&border_color,
- teximg ? teximg->_BaseFormat : GL_RGBA, is_integer);
+ texBaseFormat, is_integer);
util_format_apply_color_swizzle(&sampler->border_color,
&border_color, swz, is_integer);
} else {
st_translate_color(&msamp->BorderColor,
&sampler->border_color,
- teximg ? teximg->_BaseFormat : GL_RGBA, is_integer);
+ texBaseFormat, is_integer);
}
}
sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ?
0 : (GLuint) msamp->MaxAnisotropy);
- /* only care about ARB_shadow, not SGI shadow */
- if (msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
+ /* If sampling a depth texture and using shadow comparison */
+ if ((texBaseFormat == GL_DEPTH_COMPONENT ||
+ texBaseFormat == GL_DEPTH_STENCIL) &&
+ msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
- sampler->compare_func
- = st_compare_func_to_pipe(msamp->CompareFunc);
+ sampler->compare_func = st_compare_func_to_pipe(msamp->CompareFunc);
}
sampler->seamless_cube_map =
diff --git a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
index 7fa4cbdc4..230ab5449 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -422,6 +422,9 @@ st_bufferobj_validate_usage(struct st_context *st,
void
st_init_bufferobject_functions(struct dd_function_table *functions)
{
+ /* plug in default driver fallbacks (such as for ClearBufferSubData) */
+ _mesa_init_buffer_object_functions(functions);
+
functions->NewBufferObject = st_bufferobj_alloc;
functions->DeleteBuffer = st_bufferobj_free;
functions->BufferData = st_bufferobj_data;
diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c
index 8da664afb..887e58bd9 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_clear.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c
@@ -51,6 +51,7 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "util/u_format.h"
+#include "util/u_framebuffer.h"
#include "util/u_inlines.h"
#include "util/u_simple_shaders.h"
#include "util/u_draw_quad.h"
@@ -129,6 +130,26 @@ set_vertex_shader(struct st_context *st)
}
+static void
+set_vertex_shader_layered(struct st_context *st)
+{
+ struct pipe_context *pipe = st->pipe;
+
+ if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) ||
+ !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) {
+ assert(!"Got layered clear, but the VS layer output is unsupported");
+ set_vertex_shader(st);
+ return;
+ }
+
+ if (!st->clear.vs_layered) {
+ st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe);
+ }
+
+ cso_set_vertex_shader_handle(st->cso_context, st->clear.vs_layered);
+}
+
+
/**
* Draw a screen-aligned quadrilateral.
* Coords are clip coords with y=0=bottom.
@@ -136,15 +157,19 @@ set_vertex_shader(struct st_context *st)
static void
draw_quad(struct st_context *st,
float x0, float y0, float x1, float y1, GLfloat z,
+ unsigned num_instances,
const union pipe_color_union *color)
{
- struct pipe_context *pipe = st->pipe;
- struct pipe_resource *vbuf = NULL;
- GLuint i, offset;
+ struct cso_context *cso = st->cso_context;
+ struct pipe_vertex_buffer vb = {0};
+ GLuint i;
float (*vertices)[2][4]; /**< vertex pos + color */
+ vb.stride = 8 * sizeof(float);
+
if (u_upload_alloc(st->uploader, 0, 4 * sizeof(vertices[0]),
- &offset, &vbuf, (void **) &vertices) != PIPE_OK) {
+ &vb.buffer_offset, &vb.buffer,
+ (void **) &vertices) != PIPE_OK) {
return;
}
@@ -174,16 +199,10 @@ draw_quad(struct st_context *st,
u_upload_unmap(st->uploader);
/* draw */
- util_draw_vertex_buffer(pipe,
- st->cso_context,
- vbuf,
- cso_get_aux_vertex_buffer_slot(st->cso_context),
- offset,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
-
- pipe_resource_reference(&vbuf, NULL);
+ cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso), 1, &vb);
+ cso_draw_arrays_instanced(cso, PIPE_PRIM_TRIANGLE_FAN, 0, 4,
+ 0, num_instances);
+ pipe_resource_reference(&vb.buffer, NULL);
}
@@ -194,8 +213,7 @@ draw_quad(struct st_context *st,
* ctx->DrawBuffer->_X/Ymin/max fields.
*/
static void
-clear_with_quad(struct gl_context *ctx,
- GLboolean color, GLboolean depth, GLboolean stencil)
+clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
{
struct st_context *st = st_context(ctx);
const struct gl_framebuffer *fb = ctx->DrawBuffer;
@@ -205,7 +223,8 @@ clear_with_quad(struct gl_context *ctx,
const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax / fb_width * 2.0f - 1.0f;
const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin / fb_height * 2.0f - 1.0f;
const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax / fb_height * 2.0f - 1.0f;
- union pipe_color_union clearColor;
+ unsigned num_layers =
+ util_framebuffer_get_num_layers(&st->state.framebuffer);
/*
printf("%s %s%s%s %f,%f %f,%f\n", __FUNCTION__,
@@ -233,7 +252,7 @@ clear_with_quad(struct gl_context *ctx,
{
struct pipe_blend_state blend;
memset(&blend, 0, sizeof(blend));
- if (color) {
+ if (clear_buffers & PIPE_CLEAR_COLOR) {
int num_buffers = ctx->Extensions.EXT_draw_buffers2 ?
ctx->DrawBuffer->_NumColorDrawBuffers : 1;
int i;
@@ -241,6 +260,9 @@ clear_with_quad(struct gl_context *ctx,
blend.independent_blend_enable = num_buffers > 1;
for (i = 0; i < num_buffers; i++) {
+ if (!(clear_buffers & (PIPE_CLEAR_COLOR0 << i)))
+ continue;
+
if (ctx->Color.ColorMask[i][0])
blend.rt[i].colormask |= PIPE_MASK_R;
if (ctx->Color.ColorMask[i][1])
@@ -261,13 +283,13 @@ clear_with_quad(struct gl_context *ctx,
{
struct pipe_depth_stencil_alpha_state depth_stencil;
memset(&depth_stencil, 0, sizeof(depth_stencil));
- if (depth) {
+ if (clear_buffers & PIPE_CLEAR_DEPTH) {
depth_stencil.depth.enabled = 1;
depth_stencil.depth.writemask = 1;
depth_stencil.depth.func = PIPE_FUNC_ALWAYS;
}
- if (stencil) {
+ if (clear_buffers & PIPE_CLEAR_STENCIL) {
struct pipe_stencil_ref stencil_ref;
memset(&stencil_ref, 0, sizeof(stencil_ref));
depth_stencil.stencil[0].enabled = 1;
@@ -305,21 +327,20 @@ clear_with_quad(struct gl_context *ctx,
}
set_fragment_shader(st);
- set_vertex_shader(st);
cso_set_geometry_shader_handle(st->cso_context, NULL);
- if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
- GLboolean is_integer = _mesa_is_enum_format_integer(rb->InternalFormat);
+ if (num_layers > 1)
+ set_vertex_shader_layered(st);
+ else
+ set_vertex_shader(st);
- st_translate_color(&ctx->Color.ClearColor,
- &clearColor,
- ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
- is_integer);
- }
+ /* We can't translate the clear color to the colorbuffer format,
+ * because different colorbuffers may have different formats.
+ */
/* draw quad matching scissor rect */
- draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, &clearColor);
+ draw_quad(st, x0, y0, x1, y1, (GLfloat) ctx->Depth.Clear, num_layers,
+ (union pipe_color_union*)&ctx->Color.ClearColor);
/* Restore pipe state */
cso_restore_blend(st->cso_context);
@@ -352,6 +373,19 @@ is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
/**
+ * Return if all of the color channels are masked.
+ */
+static INLINE GLboolean
+is_color_disabled(struct gl_context *ctx, int i)
+{
+ return !ctx->Color.ColorMask[i][0] &&
+ !ctx->Color.ColorMask[i][1] &&
+ !ctx->Color.ColorMask[i][2] &&
+ !ctx->Color.ColorMask[i][3];
+}
+
+
+/**
* Return if any of the color channels are masked.
*/
static INLINE GLboolean
@@ -408,11 +442,14 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
if (!strb || !strb->surface)
continue;
+ if (is_color_disabled(ctx, colormask_index))
+ continue;
+
if (is_scissor_enabled(ctx, rb) ||
is_color_masked(ctx, colormask_index))
- quad_buffers |= PIPE_CLEAR_COLOR;
+ quad_buffers |= PIPE_CLEAR_COLOR0 << i;
else
- clear_buffers |= PIPE_CLEAR_COLOR;
+ clear_buffers |= PIPE_CLEAR_COLOR0 << i;
}
}
}
@@ -445,24 +482,13 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
*/
if (quad_buffers) {
quad_buffers |= clear_buffers;
- clear_with_quad(ctx,
- quad_buffers & PIPE_CLEAR_COLOR,
- quad_buffers & PIPE_CLEAR_DEPTH,
- quad_buffers & PIPE_CLEAR_STENCIL);
+ clear_with_quad(ctx, quad_buffers);
} else if (clear_buffers) {
- union pipe_color_union clearColor;
-
- if (ctx->DrawBuffer->_ColorDrawBuffers[0]) {
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
- GLboolean is_integer = _mesa_is_enum_format_integer(rb->InternalFormat);
-
- st_translate_color(&ctx->Color.ClearColor,
- &clearColor,
- ctx->DrawBuffer->_ColorDrawBuffers[0]->_BaseFormat,
- is_integer);
- }
-
- st->pipe->clear(st->pipe, clear_buffers, &clearColor,
+ /* We can't translate the clear color to the colorbuffer format,
+ * because different colorbuffers may have different formats.
+ */
+ st->pipe->clear(st->pipe, clear_buffers,
+ (union pipe_color_union*)&ctx->Color.ClearColor,
ctx->Depth.Clear, ctx->Stencil.Clear);
}
if (mask & BUFFER_BIT_ACCUM)
diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
index 2ce4728ad..3058dfb5b 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -878,7 +878,8 @@ draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
}
stmap = pipe_transfer_map(pipe, strb->texture,
- strb->rtt_level, strb->rtt_face + strb->rtt_slice,
+ strb->surface->u.tex.level,
+ strb->surface->u.tex.first_layer,
usage, x, y,
width, height, &pt);
@@ -1263,8 +1264,8 @@ copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
/* map the stencil buffer */
drawMap = pipe_transfer_map(pipe,
rbDraw->texture,
- rbDraw->rtt_level,
- rbDraw->rtt_face + rbDraw->rtt_slice,
+ rbDraw->surface->u.tex.level,
+ rbDraw->surface->u.tex.first_layer,
usage, dstx, dsty,
width, height, &ptDraw);
@@ -1422,20 +1423,20 @@ blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy,
memset(&blit, 0, sizeof(blit));
blit.src.resource = rbRead->texture;
- blit.src.level = rbRead->rtt_level;
+ blit.src.level = rbRead->surface->u.tex.level;
blit.src.format = rbRead->texture->format;
blit.src.box.x = readX;
blit.src.box.y = readY;
- blit.src.box.z = rbRead->rtt_face + rbRead->rtt_slice;
+ blit.src.box.z = rbRead->surface->u.tex.first_layer;
blit.src.box.width = readW;
blit.src.box.height = readH;
blit.src.box.depth = 1;
blit.dst.resource = rbDraw->texture;
- blit.dst.level = rbDraw->rtt_level;
+ blit.dst.level = rbDraw->surface->u.tex.level;
blit.dst.format = rbDraw->texture->format;
blit.dst.box.x = drawX;
blit.dst.box.y = drawY;
- blit.dst.box.z = rbDraw->rtt_face + rbDraw->rtt_slice;
+ blit.dst.box.z = rbDraw->surface->u.tex.first_layer;
blit.dst.box.width = drawW;
blit.dst.box.height = drawH;
blit.dst.box.depth = 1;
@@ -1633,11 +1634,11 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
memset(&blit, 0, sizeof(blit));
blit.src.resource = rbRead->texture;
- blit.src.level = rbRead->rtt_level;
+ blit.src.level = rbRead->surface->u.tex.level;
blit.src.format = rbRead->texture->format;
blit.src.box.x = readX;
blit.src.box.y = readY;
- blit.src.box.z = rbRead->rtt_face + rbRead->rtt_slice;
+ blit.src.box.z = rbRead->surface->u.tex.first_layer;
blit.src.box.width = readW;
blit.src.box.height = readH;
blit.src.box.depth = 1;
diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c
index 20894825f..70baa9965 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c
@@ -389,6 +389,72 @@ st_bind_framebuffer(struct gl_context *ctx, GLenum target,
/**
+ * Create or update the pipe_surface of a FBO renderbuffer.
+ * This is usually called after st_finalize_texture.
+ */
+void
+st_update_renderbuffer_surface(struct st_context *st,
+ struct st_renderbuffer *strb)
+{
+ struct pipe_context *pipe = st->pipe;
+ struct pipe_resource *resource = strb->texture;
+ int rtt_width = strb->Base.Width;
+ int rtt_height = strb->Base.Height;
+ int rtt_depth = strb->Base.Depth;
+ enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format :
+ util_format_linear(resource->format);
+ unsigned first_layer, last_layer, level;
+
+ if (resource->target == PIPE_TEXTURE_1D_ARRAY) {
+ rtt_depth = rtt_height;
+ rtt_height = 1;
+ }
+
+ /* find matching mipmap level size */
+ for (level = 0; level <= resource->last_level; level++) {
+ if (u_minify(resource->width0, level) == rtt_width &&
+ u_minify(resource->height0, level) == rtt_height &&
+ (resource->target != PIPE_TEXTURE_3D ||
+ u_minify(resource->depth0, level) == rtt_depth)) {
+ break;
+ }
+ }
+ assert(level <= resource->last_level);
+
+ /* determine the layer bounds */
+ if (strb->rtt_layered) {
+ first_layer = 0;
+ last_layer = util_max_layer(strb->texture, level);
+ }
+ else {
+ first_layer =
+ last_layer = strb->rtt_face + strb->rtt_slice;
+ }
+
+ if (!strb->surface ||
+ strb->surface->texture->nr_samples != strb->Base.NumSamples ||
+ strb->surface->format != format ||
+ strb->surface->texture != resource ||
+ strb->surface->width != rtt_width ||
+ strb->surface->height != rtt_height ||
+ strb->surface->u.tex.level != level ||
+ strb->surface->u.tex.first_layer != first_layer ||
+ strb->surface->u.tex.last_layer != last_layer) {
+ /* create a new pipe_surface */
+ struct pipe_surface surf_tmpl;
+ memset(&surf_tmpl, 0, sizeof(surf_tmpl));
+ surf_tmpl.format = format;
+ surf_tmpl.u.tex.level = level;
+ surf_tmpl.u.tex.first_layer = first_layer;
+ surf_tmpl.u.tex.last_layer = last_layer;
+
+ pipe_surface_reference(&strb->surface, NULL);
+
+ strb->surface = pipe->create_surface(pipe, resource, &surf_tmpl);
+ }
+}
+
+/**
* Called by ctx->Driver.RenderTexture
*/
static void
@@ -401,8 +467,6 @@ st_render_texture(struct gl_context *ctx,
struct gl_renderbuffer *rb = att->Renderbuffer;
struct st_renderbuffer *strb = st_renderbuffer(rb);
struct pipe_resource *pt;
- struct st_texture_object *stObj;
- struct pipe_surface surf_tmpl;
if (!st_finalize_texture(ctx, pipe, att->Texture))
return;
@@ -410,31 +474,16 @@ st_render_texture(struct gl_context *ctx,
pt = st_get_texobj_resource(att->Texture);
assert(pt);
- /* get the texture for the texture object */
- stObj = st_texture_object(att->Texture);
-
/* point renderbuffer at texobject */
- strb->rtt = stObj;
- strb->rtt_level = att->TextureLevel;
+ strb->is_rtt = TRUE;
strb->rtt_face = att->CubeMapFace;
strb->rtt_slice = att->Zoffset;
-
- pipe_resource_reference( &strb->texture, pt );
+ strb->rtt_layered = att->Layered;
+ pipe_resource_reference(&strb->texture, pt);
pipe_surface_release(pipe, &strb->surface);
- assert(strb->rtt_level <= strb->texture->last_level);
-
- /* new surface for rendering into the texture */
- memset(&surf_tmpl, 0, sizeof(surf_tmpl));
- surf_tmpl.format = ctx->Color.sRGBEnabled
- ? strb->texture->format : util_format_linear(strb->texture->format);
- surf_tmpl.u.tex.level = strb->rtt_level;
- surf_tmpl.u.tex.first_layer = strb->rtt_face + strb->rtt_slice;
- surf_tmpl.u.tex.last_layer = strb->rtt_face + strb->rtt_slice;
- strb->surface = pipe->create_surface(pipe,
- strb->texture,
- &surf_tmpl);
+ st_update_renderbuffer_surface(st, strb);
strb->Base.Format = st_pipe_format_to_mesa_format(pt->format);
@@ -464,7 +513,7 @@ st_finish_render_texture(struct gl_context *ctx, struct gl_renderbuffer *rb)
if (!strb)
return;
- strb->rtt = NULL;
+ strb->is_rtt = FALSE;
/* restore previous framebuffer state */
st_invalidate_state(ctx, _NEW_BUFFERS);
@@ -706,8 +755,8 @@ st_MapRenderbuffer(struct gl_context *ctx,
map = pipe_transfer_map(pipe,
strb->texture,
- strb->rtt_level,
- strb->rtt_face + strb->rtt_slice,
+ strb->surface->u.tex.level,
+ strb->surface->u.tex.first_layer,
usage, x, y2, w, h, &strb->transfer);
if (map) {
if (invert) {
diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.h b/mesalib/src/mesa/state_tracker/st_cb_fbo.h
index f335c371b..88fccc298 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_fbo.h
+++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.h
@@ -58,8 +58,10 @@ struct st_renderbuffer
boolean software;
void *data;
- struct st_texture_object *rtt; /**< GL render to texture's texture */
- unsigned rtt_level, rtt_face, rtt_slice;
+ /* Inputs from Driver.RenderTexture, don't use directly. */
+ boolean is_rtt; /**< whether Driver.RenderTexture was called */
+ unsigned rtt_face, rtt_slice;
+ boolean rtt_layered; /**< whether glFramebufferTexture was called */
};
@@ -74,6 +76,10 @@ extern struct gl_renderbuffer *
st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw);
extern void
+st_update_renderbuffer_surface(struct st_context *st,
+ struct st_renderbuffer *strb);
+
+extern void
st_init_fbo_functions(struct dd_function_table *functions);
#endif /* ST_CB_FBO_H */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
index b5df58c03..7547dfd8b 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_readpixels.c
@@ -166,7 +166,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y,
}
blit.src.resource = src;
- blit.src.level = strb->rtt_level;
+ blit.src.level = strb->surface->u.tex.level;
blit.src.format = src_format;
blit.dst.resource = dst;
blit.dst.level = 0;
@@ -175,7 +175,7 @@ st_readpixels(struct gl_context *ctx, GLint x, GLint y,
blit.dst.box.x = 0;
blit.src.box.y = y;
blit.dst.box.y = 0;
- blit.src.box.z = strb->rtt_face + strb->rtt_slice;
+ blit.src.box.z = strb->surface->u.tex.first_layer;
blit.dst.box.z = 0;
blit.src.box.width = blit.dst.box.width = width;
blit.src.box.height = blit.dst.box.height = height;
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index faa9ee3f6..c09f34e37 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -175,10 +175,8 @@ st_FreeTextureImageBuffer(struct gl_context *ctx,
pipe_resource_reference(&stImage->pt, NULL);
}
- if (stImage->TexData) {
- _mesa_align_free(stImage->TexData);
- stImage->TexData = NULL;
- }
+ _mesa_align_free(stImage->TexData);
+ stImage->TexData = NULL;
}
@@ -1156,8 +1154,8 @@ fallback_copy_texsubimage(struct gl_context *ctx,
map = pipe_transfer_map(pipe,
strb->texture,
- strb->rtt_level,
- strb->rtt_face + strb->rtt_slice,
+ strb->surface->u.tex.level,
+ strb->surface->u.tex.first_layer,
PIPE_TRANSFER_READ,
srcX, srcY,
width, height, &src_trans);
diff --git a/mesalib/src/mesa/state_tracker/st_context.h b/mesalib/src/mesa/state_tracker/st_context.h
index ab89b4947..cd0a5ae98 100644
--- a/mesalib/src/mesa/state_tracker/st_context.h
+++ b/mesalib/src/mesa/state_tracker/st_context.h
@@ -178,6 +178,7 @@ struct st_context
struct pipe_viewport_state viewport;
void *vs;
void *fs;
+ void *vs_layered;
} clear;
/** used for anything using util_draw_vertex_buffer */
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index cd10a0c9d..5e4a3b398 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -406,7 +406,6 @@ void st_init_extensions(struct st_context *st)
{ o(NV_texture_barrier), PIPE_CAP_TEXTURE_BARRIER },
/* GL_NV_point_sprite is not supported by gallium because we don't
* support the GL_POINT_SPRITE_R_MODE_NV option. */
- { o(MESA_texture_array), PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS },
{ o(OES_standard_derivatives), PIPE_CAP_SM3 },
{ o(ARB_texture_cube_map_array), PIPE_CAP_CUBE_MAP_ARRAY },
@@ -444,11 +443,6 @@ void st_init_extensions(struct st_context *st)
{ { o(ARB_depth_buffer_float) },
{ PIPE_FORMAT_Z32_FLOAT,
PIPE_FORMAT_Z32_FLOAT_S8X24_UINT } },
-
- { { o(EXT_packed_depth_stencil) },
- { PIPE_FORMAT_S8_UINT_Z24_UNORM,
- PIPE_FORMAT_Z24_UNORM_S8_UINT },
- GL_TRUE }, /* at least one format must be supported */
};
/* Required: sampler support */
@@ -605,6 +599,13 @@ void st_init_extensions(struct st_context *st)
ctx->Const.ForceGLSLVersion = st->options.force_glsl_version;
}
+ /* This extension needs full OpenGL 3.2, but we don't know if that's
+ * supported at this point. Only check the GLSL version. */
+ if (ctx->Const.GLSLVersion >= 150 &&
+ screen->get_param(screen, PIPE_CAP_TGSI_VS_LAYER)) {
+ ctx->Extensions.AMD_vertex_shader_layer = GL_TRUE;
+ }
+
if (ctx->Const.GLSLVersion >= 130) {
ctx->Const.NativeIntegers = GL_TRUE;
ctx->Const.MaxClipPlanes = 8;
@@ -758,8 +759,7 @@ void st_init_extensions(struct st_context *st)
PIPE_BUFFER, PIPE_BIND_SAMPLER_VIEW);
}
- if (screen->get_param(screen, PIPE_CAP_MIXED_FRAMEBUFFER_SIZES) &&
- ctx->Extensions.EXT_packed_depth_stencil) {
+ if (screen->get_param(screen, PIPE_CAP_MIXED_FRAMEBUFFER_SIZES)) {
ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
}
diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c
index ec2552384..6acf98390 100644
--- a/mesalib/src/mesa/state_tracker/st_format.c
+++ b/mesalib/src/mesa/state_tracker/st_format.c
@@ -1854,12 +1854,12 @@ st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target,
* Similarly for texture border colors.
*/
void
-st_translate_color(union gl_color_union *colorIn,
+st_translate_color(const union gl_color_union *colorIn,
union pipe_color_union *colorOut,
GLenum baseFormat, GLboolean is_integer)
{
if (is_integer) {
- int *in = colorIn->i;
+ const int *in = colorIn->i;
int *out = colorOut->i;
switch (baseFormat) {
@@ -1901,7 +1901,7 @@ st_translate_color(union gl_color_union *colorIn,
}
}
else {
- float *in = colorIn->f;
+ const float *in = colorIn->f;
float *out = colorOut->f;
switch (baseFormat) {
diff --git a/mesalib/src/mesa/state_tracker/st_format.h b/mesalib/src/mesa/state_tracker/st_format.h
index 6e97dcb96..3278748d0 100644
--- a/mesalib/src/mesa/state_tracker/st_format.h
+++ b/mesalib/src/mesa/state_tracker/st_format.h
@@ -73,7 +73,7 @@ st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target,
extern void
-st_translate_color(union gl_color_union *colorIn,
+st_translate_color(const union gl_color_union *colorIn,
union pipe_color_union *colorOut,
GLenum baseFormat, GLboolean is_integer);
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index ac95968d6..1331c73dc 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1056,11 +1056,11 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
if (strcmp(ir->name, "gl_FragCoord") == 0) {
struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
- fp->OriginUpperLeft = ir->origin_upper_left;
- fp->PixelCenterInteger = ir->pixel_center_integer;
+ fp->OriginUpperLeft = ir->data.origin_upper_left;
+ fp->PixelCenterInteger = ir->data.pixel_center_integer;
}
- if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
+ if (ir->data.mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
unsigned int i;
const ir_state_slot *const slots = ir->state_slots;
assert(ir->state_slots != NULL);
@@ -1137,53 +1137,10 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
void
glsl_to_tgsi_visitor::visit(ir_loop *ir)
{
- ir_dereference_variable *counter = NULL;
-
- if (ir->counter != NULL)
- counter = new(ir) ir_dereference_variable(ir->counter);
-
- if (ir->from != NULL) {
- assert(ir->counter != NULL);
-
- ir_assignment *a = new(ir) ir_assignment(counter, ir->from, NULL);
-
- a->accept(this);
- delete a;
- }
-
emit(NULL, TGSI_OPCODE_BGNLOOP);
- if (ir->to) {
- ir_expression *e =
- new(ir) ir_expression(ir->cmp, glsl_type::bool_type,
- counter, ir->to);
- ir_if *if_stmt = new(ir) ir_if(e);
-
- ir_loop_jump *brk = new(ir) ir_loop_jump(ir_loop_jump::jump_break);
-
- if_stmt->then_instructions.push_tail(brk);
-
- if_stmt->accept(this);
-
- delete if_stmt;
- delete e;
- delete brk;
- }
-
visit_exec_list(&ir->body_instructions, this);
- if (ir->increment) {
- ir_expression *e =
- new(ir) ir_expression(ir_binop_add, counter->type,
- counter, ir->increment);
-
- ir_assignment *a = new(ir) ir_assignment(counter, e, NULL);
-
- a->accept(this);
- delete a;
- delete e;
- }
-
emit(NULL, TGSI_OPCODE_ENDLOOP);
}
@@ -2063,10 +2020,10 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
ir_variable *var = ir->var;
if (!entry) {
- switch (var->mode) {
+ switch (var->data.mode) {
case ir_var_uniform:
entry = new(mem_ctx) variable_storage(var, PROGRAM_UNIFORM,
- var->location);
+ var->data.location);
this->variables.push_tail(entry);
break;
case ir_var_shader_in:
@@ -2075,21 +2032,22 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
* generic attributes (glBindVertexLocation), and
* user-defined varyings.
*/
- assert(var->location != -1);
+ assert(var->data.location != -1);
entry = new(mem_ctx) variable_storage(var,
PROGRAM_INPUT,
- var->location);
+ var->data.location);
break;
case ir_var_shader_out:
- assert(var->location != -1);
+ assert(var->data.location != -1);
entry = new(mem_ctx) variable_storage(var,
PROGRAM_OUTPUT,
- var->location + var->index);
+ var->data.location
+ + var->data.index);
break;
case ir_var_system_value:
entry = new(mem_ctx) variable_storage(var,
PROGRAM_SYSTEM_VALUE,
- var->location);
+ var->data.location);
break;
case ir_var_auto:
case ir_var_temporary:
@@ -2388,7 +2346,7 @@ glsl_to_tgsi_visitor::visit(ir_assignment *ir)
assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector());
l.writemask = WRITEMASK_XYZW;
} else if (ir->lhs->type->is_scalar() &&
- ir->lhs->variable_referenced()->mode == ir_var_shader_out) {
+ ir->lhs->variable_referenced()->data.mode == ir_var_shader_out) {
/* FINISHME: This hack makes writing to gl_FragDepth, which lives in the
* FINISHME: W component of fragment shader output zero, work correctly.
*/
@@ -2664,8 +2622,8 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
ir_rvalue *param_rval = (ir_rvalue *)iter.get();
ir_variable *param = (ir_variable *)sig_iter.get();
- if (param->mode == ir_var_function_in ||
- param->mode == ir_var_function_inout) {
+ if (param->data.mode == ir_var_function_in ||
+ param->data.mode == ir_var_function_inout) {
variable_storage *storage = find_variable_storage(param);
assert(storage);
@@ -2700,8 +2658,8 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
ir_rvalue *param_rval = (ir_rvalue *)iter.get();
ir_variable *param = (ir_variable *)sig_iter.get();
- if (param->mode == ir_var_function_out ||
- param->mode == ir_var_function_inout) {
+ if (param->data.mode == ir_var_function_out ||
+ param->data.mode == ir_var_function_inout) {
variable_storage *storage = find_variable_storage(param);
assert(storage);
diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c
index f010e1889..f72122b4f 100644
--- a/mesalib/src/mesa/state_tracker/st_program.c
+++ b/mesalib/src/mesa/state_tracker/st_program.c
@@ -258,6 +258,10 @@ st_prepare_vertex_program(struct gl_context *ctx,
stvp->output_semantic_name[slot] = TGSI_SEMANTIC_CLIPVERTEX;
stvp->output_semantic_index[slot] = 0;
break;
+ case VARYING_SLOT_LAYER:
+ stvp->output_semantic_name[slot] = TGSI_SEMANTIC_LAYER;
+ stvp->output_semantic_index[slot] = 0;
+ break;
case VARYING_SLOT_TEX0:
case VARYING_SLOT_TEX1:
@@ -563,6 +567,11 @@ st_translate_fragment_program(struct st_context *st,
input_semantic_index[slot] = 0;
interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
break;
+ case VARYING_SLOT_PRIMITIVE_ID:
+ input_semantic_name[slot] = TGSI_SEMANTIC_PRIMID;
+ input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
+ break;
case VARYING_SLOT_CLIP_DIST0:
input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
input_semantic_index[slot] = 0;
diff --git a/mesalib/src/mesa/state_tracker/st_texture.h b/mesalib/src/mesa/state_tracker/st_texture.h
index c15aeaea6..ac93d9655 100644
--- a/mesalib/src/mesa/state_tracker/st_texture.h
+++ b/mesalib/src/mesa/state_tracker/st_texture.h
@@ -112,6 +112,12 @@ st_texture_object(struct gl_texture_object *obj)
return (struct st_texture_object *) obj;
}
+static INLINE const struct st_texture_object *
+st_texture_object_const(const struct gl_texture_object *obj)
+{
+ return (const struct st_texture_object *) obj;
+}
+
static INLINE struct pipe_resource *
st_get_texobj_resource(struct gl_texture_object *texObj)
diff --git a/mesalib/src/mesa/swrast/s_texture.c b/mesalib/src/mesa/swrast/s_texture.c
index 27803c553..c08a4e9d1 100644
--- a/mesalib/src/mesa/swrast/s_texture.c
+++ b/mesalib/src/mesa/swrast/s_texture.c
@@ -164,10 +164,9 @@ _swrast_free_texture_image_buffer(struct gl_context *ctx,
struct gl_texture_image *texImage)
{
struct swrast_texture_image *swImage = swrast_texture_image(texImage);
- if (swImage->Buffer) {
- _mesa_align_free(swImage->Buffer);
- swImage->Buffer = NULL;
- }
+
+ _mesa_align_free(swImage->Buffer);
+ swImage->Buffer = NULL;
free(swImage->ImageSlices);
swImage->ImageSlices = NULL;
diff --git a/mesalib/src/mesa/tnl/t_vertex.c b/mesalib/src/mesa/tnl/t_vertex.c
index c7a745ed7..8c4195eed 100644
--- a/mesalib/src/mesa/tnl/t_vertex.c
+++ b/mesalib/src/mesa/tnl/t_vertex.c
@@ -546,10 +546,8 @@ void _tnl_free_vertices( struct gl_context *ctx )
struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
struct tnl_clipspace_fastpath *fp, *tmp;
- if (vtx->vertex_buf) {
- _mesa_align_free(vtx->vertex_buf);
- vtx->vertex_buf = NULL;
- }
+ _mesa_align_free(vtx->vertex_buf);
+ vtx->vertex_buf = NULL;
for (fp = vtx->fastpath ; fp ; fp = tmp) {
tmp = fp->next;
diff --git a/mesalib/src/mesa/vbo/vbo_exec_api.c b/mesalib/src/mesa/vbo/vbo_exec_api.c
index c84d97f56..6feda1657 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_api.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_api.c
@@ -990,11 +990,10 @@ void vbo_use_buffer_objects(struct gl_context *ctx)
/* Make sure this func is only used once */
assert(exec->vtx.bufferobj == ctx->Shared->NullBufferObj);
- if (exec->vtx.buffer_map) {
- _mesa_align_free(exec->vtx.buffer_map);
- exec->vtx.buffer_map = NULL;
- exec->vtx.buffer_ptr = NULL;
- }
+
+ _mesa_align_free(exec->vtx.buffer_map);
+ exec->vtx.buffer_map = NULL;
+ exec->vtx.buffer_ptr = NULL;
/* Allocate a real buffer object now */
_mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
diff --git a/mesalib/src/mesa/x86/rtasm/x86sse.c b/mesalib/src/mesa/x86/rtasm/x86sse.c
deleted file mode 100644
index c93faba79..000000000
--- a/mesalib/src/mesa/x86/rtasm/x86sse.c
+++ /dev/null
@@ -1,1203 +0,0 @@
-#ifdef USE_X86_ASM
-#if defined(__i386__) || defined(__386__)
-
-#include "main/imports.h"
-#include "x86sse.h"
-
-#define DISASSEM 0
-#define X86_TWOB 0x0f
-
-#if 0
-static unsigned char *cptr( void (*label)() )
-{
- return (unsigned char *)(unsigned long)label;
-}
-#endif
-
-
-static void do_realloc( struct x86_function *p )
-{
- if (p->size == 0) {
- p->size = 1024;
- p->store = _mesa_exec_malloc(p->size);
- p->csr = p->store;
- }
- else {
- unsigned used = p->csr - p->store;
- unsigned char *tmp = p->store;
- p->size *= 2;
- p->store = _mesa_exec_malloc(p->size);
- memcpy(p->store, tmp, used);
- p->csr = p->store + used;
- _mesa_exec_free(tmp);
- }
-}
-
-/* Emit bytes to the instruction stream:
- */
-static unsigned char *reserve( struct x86_function *p, int bytes )
-{
- if (p->csr + bytes - p->store > p->size)
- do_realloc(p);
-
- {
- unsigned char *csr = p->csr;
- p->csr += bytes;
- return csr;
- }
-}
-
-
-
-static void emit_1b( struct x86_function *p, char b0 )
-{
- char *csr = (char *)reserve(p, 1);
- *csr = b0;
-}
-
-static void emit_1i( struct x86_function *p, int i0 )
-{
- int *icsr = (int *)reserve(p, sizeof(i0));
- *icsr = i0;
-}
-
-static void emit_1ub( struct x86_function *p, unsigned char b0 )
-{
- unsigned char *csr = reserve(p, 1);
- *csr++ = b0;
-}
-
-static void emit_2ub( struct x86_function *p, unsigned char b0, unsigned char b1 )
-{
- unsigned char *csr = reserve(p, 2);
- *csr++ = b0;
- *csr++ = b1;
-}
-
-static void emit_3ub( struct x86_function *p, unsigned char b0, unsigned char b1, unsigned char b2 )
-{
- unsigned char *csr = reserve(p, 3);
- *csr++ = b0;
- *csr++ = b1;
- *csr++ = b2;
-}
-
-
-/* Build a modRM byte + possible displacement. No treatment of SIB
- * indexing. BZZT - no way to encode an absolute address.
- */
-static void emit_modrm( struct x86_function *p,
- struct x86_reg reg,
- struct x86_reg regmem )
-{
- unsigned char val = 0;
-
- assert(reg.mod == mod_REG);
-
- val |= regmem.mod << 6; /* mod field */
- val |= reg.idx << 3; /* reg field */
- val |= regmem.idx; /* r/m field */
-
- emit_1ub(p, val);
-
- /* Oh-oh we've stumbled into the SIB thing.
- */
- if (regmem.file == file_REG32 &&
- regmem.idx == reg_SP) {
- emit_1ub(p, 0x24); /* simplistic! */
- }
-
- switch (regmem.mod) {
- case mod_REG:
- case mod_INDIRECT:
- break;
- case mod_DISP8:
- emit_1b(p, regmem.disp);
- break;
- case mod_DISP32:
- emit_1i(p, regmem.disp);
- break;
- default:
- assert(0);
- break;
- }
-}
-
-
-static void emit_modrm_noreg( struct x86_function *p,
- unsigned op,
- struct x86_reg regmem )
-{
- struct x86_reg dummy = x86_make_reg(file_REG32, op);
- emit_modrm(p, dummy, regmem);
-}
-
-/* Many x86 instructions have two opcodes to cope with the situations
- * where the destination is a register or memory reference
- * respectively. This function selects the correct opcode based on
- * the arguments presented.
- */
-static void emit_op_modrm( struct x86_function *p,
- unsigned char op_dst_is_reg,
- unsigned char op_dst_is_mem,
- struct x86_reg dst,
- struct x86_reg src )
-{
- switch (dst.mod) {
- case mod_REG:
- emit_1ub(p, op_dst_is_reg);
- emit_modrm(p, dst, src);
- break;
- case mod_INDIRECT:
- case mod_DISP32:
- case mod_DISP8:
- assert(src.mod == mod_REG);
- emit_1ub(p, op_dst_is_mem);
- emit_modrm(p, src, dst);
- break;
- default:
- assert(0);
- break;
- }
-}
-
-
-
-
-
-
-
-/* Create and manipulate registers and regmem values:
- */
-struct x86_reg x86_make_reg( enum x86_reg_file file,
- enum x86_reg_name idx )
-{
- struct x86_reg reg;
-
- reg.file = file;
- reg.idx = idx;
- reg.mod = mod_REG;
- reg.disp = 0;
-
- return reg;
-}
-
-struct x86_reg x86_make_disp( struct x86_reg reg,
- int disp )
-{
- assert(reg.file == file_REG32);
-
- if (reg.mod == mod_REG)
- reg.disp = disp;
- else
- reg.disp += disp;
-
- if (reg.disp == 0)
- reg.mod = mod_INDIRECT;
- else if (reg.disp <= 127 && reg.disp >= -128)
- reg.mod = mod_DISP8;
- else
- reg.mod = mod_DISP32;
-
- return reg;
-}
-
-struct x86_reg x86_deref( struct x86_reg reg )
-{
- return x86_make_disp(reg, 0);
-}
-
-struct x86_reg x86_get_base_reg( struct x86_reg reg )
-{
- return x86_make_reg( reg.file, reg.idx );
-}
-
-unsigned char *x86_get_label( struct x86_function *p )
-{
- return p->csr;
-}
-
-
-
-/***********************************************************************
- * x86 instructions
- */
-
-
-void x86_jcc( struct x86_function *p,
- enum x86_cc cc,
- unsigned char *label )
-{
- int offset = label - (x86_get_label(p) + 2);
-
- if (offset <= 127 && offset >= -128) {
- emit_1ub(p, 0x70 + cc);
- emit_1b(p, (char) offset);
- }
- else {
- offset = label - (x86_get_label(p) + 6);
- emit_2ub(p, 0x0f, 0x80 + cc);
- emit_1i(p, offset);
- }
-}
-
-/* Always use a 32bit offset for forward jumps:
- */
-unsigned char *x86_jcc_forward( struct x86_function *p,
- enum x86_cc cc )
-{
- emit_2ub(p, 0x0f, 0x80 + cc);
- emit_1i(p, 0);
- return x86_get_label(p);
-}
-
-unsigned char *x86_jmp_forward( struct x86_function *p)
-{
- emit_1ub(p, 0xe9);
- emit_1i(p, 0);
- return x86_get_label(p);
-}
-
-unsigned char *x86_call_forward( struct x86_function *p)
-{
- emit_1ub(p, 0xe8);
- emit_1i(p, 0);
- return x86_get_label(p);
-}
-
-/* Fixup offset from forward jump:
- */
-void x86_fixup_fwd_jump( struct x86_function *p,
- unsigned char *fixup )
-{
- *(int *)(fixup - 4) = x86_get_label(p) - fixup;
-}
-
-void x86_jmp( struct x86_function *p, unsigned char *label)
-{
- emit_1ub(p, 0xe9);
- emit_1i(p, label - x86_get_label(p) - 4);
-}
-
-#if 0
-/* This doesn't work once we start reallocating & copying the
- * generated code on buffer fills, because the call is relative to the
- * current pc.
- */
-void x86_call( struct x86_function *p, void (*label)())
-{
- emit_1ub(p, 0xe8);
- emit_1i(p, cptr(label) - x86_get_label(p) - 4);
-}
-#else
-void x86_call( struct x86_function *p, struct x86_reg reg)
-{
- emit_1ub(p, 0xff);
- emit_modrm_noreg(p, 2, reg);
-}
-#endif
-
-
-/* michal:
- * Temporary. As I need immediate operands, and dont want to mess with the codegen,
- * I load the immediate into general purpose register and use it.
- */
-void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm )
-{
- assert(dst.mod == mod_REG);
- emit_1ub(p, 0xb8 + dst.idx);
- emit_1i(p, imm);
-}
-
-void x86_push( struct x86_function *p,
- struct x86_reg reg )
-{
- assert(reg.mod == mod_REG);
- emit_1ub(p, 0x50 + reg.idx);
- p->stack_offset += 4;
-}
-
-void x86_pop( struct x86_function *p,
- struct x86_reg reg )
-{
- assert(reg.mod == mod_REG);
- emit_1ub(p, 0x58 + reg.idx);
- p->stack_offset -= 4;
-}
-
-void x86_inc( struct x86_function *p,
- struct x86_reg reg )
-{
- assert(reg.mod == mod_REG);
- emit_1ub(p, 0x40 + reg.idx);
-}
-
-void x86_dec( struct x86_function *p,
- struct x86_reg reg )
-{
- assert(reg.mod == mod_REG);
- emit_1ub(p, 0x48 + reg.idx);
-}
-
-void x86_ret( struct x86_function *p )
-{
- emit_1ub(p, 0xc3);
-}
-
-void x86_sahf( struct x86_function *p )
-{
- emit_1ub(p, 0x9e);
-}
-
-void x86_mov( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_op_modrm( p, 0x8b, 0x89, dst, src );
-}
-
-void x86_xor( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_op_modrm( p, 0x33, 0x31, dst, src );
-}
-
-void x86_cmp( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_op_modrm( p, 0x3b, 0x39, dst, src );
-}
-
-void x86_lea( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_1ub(p, 0x8d);
- emit_modrm( p, dst, src );
-}
-
-void x86_test( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_1ub(p, 0x85);
- emit_modrm( p, dst, src );
-}
-
-void x86_add( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_op_modrm(p, 0x03, 0x01, dst, src );
-}
-
-void x86_mul( struct x86_function *p,
- struct x86_reg src )
-{
- assert (src.file == file_REG32 && src.mod == mod_REG);
- emit_op_modrm(p, 0xf7, 0, x86_make_reg (file_REG32, reg_SP), src );
-}
-
-void x86_sub( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_op_modrm(p, 0x2b, 0x29, dst, src );
-}
-
-void x86_or( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_op_modrm( p, 0x0b, 0x09, dst, src );
-}
-
-void x86_and( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_op_modrm( p, 0x23, 0x21, dst, src );
-}
-
-
-
-/***********************************************************************
- * SSE instructions
- */
-
-
-void sse_movss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, 0xF3, X86_TWOB);
- emit_op_modrm( p, 0x10, 0x11, dst, src );
-}
-
-void sse_movaps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_1ub(p, X86_TWOB);
- emit_op_modrm( p, 0x28, 0x29, dst, src );
-}
-
-void sse_movups( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_1ub(p, X86_TWOB);
- emit_op_modrm( p, 0x10, 0x11, dst, src );
-}
-
-void sse_movhps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- assert(dst.mod != mod_REG || src.mod != mod_REG);
- emit_1ub(p, X86_TWOB);
- emit_op_modrm( p, 0x16, 0x17, dst, src ); /* cf movlhps */
-}
-
-void sse_movlps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- assert(dst.mod != mod_REG || src.mod != mod_REG);
- emit_1ub(p, X86_TWOB);
- emit_op_modrm( p, 0x12, 0x13, dst, src ); /* cf movhlps */
-}
-
-void sse_maxps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x5F);
- emit_modrm( p, dst, src );
-}
-
-void sse_maxss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub(p, 0xF3, X86_TWOB, 0x5F);
- emit_modrm( p, dst, src );
-}
-
-void sse_divss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub(p, 0xF3, X86_TWOB, 0x5E);
- emit_modrm( p, dst, src );
-}
-
-void sse_minps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x5D);
- emit_modrm( p, dst, src );
-}
-
-void sse_subps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x5C);
- emit_modrm( p, dst, src );
-}
-
-void sse_mulps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x59);
- emit_modrm( p, dst, src );
-}
-
-void sse_mulss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub(p, 0xF3, X86_TWOB, 0x59);
- emit_modrm( p, dst, src );
-}
-
-void sse_addps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x58);
- emit_modrm( p, dst, src );
-}
-
-void sse_addss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub(p, 0xF3, X86_TWOB, 0x58);
- emit_modrm( p, dst, src );
-}
-
-void sse_andnps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x55);
- emit_modrm( p, dst, src );
-}
-
-void sse_andps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x54);
- emit_modrm( p, dst, src );
-}
-
-void sse_rsqrtps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x52);
- emit_modrm( p, dst, src );
-}
-
-void sse_rsqrtss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub(p, 0xF3, X86_TWOB, 0x52);
- emit_modrm( p, dst, src );
-
-}
-
-void sse_movhlps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- assert(dst.mod == mod_REG && src.mod == mod_REG);
- emit_2ub(p, X86_TWOB, 0x12);
- emit_modrm( p, dst, src );
-}
-
-void sse_movlhps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- assert(dst.mod == mod_REG && src.mod == mod_REG);
- emit_2ub(p, X86_TWOB, 0x16);
- emit_modrm( p, dst, src );
-}
-
-void sse_orps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x56);
- emit_modrm( p, dst, src );
-}
-
-void sse_xorps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x57);
- emit_modrm( p, dst, src );
-}
-
-void sse_cvtps2pi( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- assert(dst.file == file_MMX &&
- (src.file == file_XMM || src.mod != mod_REG));
-
- p->need_emms = 1;
-
- emit_2ub(p, X86_TWOB, 0x2d);
- emit_modrm( p, dst, src );
-}
-
-
-/* Shufps can also be used to implement a reduced swizzle when dest ==
- * arg0.
- */
-void sse_shufps( struct x86_function *p,
- struct x86_reg dest,
- struct x86_reg arg0,
- unsigned char shuf)
-{
- emit_2ub(p, X86_TWOB, 0xC6);
- emit_modrm(p, dest, arg0);
- emit_1ub(p, shuf);
-}
-
-void sse_cmpps( struct x86_function *p,
- struct x86_reg dest,
- struct x86_reg arg0,
- unsigned char cc)
-{
- emit_2ub(p, X86_TWOB, 0xC2);
- emit_modrm(p, dest, arg0);
- emit_1ub(p, cc);
-}
-
-void sse_pmovmskb( struct x86_function *p,
- struct x86_reg dest,
- struct x86_reg src)
-{
- emit_3ub(p, 0x66, X86_TWOB, 0xD7);
- emit_modrm(p, dest, src);
-}
-
-/***********************************************************************
- * SSE2 instructions
- */
-
-/**
- * Perform a reduced swizzle:
- */
-void sse2_pshufd( struct x86_function *p,
- struct x86_reg dest,
- struct x86_reg arg0,
- unsigned char shuf)
-{
- emit_3ub(p, 0x66, X86_TWOB, 0x70);
- emit_modrm(p, dest, arg0);
- emit_1ub(p, shuf);
-}
-
-void sse2_cvttps2dq( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub( p, 0xF3, X86_TWOB, 0x5B );
- emit_modrm( p, dst, src );
-}
-
-void sse2_cvtps2dq( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub(p, 0x66, X86_TWOB, 0x5B);
- emit_modrm( p, dst, src );
-}
-
-void sse2_packssdw( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub(p, 0x66, X86_TWOB, 0x6B);
- emit_modrm( p, dst, src );
-}
-
-void sse2_packsswb( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub(p, 0x66, X86_TWOB, 0x63);
- emit_modrm( p, dst, src );
-}
-
-void sse2_packuswb( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub(p, 0x66, X86_TWOB, 0x67);
- emit_modrm( p, dst, src );
-}
-
-void sse2_rcpps( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, X86_TWOB, 0x53);
- emit_modrm( p, dst, src );
-}
-
-void sse2_rcpss( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_3ub(p, 0xF3, X86_TWOB, 0x53);
- emit_modrm( p, dst, src );
-}
-
-void sse2_movd( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- emit_2ub(p, 0x66, X86_TWOB);
- emit_op_modrm( p, 0x6e, 0x7e, dst, src );
-}
-
-
-
-
-/***********************************************************************
- * x87 instructions
- */
-void x87_fist( struct x86_function *p, struct x86_reg dst )
-{
- emit_1ub(p, 0xdb);
- emit_modrm_noreg(p, 2, dst);
-}
-
-void x87_fistp( struct x86_function *p, struct x86_reg dst )
-{
- emit_1ub(p, 0xdb);
- emit_modrm_noreg(p, 3, dst);
-}
-
-void x87_fild( struct x86_function *p, struct x86_reg arg )
-{
- emit_1ub(p, 0xdf);
- emit_modrm_noreg(p, 0, arg);
-}
-
-void x87_fldz( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xee);
-}
-
-
-void x87_fldcw( struct x86_function *p, struct x86_reg arg )
-{
- assert(arg.file == file_REG32);
- assert(arg.mod != mod_REG);
- emit_1ub(p, 0xd9);
- emit_modrm_noreg(p, 5, arg);
-}
-
-void x87_fld1( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xe8);
-}
-
-void x87_fldl2e( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xea);
-}
-
-void x87_fldln2( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xed);
-}
-
-void x87_fwait( struct x86_function *p )
-{
- emit_1ub(p, 0x9b);
-}
-
-void x87_fnclex( struct x86_function *p )
-{
- emit_2ub(p, 0xdb, 0xe2);
-}
-
-void x87_fclex( struct x86_function *p )
-{
- x87_fwait(p);
- x87_fnclex(p);
-}
-
-
-static void x87_arith_op( struct x86_function *p, struct x86_reg dst, struct x86_reg arg,
- unsigned char dst0ub0,
- unsigned char dst0ub1,
- unsigned char arg0ub0,
- unsigned char arg0ub1,
- unsigned char argmem_noreg)
-{
- assert(dst.file == file_x87);
-
- if (arg.file == file_x87) {
- if (dst.idx == 0)
- emit_2ub(p, dst0ub0, dst0ub1+arg.idx);
- else if (arg.idx == 0)
- emit_2ub(p, arg0ub0, arg0ub1+arg.idx);
- else
- assert(0);
- }
- else if (dst.idx == 0) {
- assert(arg.file == file_REG32);
- emit_1ub(p, 0xd8);
- emit_modrm_noreg(p, argmem_noreg, arg);
- }
- else
- assert(0);
-}
-
-void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg )
-{
- x87_arith_op(p, dst, arg,
- 0xd8, 0xc8,
- 0xdc, 0xc8,
- 4);
-}
-
-void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg )
-{
- x87_arith_op(p, dst, arg,
- 0xd8, 0xe0,
- 0xdc, 0xe8,
- 4);
-}
-
-void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg )
-{
- x87_arith_op(p, dst, arg,
- 0xd8, 0xe8,
- 0xdc, 0xe0,
- 5);
-}
-
-void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg )
-{
- x87_arith_op(p, dst, arg,
- 0xd8, 0xc0,
- 0xdc, 0xc0,
- 0);
-}
-
-void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg )
-{
- x87_arith_op(p, dst, arg,
- 0xd8, 0xf0,
- 0xdc, 0xf8,
- 6);
-}
-
-void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg )
-{
- x87_arith_op(p, dst, arg,
- 0xd8, 0xf8,
- 0xdc, 0xf0,
- 7);
-}
-
-void x87_fmulp( struct x86_function *p, struct x86_reg dst )
-{
- assert(dst.file == file_x87);
- assert(dst.idx >= 1);
- emit_2ub(p, 0xde, 0xc8+dst.idx);
-}
-
-void x87_fsubp( struct x86_function *p, struct x86_reg dst )
-{
- assert(dst.file == file_x87);
- assert(dst.idx >= 1);
- emit_2ub(p, 0xde, 0xe8+dst.idx);
-}
-
-void x87_fsubrp( struct x86_function *p, struct x86_reg dst )
-{
- assert(dst.file == file_x87);
- assert(dst.idx >= 1);
- emit_2ub(p, 0xde, 0xe0+dst.idx);
-}
-
-void x87_faddp( struct x86_function *p, struct x86_reg dst )
-{
- assert(dst.file == file_x87);
- assert(dst.idx >= 1);
- emit_2ub(p, 0xde, 0xc0+dst.idx);
-}
-
-void x87_fdivp( struct x86_function *p, struct x86_reg dst )
-{
- assert(dst.file == file_x87);
- assert(dst.idx >= 1);
- emit_2ub(p, 0xde, 0xf8+dst.idx);
-}
-
-void x87_fdivrp( struct x86_function *p, struct x86_reg dst )
-{
- assert(dst.file == file_x87);
- assert(dst.idx >= 1);
- emit_2ub(p, 0xde, 0xf0+dst.idx);
-}
-
-void x87_fucom( struct x86_function *p, struct x86_reg arg )
-{
- assert(arg.file == file_x87);
- emit_2ub(p, 0xdd, 0xe0+arg.idx);
-}
-
-void x87_fucomp( struct x86_function *p, struct x86_reg arg )
-{
- assert(arg.file == file_x87);
- emit_2ub(p, 0xdd, 0xe8+arg.idx);
-}
-
-void x87_fucompp( struct x86_function *p )
-{
- emit_2ub(p, 0xda, 0xe9);
-}
-
-void x87_fxch( struct x86_function *p, struct x86_reg arg )
-{
- assert(arg.file == file_x87);
- emit_2ub(p, 0xd9, 0xc8+arg.idx);
-}
-
-void x87_fabs( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xe1);
-}
-
-void x87_fchs( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xe0);
-}
-
-void x87_fcos( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xff);
-}
-
-
-void x87_fprndint( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xfc);
-}
-
-void x87_fscale( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xfd);
-}
-
-void x87_fsin( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xfe);
-}
-
-void x87_fsincos( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xfb);
-}
-
-void x87_fsqrt( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xfa);
-}
-
-void x87_fxtract( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xf4);
-}
-
-/* st0 = (2^st0)-1
- *
- * Restrictions: -1.0 <= st0 <= 1.0
- */
-void x87_f2xm1( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xf0);
-}
-
-/* st1 = st1 * log2(st0);
- * pop_stack;
- */
-void x87_fyl2x( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xf1);
-}
-
-/* st1 = st1 * log2(st0 + 1.0);
- * pop_stack;
- *
- * A fast operation, with restrictions: -.29 < st0 < .29
- */
-void x87_fyl2xp1( struct x86_function *p )
-{
- emit_2ub(p, 0xd9, 0xf9);
-}
-
-
-void x87_fld( struct x86_function *p, struct x86_reg arg )
-{
- if (arg.file == file_x87)
- emit_2ub(p, 0xd9, 0xc0 + arg.idx);
- else {
- emit_1ub(p, 0xd9);
- emit_modrm_noreg(p, 0, arg);
- }
-}
-
-void x87_fst( struct x86_function *p, struct x86_reg dst )
-{
- if (dst.file == file_x87)
- emit_2ub(p, 0xdd, 0xd0 + dst.idx);
- else {
- emit_1ub(p, 0xd9);
- emit_modrm_noreg(p, 2, dst);
- }
-}
-
-void x87_fstp( struct x86_function *p, struct x86_reg dst )
-{
- if (dst.file == file_x87)
- emit_2ub(p, 0xdd, 0xd8 + dst.idx);
- else {
- emit_1ub(p, 0xd9);
- emit_modrm_noreg(p, 3, dst);
- }
-}
-
-void x87_fcom( struct x86_function *p, struct x86_reg dst )
-{
- if (dst.file == file_x87)
- emit_2ub(p, 0xd8, 0xd0 + dst.idx);
- else {
- emit_1ub(p, 0xd8);
- emit_modrm_noreg(p, 2, dst);
- }
-}
-
-void x87_fcomp( struct x86_function *p, struct x86_reg dst )
-{
- if (dst.file == file_x87)
- emit_2ub(p, 0xd8, 0xd8 + dst.idx);
- else {
- emit_1ub(p, 0xd8);
- emit_modrm_noreg(p, 3, dst);
- }
-}
-
-
-void x87_fnstsw( struct x86_function *p, struct x86_reg dst )
-{
- assert(dst.file == file_REG32);
-
- if (dst.idx == reg_AX &&
- dst.mod == mod_REG)
- emit_2ub(p, 0xdf, 0xe0);
- else {
- emit_1ub(p, 0xdd);
- emit_modrm_noreg(p, 7, dst);
- }
-}
-
-
-
-
-/***********************************************************************
- * MMX instructions
- */
-
-void mmx_emms( struct x86_function *p )
-{
- assert(p->need_emms);
- emit_2ub(p, 0x0f, 0x77);
- p->need_emms = 0;
-}
-
-void mmx_packssdw( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- assert(dst.file == file_MMX &&
- (src.file == file_MMX || src.mod != mod_REG));
-
- p->need_emms = 1;
-
- emit_2ub(p, X86_TWOB, 0x6b);
- emit_modrm( p, dst, src );
-}
-
-void mmx_packuswb( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- assert(dst.file == file_MMX &&
- (src.file == file_MMX || src.mod != mod_REG));
-
- p->need_emms = 1;
-
- emit_2ub(p, X86_TWOB, 0x67);
- emit_modrm( p, dst, src );
-}
-
-void mmx_movd( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- p->need_emms = 1;
- emit_1ub(p, X86_TWOB);
- emit_op_modrm( p, 0x6e, 0x7e, dst, src );
-}
-
-void mmx_movq( struct x86_function *p,
- struct x86_reg dst,
- struct x86_reg src )
-{
- p->need_emms = 1;
- emit_1ub(p, X86_TWOB);
- emit_op_modrm( p, 0x6f, 0x7f, dst, src );
-}
-
-
-/***********************************************************************
- * Helper functions
- */
-
-
-/* Retreive a reference to one of the function arguments, taking into
- * account any push/pop activity:
- */
-struct x86_reg x86_fn_arg( struct x86_function *p,
- unsigned arg )
-{
- return x86_make_disp(x86_make_reg(file_REG32, reg_SP),
- p->stack_offset + arg * 4); /* ??? */
-}
-
-
-void x86_init_func( struct x86_function *p )
-{
- p->size = 0;
- p->store = NULL;
- p->csr = p->store;
-}
-
-int x86_init_func_size( struct x86_function *p, unsigned code_size )
-{
- p->size = code_size;
- p->store = _mesa_exec_malloc(code_size);
- p->csr = p->store;
- return p->store != NULL;
-}
-
-void x86_release_func( struct x86_function *p )
-{
- _mesa_exec_free(p->store);
- p->store = NULL;
- p->csr = NULL;
- p->size = 0;
-}
-
-
-void (*x86_get_func( struct x86_function *p ))(void)
-{
- if (DISASSEM && p->store)
- printf("disassemble %p %p\n", p->store, p->csr);
- return (void (*)(void)) (unsigned long) p->store;
-}
-
-#else
-
-void x86sse_dummy( void )
-{
-}
-
-#endif
-
-#else /* USE_X86_ASM */
-
-int x86sse_c_dummy_var; /* silence warning */
-
-#endif /* USE_X86_ASM */
diff --git a/mesalib/src/mesa/x86/rtasm/x86sse.h b/mesalib/src/mesa/x86/rtasm/x86sse.h
deleted file mode 100644
index f6282f5bd..000000000
--- a/mesalib/src/mesa/x86/rtasm/x86sse.h
+++ /dev/null
@@ -1,256 +0,0 @@
-
-#ifndef _X86SSE_H_
-#define _X86SSE_H_
-
-#if defined(__i386__) || defined(__386__)
-
-/* It is up to the caller to ensure that instructions issued are
- * suitable for the host cpu. There are no checks made in this module
- * for mmx/sse/sse2 support on the cpu.
- */
-struct x86_reg {
- unsigned file:3;
- unsigned idx:3;
- unsigned mod:2; /* mod_REG if this is just a register */
- int disp:24; /* only +/- 23bits of offset - should be enough... */
-};
-
-struct x86_function {
- unsigned size;
- unsigned char *store;
- unsigned char *csr;
- unsigned stack_offset;
- int need_emms;
- const char *fn;
-};
-
-enum x86_reg_file {
- file_REG32,
- file_MMX,
- file_XMM,
- file_x87
-};
-
-/* Values for mod field of modr/m byte
- */
-enum x86_reg_mod {
- mod_INDIRECT,
- mod_DISP8,
- mod_DISP32,
- mod_REG
-};
-
-enum x86_reg_name {
- reg_AX,
- reg_CX,
- reg_DX,
- reg_BX,
- reg_SP,
- reg_BP,
- reg_SI,
- reg_DI
-};
-
-
-enum x86_cc {
- cc_O, /* overflow */
- cc_NO, /* not overflow */
- cc_NAE, /* not above or equal / carry */
- cc_AE, /* above or equal / not carry */
- cc_E, /* equal / zero */
- cc_NE /* not equal / not zero */
-};
-
-enum sse_cc {
- cc_Equal,
- cc_LessThan,
- cc_LessThanEqual,
- cc_Unordered,
- cc_NotEqual,
- cc_NotLessThan,
- cc_NotLessThanEqual,
- cc_Ordered
-};
-
-#define cc_Z cc_E
-#define cc_NZ cc_NE
-
-/* Begin/end/retreive function creation:
- */
-
-
-void x86_init_func( struct x86_function *p );
-int x86_init_func_size( struct x86_function *p, unsigned code_size );
-void x86_release_func( struct x86_function *p );
-void (*x86_get_func( struct x86_function *p ))( void );
-
-
-
-/* Create and manipulate registers and regmem values:
- */
-struct x86_reg x86_make_reg( enum x86_reg_file file,
- enum x86_reg_name idx );
-
-struct x86_reg x86_make_disp( struct x86_reg reg,
- int disp );
-
-struct x86_reg x86_deref( struct x86_reg reg );
-
-struct x86_reg x86_get_base_reg( struct x86_reg reg );
-
-
-/* Labels, jumps and fixup:
- */
-unsigned char *x86_get_label( struct x86_function *p );
-
-void x86_jcc( struct x86_function *p,
- enum x86_cc cc,
- unsigned char *label );
-
-unsigned char *x86_jcc_forward( struct x86_function *p,
- enum x86_cc cc );
-
-unsigned char *x86_jmp_forward( struct x86_function *p);
-
-unsigned char *x86_call_forward( struct x86_function *p);
-
-void x86_fixup_fwd_jump( struct x86_function *p,
- unsigned char *fixup );
-
-void x86_jmp( struct x86_function *p, unsigned char *label );
-
-/* void x86_call( struct x86_function *p, void (*label)() ); */
-void x86_call( struct x86_function *p, struct x86_reg reg);
-
-/* michal:
- * Temporary. As I need immediate operands, and dont want to mess with the codegen,
- * I load the immediate into general purpose register and use it.
- */
-void x86_mov_reg_imm( struct x86_function *p, struct x86_reg dst, int imm );
-
-
-/* Macro for sse_shufps() and sse2_pshufd():
- */
-#define SHUF(_x,_y,_z,_w) (((_x)<<0) | ((_y)<<2) | ((_z)<<4) | ((_w)<<6))
-#define SHUF_NOOP RSW(0,1,2,3)
-#define GET_SHUF(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
-
-void mmx_emms( struct x86_function *p );
-void mmx_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void mmx_movq( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void mmx_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void mmx_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-
-void sse2_cvtps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse2_cvttps2dq( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse2_movd( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse2_packssdw( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse2_packsswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse2_packuswb( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse2_pshufd( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0,
- unsigned char shuf );
-void sse2_rcpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse2_rcpss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-
-void sse_addps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_addss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_cvtps2pi( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_divss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_andnps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_andps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_cmpps( struct x86_function *p, struct x86_reg dst, struct x86_reg src,
- unsigned char cc );
-void sse_maxps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_maxss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_minps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_movaps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_movhlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_movhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_movlhps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_movlps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_movss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_movups( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_mulps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_mulss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_orps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_xorps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_subps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_rsqrtps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_rsqrtss( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void sse_shufps( struct x86_function *p, struct x86_reg dest, struct x86_reg arg0,
- unsigned char shuf );
-void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src );
-
-void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void x86_cmp( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void x86_dec( struct x86_function *p, struct x86_reg reg );
-void x86_inc( struct x86_function *p, struct x86_reg reg );
-void x86_lea( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void x86_mov( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void x86_mul( struct x86_function *p, struct x86_reg src );
-void x86_or( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void x86_pop( struct x86_function *p, struct x86_reg reg );
-void x86_push( struct x86_function *p, struct x86_reg reg );
-void x86_ret( struct x86_function *p );
-void x86_sub( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void x86_test( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void x86_xor( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
-void x86_sahf( struct x86_function *p );
-
-void x87_f2xm1( struct x86_function *p );
-void x87_fabs( struct x86_function *p );
-void x87_fadd( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
-void x87_faddp( struct x86_function *p, struct x86_reg dst );
-void x87_fchs( struct x86_function *p );
-void x87_fclex( struct x86_function *p );
-void x87_fcom( struct x86_function *p, struct x86_reg dst );
-void x87_fcomp( struct x86_function *p, struct x86_reg dst );
-void x87_fcos( struct x86_function *p );
-void x87_fdiv( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
-void x87_fdivp( struct x86_function *p, struct x86_reg dst );
-void x87_fdivr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
-void x87_fdivrp( struct x86_function *p, struct x86_reg dst );
-void x87_fild( struct x86_function *p, struct x86_reg arg );
-void x87_fist( struct x86_function *p, struct x86_reg dst );
-void x87_fistp( struct x86_function *p, struct x86_reg dst );
-void x87_fld( struct x86_function *p, struct x86_reg arg );
-void x87_fld1( struct x86_function *p );
-void x87_fldcw( struct x86_function *p, struct x86_reg arg );
-void x87_fldl2e( struct x86_function *p );
-void x87_fldln2( struct x86_function *p );
-void x87_fldz( struct x86_function *p );
-void x87_fmul( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
-void x87_fmulp( struct x86_function *p, struct x86_reg dst );
-void x87_fnclex( struct x86_function *p );
-void x87_fprndint( struct x86_function *p );
-void x87_fscale( struct x86_function *p );
-void x87_fsin( struct x86_function *p );
-void x87_fsincos( struct x86_function *p );
-void x87_fsqrt( struct x86_function *p );
-void x87_fst( struct x86_function *p, struct x86_reg dst );
-void x87_fstp( struct x86_function *p, struct x86_reg dst );
-void x87_fsub( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
-void x87_fsubp( struct x86_function *p, struct x86_reg dst );
-void x87_fsubr( struct x86_function *p, struct x86_reg dst, struct x86_reg arg );
-void x87_fsubrp( struct x86_function *p, struct x86_reg dst );
-void x87_fxch( struct x86_function *p, struct x86_reg dst );
-void x87_fxtract( struct x86_function *p );
-void x87_fyl2x( struct x86_function *p );
-void x87_fyl2xp1( struct x86_function *p );
-void x87_fwait( struct x86_function *p );
-void x87_fnstsw( struct x86_function *p, struct x86_reg dst );
-void x87_fucompp( struct x86_function *p );
-void x87_fucomp( struct x86_function *p, struct x86_reg arg );
-void x87_fucom( struct x86_function *p, struct x86_reg arg );
-
-
-
-/* Retreive a reference to one of the function arguments, taking into
- * account any push/pop activity. Note - doesn't track explict
- * manipulation of ESP by other instructions.
- */
-struct x86_reg x86_fn_arg( struct x86_function *p, unsigned arg );
-
-#endif
-#endif