aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src')
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_math.h5
-rw-r--r--mesalib/src/glsl/glsl_types.cpp29
-rw-r--r--mesalib/src/glsl/glsl_types.h6
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp60
-rw-r--r--mesalib/src/glsl/linker.cpp143
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c7
-rw-r--r--mesalib/src/mesa/main/api_validate.c2
-rw-r--r--mesalib/src/mesa/main/arrayobj.c2
-rw-r--r--mesalib/src/mesa/main/bitset.h2
-rw-r--r--mesalib/src/mesa/main/buffers.c25
-rw-r--r--mesalib/src/mesa/main/clear.c15
-rw-r--r--mesalib/src/mesa/main/drawpix.c6
-rw-r--r--mesalib/src/mesa/main/fbobject.c50
-rw-r--r--mesalib/src/mesa/main/fbobject.h22
-rw-r--r--mesalib/src/mesa/main/ff_fragment_shader.cpp42
-rw-r--r--mesalib/src/mesa/main/ffvertex_prog.c2
-rw-r--r--mesalib/src/mesa/main/framebuffer.c9
-rw-r--r--mesalib/src/mesa/main/hash.c20
-rw-r--r--mesalib/src/mesa/main/hash.h3
-rw-r--r--mesalib/src/mesa/main/imports.c15
-rw-r--r--mesalib/src/mesa/main/imports.h25
-rw-r--r--mesalib/src/mesa/main/mipmap.c2
-rw-r--r--mesalib/src/mesa/main/mtypes.h20
-rw-r--r--mesalib/src/mesa/main/readpix.c5
-rw-r--r--mesalib/src/mesa/main/renderbuffer.c2
-rw-r--r--mesalib/src/mesa/main/shaderapi.c95
-rw-r--r--mesalib/src/mesa/main/state.c12
-rw-r--r--mesalib/src/mesa/main/teximage.c20
-rw-r--r--mesalib/src/mesa/main/texobj.c10
-rw-r--r--mesalib/src/mesa/main/texstore.c6
-rw-r--r--mesalib/src/mesa/main/uniform_query.cpp58
-rw-r--r--mesalib/src/mesa/main/uniforms.c7
-rw-r--r--mesalib/src/mesa/main/uniforms.h6
-rw-r--r--mesalib/src/mesa/main/version.h11
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp33
-rw-r--r--mesalib/src/mesa/program/prog_print.c4
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_texture.c35
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_draw_feedback.c2
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c31
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp34
-rw-r--r--mesalib/src/mesa/state_tracker/st_manager.c20
-rw-r--r--mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c7
-rw-r--r--mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.h5
-rw-r--r--mesalib/src/mesa/swrast/s_aalinetemp.h484
-rw-r--r--mesalib/src/mesa/swrast/s_context.c2
-rw-r--r--mesalib/src/mesa/swrast/s_span.c6
-rw-r--r--mesalib/src/mesa/swrast/s_texture.c4
-rw-r--r--mesalib/src/mesa/tnl/t_draw.c2
-rw-r--r--mesalib/src/mesa/vbo/vbo.h6
-rw-r--r--mesalib/src/mesa/vbo/vbo_exec_array.c53
51 files changed, 882 insertions, 593 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_math.h b/mesalib/src/gallium/auxiliary/util/u_math.h
index 404bd21e1..f6196665f 100644
--- a/mesalib/src/gallium/auxiliary/util/u_math.h
+++ b/mesalib/src/gallium/auxiliary/util/u_math.h
@@ -340,6 +340,9 @@ util_is_inf_or_nan(float x)
* Find first bit set in word. Least significant bit is 1.
* Return 0 if no bits set.
*/
+#ifndef FFS_DEFINED
+#define FFS_DEFINED 1
+
#if defined(_MSC_VER) && _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64)
unsigned char _BitScanForward(unsigned long* Index, unsigned long Mask);
#pragma intrinsic(_BitScanForward)
@@ -372,6 +375,8 @@ unsigned ffs( unsigned u )
#define ffs __builtin_ffs
#endif
+#endif /* FFS_DEFINED */
+
/* Destructively loop over all of the bits in a mask as in:
*
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index 8587da0a3..d4385a644 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -127,6 +127,35 @@ glsl_type::contains_sampler() const
}
}
+gl_texture_index
+glsl_type::sampler_index() const
+{
+ const glsl_type *const t = (this->is_array()) ? this->fields.array : this;
+
+ assert(t->is_sampler());
+
+ switch (t->sampler_dimensionality) {
+ case GLSL_SAMPLER_DIM_1D:
+ return (t->sampler_array) ? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
+ case GLSL_SAMPLER_DIM_2D:
+ return (t->sampler_array) ? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
+ case GLSL_SAMPLER_DIM_3D:
+ return TEXTURE_3D_INDEX;
+ case GLSL_SAMPLER_DIM_CUBE:
+ return TEXTURE_CUBE_INDEX;
+ case GLSL_SAMPLER_DIM_RECT:
+ return TEXTURE_RECT_INDEX;
+ case GLSL_SAMPLER_DIM_BUF:
+ assert(!"FINISHME: Implement ARB_texture_buffer_object");
+ break;
+ case GLSL_SAMPLER_DIM_EXTERNAL:
+ return TEXTURE_EXTERNAL_INDEX;
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+}
+
void
glsl_type::generate_100ES_types(glsl_symbol_table *symtab)
{
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index 4ac90118b..2997c9311 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -28,6 +28,7 @@
#include <string.h>
#include <assert.h>
+#include "main/mtypes.h" /* for gl_texture_index, C++'s enum rules are broken */
#ifdef __cplusplus
extern "C" {
@@ -354,6 +355,11 @@ struct glsl_type {
bool contains_sampler() const;
/**
+ * Get the Mesa texture target index for a sampler type.
+ */
+ gl_texture_index sampler_index() const;
+
+ /**
* Query whether or not a type is an array
*/
bool is_array() const
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index b331db705..02f57d911 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -209,7 +209,13 @@ public:
union gl_constant_value *values)
: map(map), uniforms(uniforms), next_sampler(0), values(values)
{
- /* empty */
+ memset(this->targets, 0, sizeof(this->targets));
+ }
+
+ void start_shader()
+ {
+ this->shader_samplers_used = 0;
+ this->shader_shadow_samplers = 0;
}
private:
@@ -230,8 +236,25 @@ private:
* example, we may be processing the uniform in the fragment shader, but
* the uniform was already processed in the vertex shader.
*/
- if (this->uniforms[id].storage != NULL)
+ if (this->uniforms[id].storage != NULL) {
+ /* If the uniform already has storage set from another shader stage,
+ * mark the samplers used for this shader stage.
+ */
+ if (type->contains_sampler()) {
+ const unsigned count = MAX2(1, this->uniforms[id].array_elements);
+ const unsigned shadow = (type->is_array())
+ ? type->fields.array->sampler_shadow : type->sampler_shadow;
+
+ for (unsigned i = 0; i < count; i++) {
+ const unsigned s = this->uniforms[id].sampler + i;
+
+ this->shader_samplers_used |= 1U << s;
+ this->shader_shadow_samplers |= shadow << s;
+ }
+ }
+
return;
+ }
const glsl_type *base_type;
if (type->is_array()) {
@@ -249,6 +272,17 @@ private:
* array elements for arrays.
*/
this->next_sampler += MAX2(1, this->uniforms[id].array_elements);
+
+ const gl_texture_index target = base_type->sampler_index();
+ const unsigned shadow = base_type->sampler_shadow;
+ for (unsigned i = this->uniforms[id].sampler
+ ; i < this->next_sampler
+ ; i++) {
+ this->targets[i] = target;
+ this->shader_samplers_used |= 1U << i;
+ this->shader_shadow_samplers |= shadow << i;
+ }
+
} else {
this->uniforms[id].sampler = ~0;
}
@@ -270,6 +304,18 @@ private:
public:
union gl_constant_value *values;
+
+ gl_texture_index targets[MAX_SAMPLERS];
+
+ /**
+ * Mask of samplers used by the current shader stage.
+ */
+ unsigned shader_samplers_used;
+
+ /**
+ * Mask of samplers used by the current shader stage for shadows.
+ */
+ unsigned shader_shadow_samplers;
};
void
@@ -346,6 +392,10 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
if (prog->_LinkedShaders[i] == NULL)
continue;
+ /* Reset various per-shader target counts.
+ */
+ parcel.start_shader();
+
foreach_list(node, prog->_LinkedShaders[i]->ir) {
ir_variable *const var = ((ir_instruction *) node)->as_variable();
@@ -359,8 +409,14 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
parcel.process(var);
}
+
+ prog->_LinkedShaders[i]->active_samplers = parcel.shader_samplers_used;
+ prog->_LinkedShaders[i]->shadow_samplers = parcel.shader_shadow_samplers;
}
+ assert(sizeof(prog->SamplerTargets) == sizeof(parcel.targets));
+ memcpy(prog->SamplerTargets, parcel.targets, sizeof(prog->SamplerTargets));
+
#ifndef NDEBUG
for (unsigned i = 0; i < num_user_uniforms; i++) {
assert(uniforms[i].storage != NULL);
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index e8472d446..0d85aeee6 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -246,7 +246,8 @@ count_attribute_slots(const glsl_type *t)
/**
* Verify that a vertex shader executable meets all semantic requirements.
*
- * Also sets prog->Vert.UsesClipDistance as a side effect.
+ * Also sets prog->Vert.UsesClipDistance and prog->Vert.ClipDistanceArraySize
+ * as a side effect.
*
* \param shader Vertex shader executable to be verified
*/
@@ -264,6 +265,8 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
return false;
}
+ prog->Vert.ClipDistanceArraySize = 0;
+
if (prog->Version >= 130) {
/* From section 7.1 (Vertex Shader Special Variables) of the
* GLSL 1.30 spec:
@@ -282,6 +285,10 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
return false;
}
prog->Vert.UsesClipDistance = clip_distance.variable_found();
+ ir_variable *clip_distance_var =
+ shader->symbols->get_variable("gl_ClipDistance");
+ if (clip_distance_var)
+ prog->Vert.ClipDistanceArraySize = clip_distance_var->type->length;
}
return true;
@@ -1381,7 +1388,7 @@ public:
static bool is_same(const tfeedback_decl &x, const tfeedback_decl &y);
bool assign_location(struct gl_context *ctx, struct gl_shader_program *prog,
ir_variable *output_var);
- bool store(struct gl_shader_program *prog,
+ bool store(struct gl_context *ctx, struct gl_shader_program *prog,
struct gl_transform_feedback_info *info, unsigned buffer,
unsigned varying) const;
@@ -1399,7 +1406,10 @@ public:
*/
bool matches_var(ir_variable *var) const
{
- return strcmp(var->name, this->var_name) == 0;
+ if (this->is_clip_distance_mesa)
+ return strcmp(var->name, "gl_ClipDistanceMESA") == 0;
+ else
+ return strcmp(var->name, this->var_name) == 0;
}
/**
@@ -1408,7 +1418,10 @@ public:
*/
unsigned num_components() const
{
- return this->vector_elements * this->matrix_columns;
+ if (this->is_clip_distance_mesa)
+ return this->size;
+ else
+ return this->vector_elements * this->matrix_columns * this->size;
}
private:
@@ -1434,11 +1447,10 @@ private:
unsigned array_subscript;
/**
- * Which component to extract from the vertex shader output location that
- * the linker assigned to this variable. -1 if all components should be
- * extracted.
+ * True if the variable is gl_ClipDistance and the driver lowers
+ * gl_ClipDistance to gl_ClipDistanceMESA.
*/
- int single_component;
+ bool is_clip_distance_mesa;
/**
* The vertex shader output location that the linker assigned for this
@@ -1484,7 +1496,7 @@ tfeedback_decl::init(struct gl_context *ctx, struct gl_shader_program *prog,
this->location = -1;
this->orig_name = input;
- this->single_component = -1;
+ this->is_clip_distance_mesa = false;
const char *bracket = strrchr(input, '[');
@@ -1500,17 +1512,13 @@ tfeedback_decl::init(struct gl_context *ctx, struct gl_shader_program *prog,
this->is_subscripted = false;
}
- /* For drivers that lower gl_ClipDistance to gl_ClipDistanceMESA, we need
- * to convert a request for gl_ClipDistance[n] into a request for a
- * component of gl_ClipDistanceMESA[n/4].
+ /* For drivers that lower gl_ClipDistance to gl_ClipDistanceMESA, this
+ * class must behave specially to account for the fact that gl_ClipDistance
+ * is converted from a float[8] to a vec4[2].
*/
if (ctx->ShaderCompilerOptions[MESA_SHADER_VERTEX].LowerClipDistance &&
strcmp(this->var_name, "gl_ClipDistance") == 0) {
- this->var_name = "gl_ClipDistanceMESA";
- if (this->is_subscripted) {
- this->single_component = this->array_subscript % 4;
- this->array_subscript /= 4;
- }
+ this->is_clip_distance_mesa = true;
}
return true;
@@ -1530,8 +1538,6 @@ tfeedback_decl::is_same(const tfeedback_decl &x, const tfeedback_decl &y)
return false;
if (x.is_subscripted && x.array_subscript != y.array_subscript)
return false;
- if (x.single_component != y.single_component)
- return false;
return true;
}
@@ -1552,27 +1558,36 @@ tfeedback_decl::assign_location(struct gl_context *ctx,
/* Array variable */
const unsigned matrix_cols =
output_var->type->fields.array->matrix_columns;
+ unsigned actual_array_size = this->is_clip_distance_mesa ?
+ prog->Vert.ClipDistanceArraySize : output_var->type->array_size();
if (this->is_subscripted) {
/* Check array bounds. */
- if (this->array_subscript >=
- (unsigned) output_var->type->array_size()) {
+ if (this->array_subscript >= actual_array_size) {
linker_error(prog, "Transform feedback varying %s has index "
- "%i, but the array size is %i.",
+ "%i, but the array size is %u.",
this->orig_name, this->array_subscript,
- output_var->type->array_size());
+ actual_array_size);
return false;
}
- this->location =
- output_var->location + this->array_subscript * matrix_cols;
+ if (this->is_clip_distance_mesa) {
+ this->location =
+ output_var->location + this->array_subscript / 4;
+ } else {
+ this->location =
+ output_var->location + this->array_subscript * matrix_cols;
+ }
this->size = 1;
} else {
this->location = output_var->location;
- this->size = (unsigned) output_var->type->array_size();
+ this->size = actual_array_size;
}
this->vector_elements = output_var->type->fields.array->vector_elements;
this->matrix_columns = matrix_cols;
- this->type = output_var->type->fields.array->gl_type;
+ if (this->is_clip_distance_mesa)
+ this->type = GL_FLOAT;
+ else
+ this->type = output_var->type->fields.array->gl_type;
} else {
/* Regular variable (scalar, vector, or matrix) */
if (this->is_subscripted) {
@@ -1587,6 +1602,7 @@ tfeedback_decl::assign_location(struct gl_context *ctx,
this->matrix_columns = output_var->type->matrix_columns;
this->type = output_var->type->gl_type;
}
+
/* From GL_EXT_transform_feedback:
* A program will fail to link if:
*
@@ -1615,7 +1631,7 @@ tfeedback_decl::assign_location(struct gl_context *ctx,
* is returned.
*/
bool
-tfeedback_decl::store(struct gl_shader_program *prog,
+tfeedback_decl::store(struct gl_context *ctx, struct gl_shader_program *prog,
struct gl_transform_feedback_info *info,
unsigned buffer, unsigned varying) const
{
@@ -1631,21 +1647,63 @@ tfeedback_decl::store(struct gl_shader_program *prog,
this->orig_name);
return false;
}
- for (unsigned index = 0; index < this->size; ++index) {
+
+ /* From GL_EXT_transform_feedback:
+ * A program will fail to link if:
+ *
+ * * the total number of components to capture is greater than
+ * the constant MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT
+ * and the buffer mode is INTERLEAVED_ATTRIBS_EXT.
+ */
+ if (prog->TransformFeedback.BufferMode == GL_INTERLEAVED_ATTRIBS &&
+ info->BufferStride[buffer] + this->num_components() >
+ ctx->Const.MaxTransformFeedbackInterleavedComponents) {
+ linker_error(prog, "The MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS "
+ "limit has been exceeded.");
+ return false;
+ }
+
+ /* Verify that the checks on MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS
+ * and MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS are sufficient to prevent
+ * overflow of info->Outputs[]. In worst case we generate one entry in
+ * Outputs[] per component so a conservative check is to verify that the
+ * size of the array is greater than or equal to both
+ * MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS and
+ * MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS.
+ */
+ assert(Elements(info->Outputs) >=
+ ctx->Const.MaxTransformFeedbackInterleavedComponents);
+ assert(Elements(info->Outputs) >=
+ ctx->Const.MaxTransformFeedbackSeparateComponents);
+
+ unsigned translated_size = this->size;
+ if (this->is_clip_distance_mesa)
+ translated_size = (translated_size + 3) / 4;
+ unsigned components_so_far = 0;
+ for (unsigned index = 0; index < translated_size; ++index) {
for (unsigned v = 0; v < this->matrix_columns; ++v) {
- unsigned num_components =
- this->single_component >= 0 ? 1 : this->vector_elements;
+ unsigned num_components = this->vector_elements;
+ info->Outputs[info->NumOutputs].ComponentOffset = 0;
+ if (this->is_clip_distance_mesa) {
+ if (this->is_subscripted) {
+ num_components = 1;
+ info->Outputs[info->NumOutputs].ComponentOffset =
+ this->array_subscript % 4;
+ } else {
+ num_components = MIN2(4, this->size - components_so_far);
+ }
+ }
info->Outputs[info->NumOutputs].OutputRegister =
this->location + v + index * this->matrix_columns;
info->Outputs[info->NumOutputs].NumComponents = num_components;
info->Outputs[info->NumOutputs].OutputBuffer = buffer;
info->Outputs[info->NumOutputs].DstOffset = info->BufferStride[buffer];
- info->Outputs[info->NumOutputs].ComponentOffset =
- this->single_component >= 0 ? this->single_component : 0;
++info->NumOutputs;
info->BufferStride[buffer] += num_components;
+ components_so_far += num_components;
}
}
+ assert(components_so_far == this->num_components());
info->Varyings[varying].Name = ralloc_strdup(prog, this->orig_name);
info->Varyings[varying].Type = this->type;
@@ -1914,7 +1972,6 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
unsigned num_tfeedback_decls,
tfeedback_decl *tfeedback_decls)
{
- unsigned total_tfeedback_components = 0;
bool separate_attribs_mode =
prog->TransformFeedback.BufferMode == GL_SEPARATE_ATTRIBS;
@@ -1933,25 +1990,9 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
unsigned buffer = separate_attribs_mode ? i : 0;
- if (!tfeedback_decls[i].store(prog, &prog->LinkedTransformFeedback,
+ if (!tfeedback_decls[i].store(ctx, prog, &prog->LinkedTransformFeedback,
buffer, i))
return false;
- total_tfeedback_components += tfeedback_decls[i].num_components();
- }
-
- /* From GL_EXT_transform_feedback:
- * A program will fail to link if:
- *
- * * the total number of components to capture is greater than
- * the constant MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT
- * and the buffer mode is INTERLEAVED_ATTRIBS_EXT.
- */
- if (prog->TransformFeedback.BufferMode == GL_INTERLEAVED_ATTRIBS &&
- total_tfeedback_components >
- ctx->Const.MaxTransformFeedbackInterleavedComponents) {
- linker_error(prog, "The MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS "
- "limit has been exceeded.");
- return false;
}
return true;
diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c
index ad289aa70..dca3613a6 100644
--- a/mesalib/src/mesa/drivers/common/meta.c
+++ b/mesalib/src/mesa/drivers/common/meta.c
@@ -2920,8 +2920,8 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
/* setup texcoords (XXX what about border?) */
setup_texture_coords(faceTarget,
- 0.0f, 0.0f, /* width, height never used here */
slice,
+ 0, 0, /* width, height never used here */
verts[0].tex,
verts[1].tex,
verts[2].tex,
@@ -3071,6 +3071,8 @@ get_temp_image_type(struct gl_context *ctx, GLenum baseFormat)
switch (baseFormat) {
case GL_RGBA:
case GL_RGB:
+ case GL_RG:
+ case GL_RED:
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
@@ -3086,7 +3088,8 @@ get_temp_image_type(struct gl_context *ctx, GLenum baseFormat)
case GL_DEPTH_STENCIL:
return GL_UNSIGNED_INT_24_8;
default:
- _mesa_problem(ctx, "Unexpected format in get_temp_image_type()");
+ _mesa_problem(ctx, "Unexpected format %d in get_temp_image_type()",
+ baseFormat);
return 0;
}
}
diff --git a/mesalib/src/mesa/main/api_validate.c b/mesalib/src/mesa/main/api_validate.c
index 945f12752..b6871d0db 100644
--- a/mesalib/src/mesa/main/api_validate.c
+++ b/mesalib/src/mesa/main/api_validate.c
@@ -184,7 +184,7 @@ check_index_bounds(struct gl_context *ctx, GLsizei count, GLenum type,
ib.ptr = indices;
ib.obj = ctx->Array.ArrayObj->ElementArrayBufferObj;
- vbo_get_minmax_index(ctx, &prim, &ib, &min, &max);
+ vbo_get_minmax_indices(ctx, &prim, &ib, &min, &max, 1);
if ((int)(min + basevertex) < 0 ||
max + basevertex > ctx->Array.ArrayObj->_MaxElement) {
diff --git a/mesalib/src/mesa/main/arrayobj.c b/mesalib/src/mesa/main/arrayobj.c
index 4b3e07b85..29bfed8f5 100644
--- a/mesalib/src/mesa/main/arrayobj.c
+++ b/mesalib/src/mesa/main/arrayobj.c
@@ -303,7 +303,7 @@ _mesa_update_array_object_max_element(struct gl_context *ctx,
GLuint min = ~0u;
while (enabled) {
- GLint attrib = _mesa_ffsll(enabled) - 1;
+ GLint attrib = ffsll(enabled) - 1;
enabled &= ~BITFIELD64_BIT(attrib);
min = update_min(min, &arrayObj->VertexAttrib[attrib]);
}
diff --git a/mesalib/src/mesa/main/bitset.h b/mesalib/src/mesa/main/bitset.h
index c27b4c474..28b3c127e 100644
--- a/mesalib/src/mesa/main/bitset.h
+++ b/mesalib/src/mesa/main/bitset.h
@@ -88,7 +88,7 @@ __bitset_ffs(const BITSET_WORD *x, int n)
for (i = 0; i < n; i++) {
if (x[i])
- return _mesa_ffs(x[i]) + BITSET_WORDBITS * i;
+ return ffs(x[i]) + BITSET_WORDBITS * i;
}
return 0;
diff --git a/mesalib/src/mesa/main/buffers.c b/mesalib/src/mesa/main/buffers.c
index adea0f5f7..216b6ee87 100644
--- a/mesalib/src/mesa/main/buffers.c
+++ b/mesalib/src/mesa/main/buffers.c
@@ -35,6 +35,7 @@
#include "colormac.h"
#include "context.h"
#include "enums.h"
+#include "fbobject.h"
#include "mtypes.h"
@@ -51,11 +52,12 @@
* \return bitmask of BUFFER_BIT_* flags
*/
static GLbitfield
-supported_buffer_bitmask(const struct gl_context *ctx, const struct gl_framebuffer *fb)
+supported_buffer_bitmask(const struct gl_context *ctx,
+ const struct gl_framebuffer *fb)
{
GLbitfield mask = 0x0;
- if (fb->Name > 0) {
+ if (_mesa_is_user_fbo(fb)) {
/* A user-created renderbuffer */
GLuint i;
ASSERT(ctx->Extensions.EXT_framebuffer_object);
@@ -242,7 +244,8 @@ _mesa_DrawBuffer(GLenum buffer)
destMask = draw_buffer_enum_to_bitmask(buffer);
if (destMask == BAD_MASK) {
/* totally bogus buffer */
- _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(buffer=0x%x)", buffer);
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glDrawBuffer(buffer=0x%x)", buffer);
return;
}
destMask &= supportedMask;
@@ -340,6 +343,7 @@ _mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers)
ctx->Driver.DrawBuffer(ctx, n > 0 ? buffers[0] : GL_NONE);
}
+
/**
* Performs necessary state updates when _mesa_drawbuffers makes an
* actual change.
@@ -354,13 +358,14 @@ updated_drawbuffers(struct gl_context *ctx)
struct gl_framebuffer *fb = ctx->DrawBuffer;
/* Flag the FBO as requiring validation. */
- if (fb->Name != 0) {
+ if (_mesa_is_user_fbo(fb)) {
fb->_Status = 0;
}
}
#endif
}
+
/**
* Helper function to set the GL_DRAW_BUFFER state in the context and
* current FBO. Called via glDrawBuffer(), glDrawBuffersARB()
@@ -402,7 +407,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
if (n == 1) {
GLuint count = 0, destMask0 = destMask[0];
while (destMask0) {
- GLint bufIndex = _mesa_ffs(destMask0) - 1;
+ GLint bufIndex = ffs(destMask0) - 1;
if (fb->_ColorDrawBufferIndexes[count] != bufIndex) {
updated_drawbuffers(ctx);
fb->_ColorDrawBufferIndexes[count] = bufIndex;
@@ -417,7 +422,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
GLuint count = 0;
for (buf = 0; buf < n; buf++ ) {
if (destMask[buf]) {
- GLint bufIndex = _mesa_ffs(destMask[buf]) - 1;
+ GLint bufIndex = ffs(destMask[buf]) - 1;
/* only one bit should be set in the destMask[buf] field */
ASSERT(_mesa_bitcount(destMask[buf]) == 1);
if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) {
@@ -448,7 +453,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
fb->ColorDrawBuffer[buf] = GL_NONE;
}
- if (fb->Name == 0) {
+ if (_mesa_is_winsys_fbo(fb)) {
/* also set context drawbuffer state */
for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) {
if (ctx->Color.DrawBuffer[buf] != fb->ColorDrawBuffer[buf]) {
@@ -472,7 +477,7 @@ _mesa_update_draw_buffers(struct gl_context *ctx)
GLuint i;
/* should be a window system FBO */
- assert(ctx->DrawBuffer->Name == 0);
+ assert(_mesa_is_winsys_fbo(ctx->DrawBuffer));
for (i = 0; i < ctx->Const.MaxDrawBuffers; i++)
buffers[i] = ctx->Color.DrawBuffer[i];
@@ -493,7 +498,7 @@ _mesa_readbuffer(struct gl_context *ctx, GLenum buffer, GLint bufferIndex)
{
struct gl_framebuffer *fb = ctx->ReadBuffer;
- if (fb->Name == 0) {
+ if (_mesa_is_winsys_fbo(fb)) {
/* Only update the per-context READ_BUFFER state if we're bound to
* a window-system framebuffer.
*/
@@ -529,7 +534,7 @@ _mesa_ReadBuffer(GLenum buffer)
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
- if (fb->Name > 0 && buffer == GL_NONE) {
+ if (_mesa_is_user_fbo(fb) && buffer == GL_NONE) {
/* This is legal for user-created framebuffer objects */
srcBuffer = -1;
}
diff --git a/mesalib/src/mesa/main/clear.c b/mesalib/src/mesa/main/clear.c
index bd5c01224..e4df120d6 100644
--- a/mesalib/src/mesa/main/clear.c
+++ b/mesalib/src/mesa/main/clear.c
@@ -338,7 +338,7 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value)
drawbuffer);
return;
}
- else if (!ctx->RasterDiscard) {
+ else if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer && !ctx->RasterDiscard) {
/* Save current stencil clear value, set to 'value', do the
* stencil clear and restore the clear value.
* XXX in the future we may have a new ctx->Driver.ClearBuffer()
@@ -513,7 +513,7 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value)
drawbuffer);
return;
}
- else if (!ctx->RasterDiscard) {
+ else if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer && !ctx->RasterDiscard) {
/* Save current depth clear value, set to 'value', do the
* depth clear and restore the clear value.
* XXX in the future we may have a new ctx->Driver.ClearBuffer()
@@ -592,6 +592,8 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
GLfloat depth, GLint stencil)
{
GET_CURRENT_CONTEXT(ctx);
+ GLbitfield mask = 0;
+
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
FLUSH_CURRENT(ctx, 0);
@@ -622,7 +624,12 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
_mesa_update_state( ctx );
}
- {
+ if (ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer)
+ mask |= BUFFER_BIT_DEPTH;
+ if (ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer)
+ mask |= BUFFER_BIT_STENCIL;
+
+ if (mask) {
/* save current clear values */
const GLclampd clearDepthSave = ctx->Depth.Clear;
const GLuint clearStencilSave = ctx->Stencil.Clear;
@@ -636,7 +643,7 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer,
ctx->Driver.ClearStencil(ctx, stencil);
/* clear buffers */
- ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
+ ctx->Driver.Clear(ctx, mask);
/* restore */
ctx->Depth.Clear = clearDepthSave;
diff --git a/mesalib/src/mesa/main/drawpix.c b/mesalib/src/mesa/main/drawpix.c
index 9f5b0b36e..01983d945 100644
--- a/mesalib/src/mesa/main/drawpix.c
+++ b/mesalib/src/mesa/main/drawpix.c
@@ -203,6 +203,12 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
goto end;
}
+ if (ctx->ReadBuffer->Name != 0 && ctx->ReadBuffer->Visual.samples > 0) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION,
+ "glCopyPixels(multisample FBO)");
+ goto end;
+ }
+
if (!_mesa_source_buffer_exists(ctx, type) ||
!_mesa_dest_buffer_exists(ctx, type)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index aefcaf350..052495907 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -79,26 +79,6 @@ static struct gl_renderbuffer DummyRenderbuffer;
static struct gl_framebuffer IncompleteFramebuffer;
-/**
- * Is the given FBO a user-created FBO?
- */
-static inline GLboolean
-is_user_fbo(const struct gl_framebuffer *fb)
-{
- return fb->Name != 0;
-}
-
-
-/**
- * Is the given FBO a window system FBO (like an X window)?
- */
-static inline GLboolean
-is_winsys_fbo(const struct gl_framebuffer *fb)
-{
- return fb->Name == 0;
-}
-
-
static void
delete_dummy_renderbuffer(struct gl_renderbuffer *rb)
{
@@ -214,7 +194,7 @@ _mesa_get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
{
GLuint i;
- assert(is_user_fbo(fb));
+ assert(_mesa_is_user_fbo(fb));
switch (attachment) {
case GL_COLOR_ATTACHMENT0_EXT:
@@ -265,7 +245,7 @@ static struct gl_renderbuffer_attachment *
_mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
GLenum attachment)
{
- assert(is_winsys_fbo(fb));
+ assert(_mesa_is_winsys_fbo(fb));
switch (attachment) {
case GL_FRONT_LEFT:
@@ -711,7 +691,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx,
GLint i;
GLuint j;
- assert(is_user_fbo(fb));
+ assert(_mesa_is_user_fbo(fb));
numImages = 0;
fb->Width = 0;
@@ -1009,10 +989,10 @@ _mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
_mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
}
- if (is_user_fbo(ctx->DrawBuffer)) {
+ if (_mesa_is_user_fbo(ctx->DrawBuffer)) {
detach_renderbuffer(ctx, ctx->DrawBuffer, rb);
}
- if (is_user_fbo(ctx->ReadBuffer)
+ if (_mesa_is_user_fbo(ctx->ReadBuffer)
&& ctx->ReadBuffer != ctx->DrawBuffer) {
detach_renderbuffer(ctx, ctx->ReadBuffer, rb);
}
@@ -1318,7 +1298,7 @@ invalidate_rb(GLuint key, void *data, void *userData)
struct gl_renderbuffer *rb = (struct gl_renderbuffer *) userData;
/* If this is a user-created FBO */
- if (is_user_fbo(fb)) {
+ if (_mesa_is_user_fbo(fb)) {
GLuint i;
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = fb->Attachment + i;
@@ -1395,7 +1375,8 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
if (rb->InternalFormat == internalFormat &&
rb->Width == (GLuint) width &&
- rb->Height == (GLuint) height) {
+ rb->Height == (GLuint) height &&
+ rb->NumSamples == samples) {
/* no change in allocation needed */
return;
}
@@ -1609,7 +1590,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
GLuint i;
ASSERT(ctx->Driver.RenderTexture);
- if (is_winsys_fbo(fb))
+ if (_mesa_is_winsys_fbo(fb))
return; /* can't render to texture with winsys framebuffers */
for (i = 0; i < BUFFER_COUNT; i++) {
@@ -1629,7 +1610,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
static void
check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb)
{
- if (is_winsys_fbo(fb))
+ if (_mesa_is_winsys_fbo(fb))
return; /* can't render to texture with winsys framebuffers */
if (ctx->Driver.FinishRenderTexture) {
@@ -1882,7 +1863,7 @@ _mesa_CheckFramebufferStatusEXT(GLenum target)
return 0;
}
- if (is_winsys_fbo(buffer)) {
+ if (_mesa_is_winsys_fbo(buffer)) {
/* The window system / default framebuffer is always complete */
return GL_FRAMEBUFFER_COMPLETE_EXT;
}
@@ -1944,7 +1925,7 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
}
/* check framebuffer binding */
- if (is_winsys_fbo(fb)) {
+ if (_mesa_is_winsys_fbo(fb)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFramebufferTexture%sEXT", caller);
return;
@@ -2204,7 +2185,7 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
return;
}
- if (is_winsys_fbo(fb)) {
+ if (_mesa_is_winsys_fbo(fb)) {
/* Can't attach new renderbuffers to a window system framebuffer */
_mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
return;
@@ -2285,7 +2266,7 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
return;
}
- if (is_winsys_fbo(buffer)) {
+ if (_mesa_is_winsys_fbo(buffer)) {
/* Page 126 (page 136 of the PDF) of the OpenGL ES 2.0.25 spec
* says:
*
@@ -2332,7 +2313,8 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
switch (pname) {
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
- *params = is_winsys_fbo(buffer) ? GL_FRAMEBUFFER_DEFAULT : att->Type;
+ *params = _mesa_is_winsys_fbo(buffer)
+ ? GL_FRAMEBUFFER_DEFAULT : att->Type;
return;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
if (att->Type == GL_RENDERBUFFER_EXT) {
diff --git a/mesalib/src/mesa/main/fbobject.h b/mesalib/src/mesa/main/fbobject.h
index 0a70a436d..3aee842f5 100644
--- a/mesalib/src/mesa/main/fbobject.h
+++ b/mesalib/src/mesa/main/fbobject.h
@@ -32,6 +32,28 @@
struct gl_context;
struct gl_texture_object;
+
+/**
+ * Is the given FBO a user-created FBO?
+ */
+static inline GLboolean
+_mesa_is_user_fbo(const struct gl_framebuffer *fb)
+{
+ return fb->Name != 0;
+}
+
+
+/**
+ * Is the given FBO a window system FBO (like an X window)?
+ */
+static inline GLboolean
+_mesa_is_winsys_fbo(const struct gl_framebuffer *fb)
+{
+ return fb->Name == 0;
+}
+
+
+
extern void
_mesa_init_fbobjects(struct gl_context *ctx);
diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp
index 3e736fa15..afc17dc49 100644
--- a/mesalib/src/mesa/main/ff_fragment_shader.cpp
+++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp
@@ -42,6 +42,7 @@ extern "C" {
#include "program/programopt.h"
#include "texenvprogram.h"
}
+#include "main/uniforms.h"
#include "../glsl/glsl_types.h"
#include "../glsl/ir.h"
#include "../glsl/glsl_symbol_table.h"
@@ -294,7 +295,7 @@ need_saturate( GLuint mode )
static GLuint translate_tex_src_bit( GLbitfield bit )
{
ASSERT(bit);
- return _mesa_ffs(bit) - 1;
+ return ffs(bit) - 1;
}
@@ -527,7 +528,7 @@ struct texenv_fragment_program {
*/
/* Texcoord override from bumpmapping. */
- struct ir_variable *texcoord_tex[MAX_TEXTURE_COORD_UNITS];
+ ir_variable *texcoord_tex[MAX_TEXTURE_COORD_UNITS];
/* Reg containing texcoord for a texture unit,
* needed for bump mapping, else undef.
@@ -1498,25 +1499,48 @@ create_new_program(struct gl_context *ctx, struct state_key *key)
/* Set the sampler uniforms, and relink to get them into the linked
* program.
*/
- struct gl_program *fp;
- fp = p.shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
+ struct gl_shader *const fs =
+ p.shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT];
+ struct gl_program *const fp = fs->Program;
+
+ _mesa_generate_parameters_list_for_uniforms(p.shader_program, fs,
+ fp->Parameters);
+
+ _mesa_associate_uniform_storage(ctx, p.shader_program, fp->Parameters);
for (unsigned int i = 0; i < MAX_TEXTURE_UNITS; i++) {
- char *name = ralloc_asprintf(p.mem_ctx, "sampler_%d", i);
+ /* Enough space for 'sampler_999\0'.
+ */
+ char name[12];
+
+ snprintf(name, sizeof(name), "sampler_%d", i);
+
int loc = _mesa_get_uniform_location(ctx, p.shader_program, name);
if (loc != -1) {
+ unsigned base;
+ unsigned idx;
+
/* Avoid using _mesa_uniform() because it flags state
* updates, so if we're generating this shader_program in a
* state update, we end up recursing. Instead, just set the
* value, which is picked up at re-link.
*/
- loc = (loc & 0xffff) + (loc >> 16);
- int sampler = fp->Parameters->ParameterValues[loc][0].f;
+ _mesa_uniform_split_location_offset(loc, &base, &idx);
+ assert(idx == 0);
- fp->SamplerUnits[sampler] = i;
+ struct gl_uniform_storage *const storage =
+ &p.shader_program->UniformStorage[base];
+
+ /* Update the storage, the SamplerUnits in the shader program, and
+ * the SamplerUnits in the assembly shader.
+ */
+ storage->storage[idx].i = i;
+ fp->SamplerUnits[storage->sampler] = i;
+ p.shader_program->SamplerUnits[storage->sampler] = i;
+ _mesa_propagate_uniforms_to_driver_storage(storage, 0, 1);
}
}
- _mesa_update_shader_textures_used(fp);
+ _mesa_update_shader_textures_used(p.shader_program, fp);
(void) ctx->Driver.ProgramStringNotify(ctx, fp->Target, fp);
if (!p.shader_program->LinkStatus)
diff --git a/mesalib/src/mesa/main/ffvertex_prog.c b/mesalib/src/mesa/main/ffvertex_prog.c
index 19d319a56..f1ab75333 100644
--- a/mesalib/src/mesa/main/ffvertex_prog.c
+++ b/mesalib/src/mesa/main/ffvertex_prog.c
@@ -378,7 +378,7 @@ static struct ureg swizzle1( struct ureg reg, int x )
static struct ureg get_temp( struct tnl_program *p )
{
- int bit = _mesa_ffs( ~p->temp_in_use );
+ int bit = ffs( ~p->temp_in_use );
if (!bit) {
_mesa_problem(NULL, "%s: out of temporaries\n", __FILE__);
exit(1);
diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c
index 730de6206..7c3c4e345 100644
--- a/mesalib/src/mesa/main/framebuffer.c
+++ b/mesalib/src/mesa/main/framebuffer.c
@@ -281,8 +281,8 @@ _mesa_resize_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb,
* and return early.
*/
- /* For window system framebuffers, Name is zero */
- assert(fb->Name == 0);
+ /* Can only resize win-sys framebuffer objects */
+ assert(_mesa_is_winsys_fbo(fb));
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
@@ -408,7 +408,7 @@ update_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb)
GLuint i;
/* user-created framebuffers only */
- assert(fb->Name);
+ assert(_mesa_is_user_fbo(fb));
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
@@ -687,7 +687,7 @@ update_color_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb)
static void
update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb)
{
- if (fb->Name == 0) {
+ if (_mesa_is_winsys_fbo(fb)) {
/* This is a window-system framebuffer */
/* Need to update the FB's GL_DRAW_BUFFER state to match the
* context state (GL_READ_BUFFER too).
@@ -851,7 +851,6 @@ _mesa_source_buffer_exists(struct gl_context *ctx, GLenum format)
/**
* As above, but for drawing operations.
- * XXX could do some code merging w/ above function.
*/
GLboolean
_mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format)
diff --git a/mesalib/src/mesa/main/hash.c b/mesalib/src/mesa/main/hash.c
index 4b250ad54..61c369a80 100644
--- a/mesalib/src/mesa/main/hash.c
+++ b/mesalib/src/mesa/main/hash.c
@@ -480,6 +480,26 @@ _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys)
}
+/**
+ * Return the number of entries in the hash table.
+ */
+GLuint
+_mesa_HashNumEntries(const struct _mesa_HashTable *table)
+{
+ GLuint pos, count = 0;
+
+ for (pos = 0; pos < TABLE_SIZE; pos++) {
+ const struct HashEntry *entry;
+ for (entry = table->Table[pos]; entry; entry = entry->Next) {
+ count++;
+ }
+ }
+
+ return count;
+}
+
+
+
#if 0 /* debug only */
/**
diff --git a/mesalib/src/mesa/main/hash.h b/mesalib/src/mesa/main/hash.h
index 4f916f9d0..e935f8d39 100644
--- a/mesalib/src/mesa/main/hash.h
+++ b/mesalib/src/mesa/main/hash.h
@@ -63,6 +63,9 @@ extern void _mesa_HashPrint(const struct _mesa_HashTable *table);
extern GLuint _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys);
+extern GLuint
+_mesa_HashNumEntries(const struct _mesa_HashTable *table);
+
extern void _mesa_test_hash_functions(void);
diff --git a/mesalib/src/mesa/main/imports.c b/mesalib/src/mesa/main/imports.c
index 2469e4265..bbc6ac6e2 100644
--- a/mesalib/src/mesa/main/imports.c
+++ b/mesalib/src/mesa/main/imports.c
@@ -458,9 +458,8 @@ _mesa_inv_sqrtf(float n)
* Find the first bit set in a word.
*/
int
-_mesa_ffs(int32_t i)
+ffs(int i)
{
-#if (defined(_WIN32) ) || defined(__IBMC__) || defined(__IBMCPP__)
register int bit = 0;
if (i != 0) {
if ((i & 0xffff) == 0) {
@@ -482,9 +481,6 @@ _mesa_ffs(int32_t i)
bit++;
}
return bit;
-#else
- return ffs(i);
-#endif
}
@@ -495,23 +491,24 @@ _mesa_ffs(int32_t i)
* if no bits set.
*/
int
-_mesa_ffsll(int64_t val)
+ffsll(long long int val)
{
int bit;
assert(sizeof(val) == 8);
- bit = _mesa_ffs((int32_t)val);
+ bit = ffs((int) val);
if (bit != 0)
return bit;
- bit = _mesa_ffs((int32_t)(val >> 32));
+ bit = ffs((int) (val >> 32));
if (bit != 0)
return 32 + bit;
return 0;
}
-#endif
+#endif /* __GNUC__ */
+
#if !defined(__GNUC__) ||\
((__GNUC__ * 100 + __GNUC_MINOR__) < 304) /* Not gcc 3.4 or later */
diff --git a/mesalib/src/mesa/main/imports.h b/mesalib/src/mesa/main/imports.h
index b7e87439f..ce7b45d77 100644
--- a/mesalib/src/mesa/main/imports.h
+++ b/mesalib/src/mesa/main/imports.h
@@ -566,6 +566,9 @@ _mesa_inv_sqrtf(float x);
extern void
_mesa_init_sqrt_table(void);
+
+#ifndef FFS_DEFINED
+#define FFS_DEFINED 1
#ifdef __GNUC__
#if defined(__MINGW32__) || defined(__CYGWIN__) || defined(ANDROID) || defined(__APPLE__)
@@ -573,10 +576,16 @@ _mesa_init_sqrt_table(void);
#define ffsll __builtin_ffsll
#endif
-#define _mesa_ffs(i) ffs(i)
-#define _mesa_ffsll(i) ffsll(i)
+#else
+
+extern int ffs(int i);
+extern int ffsll(long long int i);
+
+#endif /*__ GNUC__ */
+#endif /* FFS_DEFINED */
-#if ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
+
+#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) /* gcc 3.4 or later */
#define _mesa_bitcount(i) __builtin_popcount(i)
#define _mesa_bitcount_64(i) __builtin_popcountll(i)
#else
@@ -586,16 +595,6 @@ extern unsigned int
_mesa_bitcount_64(uint64_t n);
#endif
-#else
-extern int
-_mesa_ffs(int32_t i);
-
-extern int
-_mesa_ffsll(int64_t i);
-
-extern unsigned int
-_mesa_bitcount(unsigned int n);
-#endif
extern GLhalfARB
_mesa_float_to_half(float f);
diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c
index 867506c9f..03ce5361e 100644
--- a/mesalib/src/mesa/main/mipmap.c
+++ b/mesalib/src/mesa/main/mipmap.c
@@ -476,7 +476,7 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth,
GLuint *dst = (GLuint *) dstRow;
for (i = j = 0, k = k0; i < (GLuint) dstWidth;
i++, j += colStride, k += colStride) {
- dst[i] = (GLfloat)(rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4);
+ dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4;
}
}
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 64d8c8d3f..9fdabf98c 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1894,8 +1894,6 @@ struct gl_program
/** Map from sampler unit to texture unit (set by glUniform1i()) */
GLubyte SamplerUnits[MAX_SAMPLERS];
- /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */
- gl_texture_index SamplerTargets[MAX_SAMPLERS];
/** Bitmask of which register files are read/written with indirect
* addressing. Mask of (1 << PROGRAM_x) bits.
@@ -2185,9 +2183,17 @@ struct gl_shader
unsigned Version; /**< GLSL version used for linking */
- unsigned num_samplers; /**< Number of samplers used by this shader.
- * This field is only set post-linking.
- */
+ /**
+ * \name Sampler tracking
+ *
+ * \note Each of these fields is only set post-linking.
+ */
+ /*@{*/
+ unsigned num_samplers; /**< Number of samplers used by this shader. */
+ GLbitfield active_samplers; /**< Bitfield of which samplers are used */
+ GLbitfield shadow_samplers; /**< Samplers used for shadow sampling. */
+ /*@}*/
+
/**
* Number of uniform components used by this shader.
*
@@ -2277,6 +2283,8 @@ struct gl_shader_program
/** Vertex shader state - copied into gl_vertex_program at link time */
struct {
GLboolean UsesClipDistance; /**< True if gl_ClipDistance is written to. */
+ GLuint ClipDistanceArraySize; /**< Size of the gl_ClipDistance array, or
+ 0 if not present. */
} Vert;
/* post-link info: */
@@ -2348,6 +2356,8 @@ struct gl_shader_state
struct gl_shader_program *CurrentGeometryProgram;
struct gl_shader_program *CurrentFragmentProgram;
+ struct gl_shader_program *_CurrentFragmentProgram;
+
/**
* Program used by glUniform calls.
*
diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c
index 0c0e5394d..c1489d211 100644
--- a/mesalib/src/mesa/main/readpix.c
+++ b/mesalib/src/mesa/main/readpix.c
@@ -782,6 +782,11 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
return;
}
+ if (ctx->ReadBuffer->Name != 0 && ctx->ReadBuffer->Visual.samples > 0) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
+ return;
+ }
+
if (!_mesa_source_buffer_exists(ctx, format)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
return;
diff --git a/mesalib/src/mesa/main/renderbuffer.c b/mesalib/src/mesa/main/renderbuffer.c
index bb8f46d11..08e694673 100644
--- a/mesalib/src/mesa/main/renderbuffer.c
+++ b/mesalib/src/mesa/main/renderbuffer.c
@@ -132,7 +132,7 @@ _mesa_add_renderbuffer(struct gl_framebuffer *fb,
fb->Attachment[bufferName].Renderbuffer == NULL);
/* winsys vs. user-created buffer cross check */
- if (fb->Name) {
+ if (_mesa_is_user_fbo(fb)) {
assert(rb->Name);
}
else {
diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c
index 9372d6dec..0e655a0d8 100644
--- a/mesalib/src/mesa/main/shaderapi.c
+++ b/mesalib/src/mesa/main/shaderapi.c
@@ -45,6 +45,7 @@
#include "main/mtypes.h"
#include "main/shaderapi.h"
#include "main/shaderobj.h"
+#include "main/uniforms.h"
#include "program/program.h"
#include "program/prog_parameter.h"
#include "ralloc.h"
@@ -124,6 +125,8 @@ _mesa_free_shader_state(struct gl_context *ctx)
NULL);
_mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram,
NULL);
+ _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram,
+ NULL);
_mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL);
}
@@ -876,6 +879,33 @@ use_shader_program(struct gl_context *ctx, GLenum type,
if (*target != shProg) {
FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+
+ /* If the shader is also bound as the current rendering shader, unbind
+ * it from that binding point as well. This ensures that the correct
+ * semantics of glDeleteProgram are maintained.
+ */
+ switch (type) {
+#if FEATURE_ARB_vertex_shader
+ case GL_VERTEX_SHADER:
+ /* Empty for now. */
+ break;
+#endif
+#if FEATURE_ARB_geometry_shader4
+ case GL_GEOMETRY_SHADER_ARB:
+ /* Empty for now. */
+ break;
+#endif
+#if FEATURE_ARB_fragment_shader
+ case GL_FRAGMENT_SHADER:
+ if (*target == ctx->Shader._CurrentFragmentProgram) {
+ _mesa_reference_shader_program(ctx,
+ &ctx->Shader._CurrentFragmentProgram,
+ NULL);
+ }
+ break;
+#endif
+ }
+
_mesa_reference_shader_program(ctx, target, shProg);
return true;
}
@@ -900,61 +930,6 @@ _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg)
/**
- * Validate a program's samplers.
- * Specifically, check that there aren't two samplers of different types
- * pointing to the same texture unit.
- * \return GL_TRUE if valid, GL_FALSE if invalid
- */
-static GLboolean
-validate_samplers(const struct gl_program *prog, char *errMsg)
-{
- static const char *targetName[] = {
- "TEXTURE_BUFFER",
- "TEXTURE_2D_ARRAY",
- "TEXTURE_1D_ARRAY",
- "TEXTURE_EXTERNAL",
- "TEXTURE_CUBE",
- "TEXTURE_3D",
- "TEXTURE_RECT",
- "TEXTURE_2D",
- "TEXTURE_1D",
- };
- GLint targetUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
- GLbitfield samplersUsed = prog->SamplersUsed;
- GLuint i;
-
- STATIC_ASSERT(Elements(targetName) == NUM_TEXTURE_TARGETS);
-
- if (samplersUsed == 0x0)
- return GL_TRUE;
-
- for (i = 0; i < Elements(targetUsed); i++)
- targetUsed[i] = -1;
-
- /* walk over bits which are set in 'samplers' */
- while (samplersUsed) {
- GLuint unit;
- gl_texture_index target;
- GLint sampler = _mesa_ffs(samplersUsed) - 1;
- assert(sampler >= 0);
- assert(sampler < Elements(prog->SamplerUnits));
- unit = prog->SamplerUnits[sampler];
- target = prog->SamplerTargets[sampler];
- if (targetUsed[unit] != -1 && targetUsed[unit] != (int) target) {
- _mesa_snprintf(errMsg, 100,
- "Texture unit %d is accessed both as %s and %s",
- unit, targetName[targetUsed[unit]], targetName[target]);
- return GL_FALSE;
- }
- targetUsed[unit] = target;
- samplersUsed ^= (1 << sampler);
- }
-
- return GL_TRUE;
-}
-
-
-/**
* Do validation of the given shader program.
* \param errMsg returns error message if validation fails.
* \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
@@ -963,8 +938,6 @@ static GLboolean
validate_shader_program(const struct gl_shader_program *shProg,
char *errMsg)
{
- unsigned i;
-
if (!shProg->LinkStatus) {
return GL_FALSE;
}
@@ -989,12 +962,8 @@ validate_shader_program(const struct gl_shader_program *shProg,
* Check: any two active samplers in the current program object are of
* different types, but refer to the same texture image unit,
*/
- for (i = 0; i < Elements(shProg->_LinkedShaders); i++) {
- if (shProg->_LinkedShaders[i]
- && !validate_samplers(shProg->_LinkedShaders[i]->Program, errMsg)) {
- return GL_FALSE;
- }
- }
+ if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100))
+ return GL_FALSE;
return GL_TRUE;
}
diff --git a/mesalib/src/mesa/main/state.c b/mesalib/src/mesa/main/state.c
index 7e43563bd..b910543e2 100644
--- a/mesalib/src/mesa/main/state.c
+++ b/mesalib/src/mesa/main/state.c
@@ -43,6 +43,7 @@
#include "pixel.h"
#include "program/program.h"
#include "program/prog_parameter.h"
+#include "shaderobj.h"
#include "state.h"
#include "stencil.h"
#include "texenvprogram.h"
@@ -227,7 +228,7 @@ update_program(struct gl_context *ctx)
{
const struct gl_shader_program *vsProg = ctx->Shader.CurrentVertexProgram;
const struct gl_shader_program *gsProg = ctx->Shader.CurrentGeometryProgram;
- const struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram;
+ struct gl_shader_program *fsProg = ctx->Shader.CurrentFragmentProgram;
const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current;
const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current;
const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current;
@@ -252,12 +253,18 @@ update_program(struct gl_context *ctx)
if (fsProg && fsProg->LinkStatus
&& fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) {
/* Use GLSL fragment shader */
+ _mesa_reference_shader_program(ctx,
+ &ctx->Shader._CurrentFragmentProgram,
+ fsProg);
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
(struct gl_fragment_program *)
fsProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
}
else if (ctx->FragmentProgram._Enabled) {
/* Use user-defined fragment program */
+ _mesa_reference_shader_program(ctx,
+ &ctx->Shader._CurrentFragmentProgram,
+ NULL);
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
ctx->FragmentProgram.Current);
}
@@ -265,6 +272,9 @@ update_program(struct gl_context *ctx)
/* Use fragment program generated from fixed-function state */
struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx);
+ _mesa_reference_shader_program(ctx,
+ &ctx->Shader._CurrentFragmentProgram,
+ f);
_mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current,
(struct gl_fragment_program *)
f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program);
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 9475e84f5..39732522c 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -1900,7 +1900,7 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
}
/* Check that the source buffer is complete */
- if (ctx->ReadBuffer->Name) {
+ if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
if (ctx->ReadBuffer->_Status == 0) {
_mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
}
@@ -1909,6 +1909,13 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
"glCopyTexImage%dD(invalid readbuffer)", dimensions);
return GL_TRUE;
}
+
+ if (ctx->ReadBuffer->Visual.samples > 0) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION,
+ "glCopyTexImage%dD(multisample FBO)",
+ dimensions);
+ return GL_TRUE;
+ }
}
/* Check border */
@@ -1999,7 +2006,7 @@ copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
GLenum target, GLint level)
{
/* Check that the source buffer is complete */
- if (ctx->ReadBuffer->Name) {
+ if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
if (ctx->ReadBuffer->_Status == 0) {
_mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
}
@@ -2008,6 +2015,13 @@ copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
"glCopyTexImage%dD(invalid readbuffer)", dimensions);
return GL_TRUE;
}
+
+ if (ctx->ReadBuffer->Visual.samples > 0) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION,
+ "glCopyTexSubImage%dD(multisample FBO)",
+ dimensions);
+ return GL_TRUE;
+ }
}
/* check target (proxies not allowed) */
@@ -2179,7 +2193,7 @@ check_rtt_cb(GLuint key, void *data, void *userData)
const GLuint level = info->level, face = info->face;
/* If this is a user-created FBO */
- if (fb->Name) {
+ if (_mesa_is_user_fbo(fb)) {
GLuint i;
/* check if any of the FBO's attachments point to 'texObj' */
for (i = 0; i < BUFFER_COUNT; i++) {
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index 7ee200585..1b61d3a63 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -672,9 +672,11 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
return;
}
/* Don't support GL_DEPTH_COMPONENT for cube maps */
- if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
- incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
- return;
+ if (ctx->VersionMajor < 3 && !ctx->Extensions.EXT_gpu_shader4) {
+ if (t->Image[face][i]->_BaseFormat == GL_DEPTH_COMPONENT) {
+ incomplete(t, "GL_DEPTH_COMPONENT only works with 1/2D tex");
+ return;
+ }
}
/* check that all six images have same size */
if (t->Image[face][i]->Width2 != width ||
@@ -891,7 +893,7 @@ unbind_texobj_from_fbo(struct gl_context *ctx,
for (i = 0; i < n; i++) {
struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer;
- if (fb->Name) {
+ if (_mesa_is_user_fbo(fb)) {
GLuint j;
for (j = 0; j < BUFFER_COUNT; j++) {
if (fb->Attachment[j].Type == GL_TEXTURE &&
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c
index 512965fc3..a9c64cede 100644
--- a/mesalib/src/mesa/main/texstore.c
+++ b/mesalib/src/mesa/main/texstore.c
@@ -515,9 +515,9 @@ make_temp_uint_image(struct gl_context *ctx, GLuint dims,
for (k = 0; k < texComponents; k++) {
GLint j = map[k];
if (j == ZERO)
- newImage[i * texComponents + k] = 0.0F;
+ newImage[i * texComponents + k] = 0;
else if (j == ONE)
- newImage[i * texComponents + k] = 1.0F;
+ newImage[i * texComponents + k] = 1;
else
newImage[i * texComponents + k] = tempImage[i * logComponents + j];
}
@@ -4094,7 +4094,7 @@ _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
_mesa_unpack_depth_span(ctx, srcWidth,
GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
dstRow, /* dst addr */
- 1.0f, srcType, src, srcPacking);
+ ~0U, srcType, src, srcPacking);
if (srcFormat != GL_DEPTH_COMPONENT)
_mesa_unpack_stencil_span(ctx, srcWidth,
diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp
index f3d6a16ee..869f7d373 100644
--- a/mesalib/src/mesa/main/uniform_query.cpp
+++ b/mesalib/src/mesa/main/uniform_query.cpp
@@ -691,19 +691,16 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
bool flushed = false;
for (i = 0; i < MESA_SHADER_TYPES; i++) {
- struct gl_program *prog;
-
- if (shProg->_LinkedShaders[i] == NULL)
- continue;
-
- prog = shProg->_LinkedShaders[i]->Program;
+ struct gl_shader *const sh = shProg->_LinkedShaders[i];
/* If the shader stage doesn't use any samplers, don't bother
* checking if any samplers have changed.
*/
- if (prog->SamplersUsed == 0)
+ if (sh == NULL || sh->active_samplers == 0)
continue;
+ struct gl_program *const prog = sh->Program;
+
assert(sizeof(prog->SamplerUnits) == sizeof(shProg->SamplerUnits));
/* Determine if any of the samplers used by this shader stage have
@@ -711,7 +708,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
*/
bool changed = false;
for (unsigned j = 0; j < Elements(prog->SamplerUnits); j++) {
- if ((prog->SamplersUsed & (1U << j)) != 0
+ if ((sh->active_samplers & (1U << j)) != 0
&& (prog->SamplerUnits[j] != shProg->SamplerUnits[j])) {
changed = true;
break;
@@ -728,7 +725,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
shProg->SamplerUnits,
sizeof(shProg->SamplerUnits));
- _mesa_update_shader_textures_used(prog);
+ _mesa_update_shader_textures_used(shProg, prog);
(void) ctx->Driver.ProgramStringNotify(ctx, prog->Target, prog);
}
}
@@ -933,3 +930,46 @@ _mesa_get_uniform_location(struct gl_context *ctx,
return _mesa_uniform_merge_location_offset(location, offset);
}
+
+extern "C" bool
+_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
+ char *errMsg, size_t errMsgLength)
+{
+ const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
+
+ memset(unit_types, 0, sizeof(unit_types));
+
+ for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) {
+ const struct gl_uniform_storage *const storage =
+ &shProg->UniformStorage[i];
+ const glsl_type *const t = (storage->type->is_array())
+ ? storage->type->fields.array : storage->type;
+
+ if (!t->is_sampler())
+ continue;
+
+ const unsigned count = MAX2(1, storage->type->array_size());
+ for (unsigned j = 0; j < count; j++) {
+ const unsigned unit = storage->storage[j].i;
+
+ /* The types of the samplers associated with a particular texture
+ * unit must be an exact match. Page 74 (page 89 of the PDF) of the
+ * OpenGL 3.3 core spec says:
+ *
+ * "It is not allowed to have variables of different sampler
+ * types pointing to the same texture image unit within a program
+ * object."
+ */
+ if (unit_types[unit] == NULL) {
+ unit_types[unit] = t;
+ } else if (unit_types[unit] != t) {
+ _mesa_snprintf(errMsg, errMsgLength,
+ "Texture unit %d is accessed both as %s and %s",
+ unit, unit_types[unit]->name, t->name);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c
index 685c0f13f..e0214a88a 100644
--- a/mesalib/src/mesa/main/uniforms.c
+++ b/mesalib/src/mesa/main/uniforms.c
@@ -60,7 +60,8 @@
* We'll use that info for state validation before rendering.
*/
void
-_mesa_update_shader_textures_used(struct gl_program *prog)
+_mesa_update_shader_textures_used(struct gl_shader_program *shProg,
+ struct gl_program *prog)
{
GLuint s;
@@ -68,8 +69,8 @@ _mesa_update_shader_textures_used(struct gl_program *prog)
for (s = 0; s < MAX_SAMPLERS; s++) {
if (prog->SamplersUsed & (1 << s)) {
- GLuint unit = prog->SamplerUnits[s];
- GLuint tgt = prog->SamplerTargets[s];
+ GLuint unit = shProg->SamplerUnits[s];
+ GLuint tgt = shProg->SamplerTargets[s];
assert(unit < Elements(prog->TexturesUsed));
assert(tgt < NUM_TEXTURE_TARGETS);
prog->TexturesUsed[unit] |= (1 << tgt);
diff --git a/mesalib/src/mesa/main/uniforms.h b/mesalib/src/mesa/main/uniforms.h
index 123d7b954..7b512a527 100644
--- a/mesalib/src/mesa/main/uniforms.h
+++ b/mesalib/src/mesa/main/uniforms.h
@@ -212,8 +212,12 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni,
unsigned count);
extern void
-_mesa_update_shader_textures_used(struct gl_program *prog);
+_mesa_update_shader_textures_used(struct gl_shader_program *shProg,
+ struct gl_program *prog);
+extern bool
+_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
+ char *errMsg, size_t errMsgLength);
extern void
_mesa_init_shader_uniform_dispatch(struct _glapi_table *exec);
diff --git a/mesalib/src/mesa/main/version.h b/mesalib/src/mesa/main/version.h
index d288c4d55..8723c1f57 100644
--- a/mesalib/src/mesa/main/version.h
+++ b/mesalib/src/mesa/main/version.h
@@ -42,17 +42,6 @@ struct gl_context;
#define MESA_VERSION_CODE MESA_VERSION(MESA_MAJOR, MESA_MINOR, MESA_PATCH)
-/* OpenGL API version */
-#define OPENGL_MAJOR 2
-#define OPENGL_MINOR 1
-#define OPENGL_PATCH 0
-#define OPENGL_VERSION_STRING "2.1"
-
-/* To make version comparison easy */
-#define OPENGL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-#define OPENGL_VERSION_CODE OPENGL_VERSION(OPENGL_MAJOR, OPENGL_MINOR, OPENGL_PATCH)
-
-
extern void
_mesa_compute_version(struct gl_context *ctx);
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 5a68fc51d..6a90d5ad7 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -2490,34 +2490,6 @@ print_program(struct prog_instruction *mesa_instructions,
}
}
-
-/**
- * Count resources used by the given gpu program (number of texture
- * samplers, etc).
- */
-static void
-count_resources(struct gl_program *prog)
-{
- unsigned int i;
-
- prog->SamplersUsed = 0;
-
- for (i = 0; i < prog->NumInstructions; i++) {
- struct prog_instruction *inst = &prog->Instructions[i];
-
- if (_mesa_is_tex_instruction(inst->Opcode)) {
- prog->SamplerTargets[inst->TexSrcUnit] =
- (gl_texture_index)inst->TexSrcTarget;
- prog->SamplersUsed |= 1 << inst->TexSrcUnit;
- if (inst->TexShadow) {
- prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
- }
- }
- }
-
- _mesa_update_shader_textures_used(prog);
-}
-
class add_uniform_to_shader : public uniform_field_visitor {
public:
add_uniform_to_shader(struct gl_shader_program *shader_program,
@@ -3197,7 +3169,10 @@ get_mesa_program(struct gl_context *ctx,
mesa_instructions = NULL;
do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER);
- count_resources(prog);
+
+ prog->SamplersUsed = shader->active_samplers;
+ prog->ShadowSamplers = shader->shadow_samplers;
+ _mesa_update_shader_textures_used(shader_program, prog);
/* Set the gl_FragDepth layout. */
if (target == GL_FRAGMENT_PROGRAM_ARB) {
diff --git a/mesalib/src/mesa/program/prog_print.c b/mesalib/src/mesa/program/prog_print.c
index 352a80f27..46f1df0fc 100644
--- a/mesalib/src/mesa/program/prog_print.c
+++ b/mesalib/src/mesa/program/prog_print.c
@@ -194,7 +194,7 @@ _mesa_print_vp_inputs(GLbitfield inputs)
{
printf("VP Inputs 0x%x: \n", inputs);
while (inputs) {
- GLint attr = _mesa_ffs(inputs) - 1;
+ GLint attr = ffs(inputs) - 1;
const char *name = arb_input_attrib_string(attr,
GL_VERTEX_PROGRAM_ARB);
printf(" %d: %s\n", attr, name);
@@ -212,7 +212,7 @@ _mesa_print_fp_inputs(GLbitfield inputs)
{
printf("FP Inputs 0x%x: \n", inputs);
while (inputs) {
- GLint attr = _mesa_ffs(inputs) - 1;
+ GLint attr = ffs(inputs) - 1;
const char *name = arb_input_attrib_string(attr,
GL_FRAGMENT_PROGRAM_ARB);
printf(" %d: %s\n", attr, name);
diff --git a/mesalib/src/mesa/state_tracker/st_atom_texture.c b/mesalib/src/mesa/state_tracker/st_atom_texture.c
index 008e9bd10..88e6128c8 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_texture.c
@@ -1,8 +1,8 @@
/**************************************************************************
- *
+ *
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
- *
+ *
* 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
@@ -10,11 +10,11 @@
* distribute, sub license, 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 (including the
* next paragraph) 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 NON-INFRINGEMENT.
@@ -22,7 +22,7 @@
* 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.
- *
+ *
**************************************************************************/
/*
@@ -30,7 +30,7 @@
* Keith Whitwell <keith@tungstengraphics.com>
* Brian Paul
*/
-
+
#include "main/macros.h"
#include "main/mtypes.h"
@@ -182,8 +182,10 @@ st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj,
return stObj->sampler_view;
}
+
static GLboolean
-update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_view,
+update_single_texture(struct st_context *st,
+ struct pipe_sampler_view **sampler_view,
GLuint texUnit)
{
struct pipe_context *pipe = st->pipe;
@@ -233,7 +235,6 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_
st_view_format = firstImageFormat;
}
-
/* if sampler view has changed dereference it */
if (stObj->sampler_view) {
if (check_sampler_swizzle(stObj->sampler_view,
@@ -251,7 +252,8 @@ update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_
return GL_TRUE;
}
-static void
+
+static void
update_vertex_textures(struct st_context *st)
{
const struct gl_context *ctx = st->ctx;
@@ -275,7 +277,8 @@ update_vertex_textures(struct st_context *st)
st->state.num_vertex_textures = su + 1;
}
- pipe_sampler_view_reference(&st->state.sampler_vertex_views[su], sampler_view);
+ pipe_sampler_view_reference(&st->state.sampler_vertex_views[su],
+ sampler_view);
}
if (ctx->Const.MaxVertexTextureImageUnits > 0) {
@@ -287,7 +290,8 @@ update_vertex_textures(struct st_context *st)
}
}
-static void
+
+static void
update_fragment_textures(struct st_context *st)
{
const struct gl_context *ctx = st->ctx;
@@ -319,6 +323,7 @@ update_fragment_textures(struct st_context *st)
st->state.sampler_views);
}
+
const struct st_tracked_state st_update_texture = {
"st_update_texture", /* name */
{ /* dirty */
@@ -328,8 +333,9 @@ const struct st_tracked_state st_update_texture = {
update_fragment_textures /* update */
};
+
const struct st_tracked_state st_update_vertex_texture = {
- "st_update_vertex_texture", /* name */
+ "st_update_vertex_texture", /* name */
{ /* dirty */
_NEW_TEXTURE, /* mesa */
ST_NEW_VERTEX_PROGRAM, /* st */
@@ -337,7 +343,9 @@ const struct st_tracked_state st_update_vertex_texture = {
update_vertex_textures /* update */
};
-static void
+
+
+static void
finalize_textures(struct st_context *st)
{
struct gl_context *ctx = st->ctx;
@@ -371,7 +379,6 @@ finalize_textures(struct st_context *st)
}
-
const struct st_tracked_state st_finalize_textures = {
"st_finalize_textures", /* name */
{ /* dirty */
diff --git a/mesalib/src/mesa/state_tracker/st_draw.c b/mesalib/src/mesa/state_tracker/st_draw.c
index 6d6fc858d..c0554cfc7 100644
--- a/mesalib/src/mesa/state_tracker/st_draw.c
+++ b/mesalib/src/mesa/state_tracker/st_draw.c
@@ -990,7 +990,8 @@ st_draw_vbo(struct gl_context *ctx,
/* Gallium probably doesn't want this in some cases. */
if (!index_bounds_valid)
if (!all_varyings_in_vbos(arrays))
- vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+ vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index,
+ nr_prims);
for (i = 0; i < nr_prims; i++) {
num_instances = MAX2(num_instances, prims[i].num_instances);
diff --git a/mesalib/src/mesa/state_tracker/st_draw_feedback.c b/mesalib/src/mesa/state_tracker/st_draw_feedback.c
index fbf0349b4..a559b733a 100644
--- a/mesalib/src/mesa/state_tracker/st_draw_feedback.c
+++ b/mesalib/src/mesa/state_tracker/st_draw_feedback.c
@@ -119,7 +119,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
st_validate_state(st);
if (!index_bounds_valid)
- vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+ vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, nr_prims);
/* must get these after state validation! */
vp = st->vp;
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index a9d405436..49c874710 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -263,12 +263,6 @@ void st_init_extensions(struct st_context *st)
ctx->Const.GLSLVersion = 120;
_mesa_override_glsl_version(st->ctx);
- /* Extensions that only depend on the GLSL version:
- */
- if (ctx->Const.GLSLVersion >= 130) {
- ctx->Extensions.ARB_conservative_depth = GL_TRUE;
- }
-
/*
* Extensions that are supported by all Gallium drivers:
*/
@@ -587,6 +581,23 @@ void st_init_extensions(struct st_context *st)
#endif
}
+ if (screen->get_shader_param(screen, PIPE_SHADER_VERTEX,
+ PIPE_SHADER_CAP_INTEGERS) &&
+ screen->get_shader_param(screen, PIPE_SHADER_FRAGMENT,
+ PIPE_SHADER_CAP_INTEGERS)) {
+ ctx->Const.NativeIntegers = GL_TRUE;
+ }
+
+ if (ctx->Const.NativeIntegers)
+ ctx->Const.GLSLVersion = 130;
+
+ /* Extensions that only depend on the GLSL version:
+ */
+ if (ctx->Const.GLSLVersion >= 130) {
+ ctx->Extensions.ARB_conservative_depth = GL_TRUE;
+ ctx->Const.MaxClipPlanes = 8;
+ }
+
ctx->Extensions.NV_primitive_restart = GL_TRUE;
if (!screen->get_param(screen, PIPE_CAP_PRIMITIVE_RESTART)) {
st->sw_primitive_restart = GL_TRUE;
@@ -703,4 +714,12 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.ARB_transform_feedback2 = GL_TRUE;
}
}
+
+ if (ctx->Const.NativeIntegers &&
+ screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_UINT, PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_R32G32B32A32_SINT, PIPE_TEXTURE_2D, 0,
+ PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET))
+ ctx->Extensions.EXT_texture_integer = GL_TRUE;
+
}
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 3b8e2fe37..26047cfe0 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -664,6 +664,9 @@ glsl_to_tgsi_visitor::get_opcode(ir_instruction *ir, unsigned op,
case3(SLT, ISLT, USLT);
case2iu(ISHR, USHR);
+
+ case2fi(SSG, ISSG);
+ case3(ABS, IABS, IABS);
default: break;
}
@@ -1410,10 +1413,7 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
}
break;
case ir_unop_abs:
- if (result_dst.type == GLSL_TYPE_INT || result_dst.type == GLSL_TYPE_UINT)
- emit(ir, TGSI_OPCODE_IABS, result_dst, op[0]);
- else
- emit(ir, TGSI_OPCODE_ABS, result_dst, op[0]);
+ emit(ir, TGSI_OPCODE_ABS, result_dst, op[0]);
break;
case ir_unop_sign:
emit(ir, TGSI_OPCODE_SSG, result_dst, op[0]);
@@ -2646,8 +2646,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
ir->shadow_comparitor->accept(this);
/* XXX This will need to be updated for cubemap array samplers. */
- if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D &&
- sampler_type->sampler_array) {
+ if ((sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D &&
+ sampler_type->sampler_array) ||
+ sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE) {
coord_dst.writemask = WRITEMASK_W;
} else {
coord_dst.writemask = WRITEMASK_Z;
@@ -2842,8 +2843,6 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program *prog)
if (is_tex_instruction(inst->op)) {
v->samplers_used |= 1 << inst->sampler;
- prog->SamplerTargets[inst->sampler] =
- (gl_texture_index)inst->tex_target;
if (inst->tex_shadow) {
prog->ShadowSamplers |= 1 << inst->sampler;
}
@@ -2851,7 +2850,9 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program *prog)
}
prog->SamplersUsed = v->samplers_used;
- _mesa_update_shader_textures_used(prog);
+
+ if (v->shader_program != NULL)
+ _mesa_update_shader_textures_used(v->shader_program, prog);
}
static void
@@ -4181,7 +4182,7 @@ compile_tgsi_instruction(struct st_translate *t,
ureg_tex_insn(ureg,
inst->op,
dst, num_dst,
- translate_texture_target(inst->tex_target, inst->tex_shadow),
+ st_translate_texture_target(inst->tex_target, inst->tex_shadow),
texoffsets, inst->tex_offset_num_offset,
src, num_src);
return;
@@ -5010,13 +5011,18 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
num_clip_distances[i] = get_clip_distance_size(ir);
do {
+ unsigned what_to_lower = MOD_TO_FRACT | DIV_TO_MUL_RCP |
+ EXP_TO_EXP2 | LOG_TO_LOG2;
+ if (options->EmitNoPow)
+ what_to_lower |= POW_TO_EXP2;
+ if (!ctx->Const.NativeIntegers)
+ what_to_lower |= INT_DIV_TO_MUL_RCP;
+
progress = false;
/* Lowering */
do_mat_op_to_vec(ir);
- lower_instructions(ir, (MOD_TO_FRACT | DIV_TO_MUL_RCP | EXP_TO_EXP2
- | LOG_TO_LOG2 | INT_DIV_TO_MUL_RCP
- | ((options->EmitNoPow) ? POW_TO_EXP2 : 0)));
+ lower_instructions(ir, what_to_lower);
progress = do_lower_jumps(ir, true, true, options->EmitNoMainReturn, options->EmitNoCont, options->EmitNoLoops) || progress;
@@ -5087,7 +5093,7 @@ st_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
}
void
-st_translate_stream_output_info(struct glsl_to_tgsi_visitor *glsl_to_tgsi,
+st_translate_stream_output_info(glsl_to_tgsi_visitor *glsl_to_tgsi,
const GLuint outputMapping[],
struct pipe_stream_output_info *so)
{
diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c
index b83cb2339..63920a39e 100644
--- a/mesalib/src/mesa/state_tracker/st_manager.c
+++ b/mesalib/src/mesa/state_tracker/st_manager.c
@@ -26,16 +26,6 @@
* Chia-I Wu <olv@lunarg.com>
*/
-#include "state_tracker/st_gl_api.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
-#include "util/u_format.h"
-#include "util/u_pointer.h"
-#include "util/u_inlines.h"
-#include "util/u_atomic.h"
-#include "util/u_surface.h"
-
#include "main/mtypes.h"
#include "main/context.h"
#include "main/mfeatures.h"
@@ -54,6 +44,16 @@
#include "st_cb_flush.h"
#include "st_manager.h"
+#include "state_tracker/st_gl_api.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
+#include "util/u_format.h"
+#include "util/u_pointer.h"
+#include "util/u_inlines.h"
+#include "util/u_atomic.h"
+#include "util/u_surface.h"
+
/**
* Cast wrapper to convert a struct gl_framebuffer to an st_framebuffer.
* Return NULL if the struct gl_framebuffer is a user-created framebuffer.
diff --git a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
index ac615343a..0764234bd 100644
--- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -269,7 +269,7 @@ src_register( struct st_translate *t,
* Map mesa texture target to TGSI texture target.
*/
unsigned
-translate_texture_target( GLuint textarget,
+st_translate_texture_target( GLuint textarget,
GLboolean shadow )
{
if (shadow) {
@@ -279,6 +279,7 @@ translate_texture_target( GLuint textarget,
case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_SHADOWRECT;
case TEXTURE_1D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW1D_ARRAY;
case TEXTURE_2D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW2D_ARRAY;
+ case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_SHADOWCUBE;
default: break;
}
}
@@ -515,7 +516,7 @@ static void emit_ddy( struct st_translate *t,
-unsigned
+static unsigned
translate_opcode( unsigned op )
{
switch( op ) {
@@ -707,7 +708,7 @@ compile_instruction(
ureg_tex_insn( ureg,
translate_opcode( inst->Opcode ),
dst, num_dst,
- translate_texture_target( inst->TexSrcTarget,
+ st_translate_texture_target( inst->TexSrcTarget,
inst->TexShadow ),
NULL, 0,
src, num_src );
diff --git a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.h b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.h
index 0dbdf5f61..7563c8050 100644
--- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.h
+++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.h
@@ -65,10 +65,7 @@ void
st_free_tokens(const struct tgsi_token *tokens);
unsigned
-translate_opcode(unsigned op);
-
-unsigned
-translate_texture_target(GLuint textarget, GLboolean shadow);
+st_translate_texture_target(GLuint textarget, GLboolean shadow);
#if defined __cplusplus
diff --git a/mesalib/src/mesa/swrast/s_aalinetemp.h b/mesalib/src/mesa/swrast/s_aalinetemp.h
index 7c535669b..376ef32d0 100644
--- a/mesalib/src/mesa/swrast/s_aalinetemp.h
+++ b/mesalib/src/mesa/swrast/s_aalinetemp.h
@@ -1,242 +1,242 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
- *
- * 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
- * BRIAN PAUL 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.
- */
-
-
-/*
- * Antialiased line template.
- */
-
-
-/*
- * Function to render each fragment in the AA line.
- * \param ix - integer fragment window X coordiante
- * \param iy - integer fragment window Y coordiante
- */
-static void
-NAME(plot)(struct gl_context *ctx, struct LineInfo *line, int ix, int iy)
-{
- const SWcontext *swrast = SWRAST_CONTEXT(ctx);
- const GLfloat fx = (GLfloat) ix;
- const GLfloat fy = (GLfloat) iy;
- const GLfloat coverage = compute_coveragef(line, ix, iy);
- const GLuint i = line->span.end;
-
- (void) swrast;
-
- if (coverage == 0.0)
- return;
-
- line->span.end++;
- line->span.array->coverage[i] = coverage;
- line->span.array->x[i] = ix;
- line->span.array->y[i] = iy;
-
- /*
- * Compute Z, color, texture coords, fog for the fragment by
- * solving the plane equations at (ix,iy).
- */
-#ifdef DO_Z
- line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane);
-#endif
- line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane);
- line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane);
- line->span.array->rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane);
- line->span.array->rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane);
-#if defined(DO_ATTRIBS)
- ATTRIB_LOOP_BEGIN
- GLfloat (*attribArray)[4] = line->span.array->attribs[attr];
- if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0
- && !ctx->FragmentProgram._Current) {
- /* texcoord w/ divide by Q */
- const GLuint unit = attr - FRAG_ATTRIB_TEX0;
- const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]);
- GLuint c;
- for (c = 0; c < 3; c++) {
- attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invQ;
- }
- line->span.array->lambda[unit][i]
- = compute_lambda(line->attrPlane[attr][0],
- line->attrPlane[attr][1], invQ,
- line->texWidth[attr], line->texHeight[attr]);
- }
- else {
- /* non-texture attrib */
- const GLfloat invW = solve_plane_recip(fx, fy, line->wPlane);
- GLuint c;
- for (c = 0; c < 4; c++) {
- attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invW;
- }
- }
- ATTRIB_LOOP_END
-#endif
-
- if (line->span.end == MAX_WIDTH) {
- _swrast_write_rgba_span(ctx, &(line->span));
- line->span.end = 0; /* reset counter */
- }
-}
-
-
-
-/*
- * Line setup
- */
-static void
-NAME(line)(struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1)
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
- GLfloat tStart, tEnd; /* segment start, end along line length */
- GLboolean inSegment;
- GLint iLen, i;
-
- /* Init the LineInfo struct */
- struct LineInfo line;
- line.x0 = v0->attrib[FRAG_ATTRIB_WPOS][0];
- line.y0 = v0->attrib[FRAG_ATTRIB_WPOS][1];
- line.x1 = v1->attrib[FRAG_ATTRIB_WPOS][0];
- line.y1 = v1->attrib[FRAG_ATTRIB_WPOS][1];
- line.dx = line.x1 - line.x0;
- line.dy = line.y1 - line.y0;
- line.len = SQRTF(line.dx * line.dx + line.dy * line.dy);
- line.halfWidth = 0.5F * CLAMP(ctx->Line.Width,
- ctx->Const.MinLineWidthAA,
- ctx->Const.MaxLineWidthAA);
-
- if (line.len == 0.0 || IS_INF_OR_NAN(line.len))
- return;
-
- INIT_SPAN(line.span, GL_LINE);
- line.span.arrayMask = SPAN_XY | SPAN_COVERAGE;
- line.span.facing = swrast->PointLineFacing;
- line.xAdj = line.dx / line.len * line.halfWidth;
- line.yAdj = line.dy / line.len * line.halfWidth;
-
-#ifdef DO_Z
- line.span.arrayMask |= SPAN_Z;
- compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->attrib[FRAG_ATTRIB_WPOS][2], v1->attrib[FRAG_ATTRIB_WPOS][2], line.zPlane);
-#endif
- line.span.arrayMask |= SPAN_RGBA;
- if (ctx->Light.ShadeModel == GL_SMOOTH) {
- compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->color[RCOMP], v1->color[RCOMP], line.rPlane);
- compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->color[GCOMP], v1->color[GCOMP], line.gPlane);
- compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->color[BCOMP], v1->color[BCOMP], line.bPlane);
- compute_plane(line.x0, line.y0, line.x1, line.y1,
- v0->color[ACOMP], v1->color[ACOMP], line.aPlane);
- }
- else {
- constant_plane(v1->color[RCOMP], line.rPlane);
- constant_plane(v1->color[GCOMP], line.gPlane);
- constant_plane(v1->color[BCOMP], line.bPlane);
- constant_plane(v1->color[ACOMP], line.aPlane);
- }
-#if defined(DO_ATTRIBS)
- {
- const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3];
- const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3];
- line.span.arrayMask |= SPAN_LAMBDA;
- compute_plane(line.x0, line.y0, line.x1, line.y1, invW0, invW1, line.wPlane);
- ATTRIB_LOOP_BEGIN
- GLuint c;
- if (swrast->_InterpMode[attr] == GL_FLAT) {
- for (c = 0; c < 4; c++) {
- constant_plane(v1->attrib[attr][c], line.attrPlane[attr][c]);
- }
- }
- else {
- for (c = 0; c < 4; c++) {
- const GLfloat a0 = v0->attrib[attr][c] * invW0;
- const GLfloat a1 = v1->attrib[attr][c] * invW1;
- compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1,
- line.attrPlane[attr][c]);
- }
- }
- line.span.arrayAttribs |= (1 << attr);
- if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
- const GLuint u = attr - FRAG_ATTRIB_TEX0;
- const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
- const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel];
- line.texWidth[attr] = (GLfloat) texImage->Width;
- line.texHeight[attr] = (GLfloat) texImage->Height;
- }
- ATTRIB_LOOP_END
- }
-#endif
-
- tStart = tEnd = 0.0;
- inSegment = GL_FALSE;
- iLen = (GLint) line.len;
-
- if (ctx->Line.StippleFlag) {
- for (i = 0; i < iLen; i++) {
- const GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf;
- if ((1 << bit) & ctx->Line.StipplePattern) {
- /* stipple bit is on */
- const GLfloat t = (GLfloat) i / (GLfloat) line.len;
- if (!inSegment) {
- /* start new segment */
- inSegment = GL_TRUE;
- tStart = t;
- }
- else {
- /* still in the segment, extend it */
- tEnd = t;
- }
- }
- else {
- /* stipple bit is off */
- if (inSegment && (tEnd > tStart)) {
- /* draw the segment */
- segment(ctx, &line, NAME(plot), tStart, tEnd);
- inSegment = GL_FALSE;
- }
- else {
- /* still between segments, do nothing */
- }
- }
- swrast->StippleCounter++;
- }
-
- if (inSegment) {
- /* draw the final segment of the line */
- segment(ctx, &line, NAME(plot), tStart, 1.0F);
- }
- }
- else {
- /* non-stippled */
- segment(ctx, &line, NAME(plot), 0.0, 1.0);
- }
-
- _swrast_write_rgba_span(ctx, &(line.span));
-}
-
-
-
-
-#undef DO_Z
-#undef DO_ATTRIBS
-#undef NAME
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.1
+ *
+ * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ *
+ * 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
+ * BRIAN PAUL 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.
+ */
+
+
+/*
+ * Antialiased line template.
+ */
+
+
+/*
+ * Function to render each fragment in the AA line.
+ * \param ix - integer fragment window X coordiante
+ * \param iy - integer fragment window Y coordiante
+ */
+static void
+NAME(plot)(struct gl_context *ctx, struct LineInfo *line, int ix, int iy)
+{
+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ const GLfloat fx = (GLfloat) ix;
+ const GLfloat fy = (GLfloat) iy;
+ const GLfloat coverage = compute_coveragef(line, ix, iy);
+ const GLuint i = line->span.end;
+
+ (void) swrast;
+
+ if (coverage == 0.0)
+ return;
+
+ line->span.end++;
+ line->span.array->coverage[i] = coverage;
+ line->span.array->x[i] = ix;
+ line->span.array->y[i] = iy;
+
+ /*
+ * Compute Z, color, texture coords, fog for the fragment by
+ * solving the plane equations at (ix,iy).
+ */
+#ifdef DO_Z
+ line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane);
+#endif
+ line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane);
+ line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane);
+ line->span.array->rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane);
+ line->span.array->rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane);
+#if defined(DO_ATTRIBS)
+ ATTRIB_LOOP_BEGIN
+ GLfloat (*attribArray)[4] = line->span.array->attribs[attr];
+ if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0
+ && !ctx->FragmentProgram._Current) {
+ /* texcoord w/ divide by Q */
+ const GLuint unit = attr - FRAG_ATTRIB_TEX0;
+ const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]);
+ GLuint c;
+ for (c = 0; c < 3; c++) {
+ attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invQ;
+ }
+ line->span.array->lambda[unit][i]
+ = compute_lambda(line->attrPlane[attr][0],
+ line->attrPlane[attr][1], invQ,
+ line->texWidth[attr], line->texHeight[attr]);
+ }
+ else {
+ /* non-texture attrib */
+ const GLfloat invW = solve_plane_recip(fx, fy, line->wPlane);
+ GLuint c;
+ for (c = 0; c < 4; c++) {
+ attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invW;
+ }
+ }
+ ATTRIB_LOOP_END
+#endif
+
+ if (line->span.end == MAX_WIDTH) {
+ _swrast_write_rgba_span(ctx, &(line->span));
+ line->span.end = 0; /* reset counter */
+ }
+}
+
+
+
+/*
+ * Line setup
+ */
+static void
+NAME(line)(struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLfloat tStart, tEnd; /* segment start, end along line length */
+ GLboolean inSegment;
+ GLint iLen, i;
+
+ /* Init the LineInfo struct */
+ struct LineInfo line;
+ line.x0 = v0->attrib[FRAG_ATTRIB_WPOS][0];
+ line.y0 = v0->attrib[FRAG_ATTRIB_WPOS][1];
+ line.x1 = v1->attrib[FRAG_ATTRIB_WPOS][0];
+ line.y1 = v1->attrib[FRAG_ATTRIB_WPOS][1];
+ line.dx = line.x1 - line.x0;
+ line.dy = line.y1 - line.y0;
+ line.len = SQRTF(line.dx * line.dx + line.dy * line.dy);
+ line.halfWidth = 0.5F * CLAMP(ctx->Line.Width,
+ ctx->Const.MinLineWidthAA,
+ ctx->Const.MaxLineWidthAA);
+
+ if (line.len == 0.0 || IS_INF_OR_NAN(line.len))
+ return;
+
+ INIT_SPAN(line.span, GL_LINE);
+ line.span.arrayMask = SPAN_XY | SPAN_COVERAGE;
+ line.span.facing = swrast->PointLineFacing;
+ line.xAdj = line.dx / line.len * line.halfWidth;
+ line.yAdj = line.dy / line.len * line.halfWidth;
+
+#ifdef DO_Z
+ line.span.arrayMask |= SPAN_Z;
+ compute_plane(line.x0, line.y0, line.x1, line.y1,
+ v0->attrib[FRAG_ATTRIB_WPOS][2], v1->attrib[FRAG_ATTRIB_WPOS][2], line.zPlane);
+#endif
+ line.span.arrayMask |= SPAN_RGBA;
+ if (ctx->Light.ShadeModel == GL_SMOOTH) {
+ compute_plane(line.x0, line.y0, line.x1, line.y1,
+ v0->color[RCOMP], v1->color[RCOMP], line.rPlane);
+ compute_plane(line.x0, line.y0, line.x1, line.y1,
+ v0->color[GCOMP], v1->color[GCOMP], line.gPlane);
+ compute_plane(line.x0, line.y0, line.x1, line.y1,
+ v0->color[BCOMP], v1->color[BCOMP], line.bPlane);
+ compute_plane(line.x0, line.y0, line.x1, line.y1,
+ v0->color[ACOMP], v1->color[ACOMP], line.aPlane);
+ }
+ else {
+ constant_plane(v1->color[RCOMP], line.rPlane);
+ constant_plane(v1->color[GCOMP], line.gPlane);
+ constant_plane(v1->color[BCOMP], line.bPlane);
+ constant_plane(v1->color[ACOMP], line.aPlane);
+ }
+#if defined(DO_ATTRIBS)
+ {
+ const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3];
+ const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3];
+ line.span.arrayMask |= SPAN_LAMBDA;
+ compute_plane(line.x0, line.y0, line.x1, line.y1, invW0, invW1, line.wPlane);
+ ATTRIB_LOOP_BEGIN
+ GLuint c;
+ if (swrast->_InterpMode[attr] == GL_FLAT) {
+ for (c = 0; c < 4; c++) {
+ constant_plane(v1->attrib[attr][c], line.attrPlane[attr][c]);
+ }
+ }
+ else {
+ for (c = 0; c < 4; c++) {
+ const GLfloat a0 = v0->attrib[attr][c] * invW0;
+ const GLfloat a1 = v1->attrib[attr][c] * invW1;
+ compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1,
+ line.attrPlane[attr][c]);
+ }
+ }
+ line.span.arrayAttribs |= BITFIELD64_BIT(attr);
+ if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
+ const GLuint u = attr - FRAG_ATTRIB_TEX0;
+ const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
+ const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel];
+ line.texWidth[attr] = (GLfloat) texImage->Width;
+ line.texHeight[attr] = (GLfloat) texImage->Height;
+ }
+ ATTRIB_LOOP_END
+ }
+#endif
+
+ tStart = tEnd = 0.0;
+ inSegment = GL_FALSE;
+ iLen = (GLint) line.len;
+
+ if (ctx->Line.StippleFlag) {
+ for (i = 0; i < iLen; i++) {
+ const GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf;
+ if ((1 << bit) & ctx->Line.StipplePattern) {
+ /* stipple bit is on */
+ const GLfloat t = (GLfloat) i / (GLfloat) line.len;
+ if (!inSegment) {
+ /* start new segment */
+ inSegment = GL_TRUE;
+ tStart = t;
+ }
+ else {
+ /* still in the segment, extend it */
+ tEnd = t;
+ }
+ }
+ else {
+ /* stipple bit is off */
+ if (inSegment && (tEnd > tStart)) {
+ /* draw the segment */
+ segment(ctx, &line, NAME(plot), tStart, tEnd);
+ inSegment = GL_FALSE;
+ }
+ else {
+ /* still between segments, do nothing */
+ }
+ }
+ swrast->StippleCounter++;
+ }
+
+ if (inSegment) {
+ /* draw the final segment of the line */
+ segment(ctx, &line, NAME(plot), tStart, 1.0F);
+ }
+ }
+ else {
+ /* non-stippled */
+ segment(ctx, &line, NAME(plot), 0.0, 1.0);
+ }
+
+ _swrast_write_rgba_span(ctx, &(line.span));
+}
+
+
+
+
+#undef DO_Z
+#undef DO_ATTRIBS
+#undef NAME
diff --git a/mesalib/src/mesa/swrast/s_context.c b/mesalib/src/mesa/swrast/s_context.c
index 94b7fe34d..06824ea2c 100644
--- a/mesalib/src/mesa/swrast/s_context.c
+++ b/mesalib/src/mesa/swrast/s_context.c
@@ -531,7 +531,7 @@ _swrast_update_active_attribs(struct gl_context *ctx)
{
GLuint i, num = 0;
for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
- if (attribsMask & (1 << i)) {
+ if (attribsMask & BITFIELD64_BIT(i)) {
swrast->_ActiveAttribs[num++] = i;
/* how should this attribute be interpolated? */
if (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1)
diff --git a/mesalib/src/mesa/swrast/s_span.c b/mesalib/src/mesa/swrast/s_span.c
index 689fe34ae..e89930353 100644
--- a/mesalib/src/mesa/swrast/s_span.c
+++ b/mesalib/src/mesa/swrast/s_span.c
@@ -175,7 +175,7 @@ interpolate_active_attribs(struct gl_context *ctx, SWspan *span,
attrMask &= ~span->arrayAttribs;
ATTRIB_LOOP_BEGIN
- if (attrMask & (1 << attr)) {
+ if (attrMask & BITFIELD64_BIT(attr)) {
const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3];
const GLfloat dv0dx = span->attrStepX[attr][0];
@@ -199,8 +199,8 @@ interpolate_active_attribs(struct gl_context *ctx, SWspan *span,
v3 += dv3dx;
w += dwdx;
}
- ASSERT((span->arrayAttribs & (1 << attr)) == 0);
- span->arrayAttribs |= (1 << attr);
+ ASSERT((span->arrayAttribs & BITFIELD64_BIT(attr)) == 0);
+ span->arrayAttribs |= BITFIELD64_BIT(attr);
}
ATTRIB_LOOP_END
}
diff --git a/mesalib/src/mesa/swrast/s_texture.c b/mesalib/src/mesa/swrast/s_texture.c
index ffd78a2b8..337a52f32 100644
--- a/mesalib/src/mesa/swrast/s_texture.c
+++ b/mesalib/src/mesa/swrast/s_texture.c
@@ -285,7 +285,7 @@ _swrast_map_textures(struct gl_context *ctx)
/* loop over enabled texture units */
while (enabledUnits) {
- GLuint unit = _mesa_ffs(enabledUnits) - 1;
+ GLuint unit = ffs(enabledUnits) - 1;
struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
_swrast_map_texture(ctx, texObj);
@@ -305,7 +305,7 @@ _swrast_unmap_textures(struct gl_context *ctx)
/* loop over enabled texture units */
while (enabledUnits) {
- GLuint unit = _mesa_ffs(enabledUnits) - 1;
+ GLuint unit = ffs(enabledUnits) - 1;
struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
_swrast_unmap_texture(ctx, texObj);
diff --git a/mesalib/src/mesa/tnl/t_draw.c b/mesalib/src/mesa/tnl/t_draw.c
index f949c34d3..17042cf8f 100644
--- a/mesalib/src/mesa/tnl/t_draw.c
+++ b/mesalib/src/mesa/tnl/t_draw.c
@@ -418,7 +418,7 @@ void _tnl_vbo_draw_prims(struct gl_context *ctx,
struct gl_transform_feedback_object *tfb_vertcount)
{
if (!index_bounds_valid)
- vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+ vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims);
_tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
}
diff --git a/mesalib/src/mesa/vbo/vbo.h b/mesalib/src/mesa/vbo/vbo.h
index ed8fc1722..bf925ab16 100644
--- a/mesalib/src/mesa/vbo/vbo.h
+++ b/mesalib/src/mesa/vbo/vbo.h
@@ -127,9 +127,9 @@ int
vbo_sizeof_ib_type(GLenum type);
void
-vbo_get_minmax_index(struct gl_context *ctx, const struct _mesa_prim *prim,
- const struct _mesa_index_buffer *ib,
- GLuint *min_index, GLuint *max_index);
+vbo_get_minmax_indices(struct gl_context *ctx, const struct _mesa_prim *prim,
+ const struct _mesa_index_buffer *ib,
+ GLuint *min_index, GLuint *max_index, GLuint nr_prims);
void vbo_use_buffer_objects(struct gl_context *ctx);
diff --git a/mesalib/src/mesa/vbo/vbo_exec_array.c b/mesalib/src/mesa/vbo/vbo_exec_array.c
index fec49d35e..9861b21c9 100644
--- a/mesalib/src/mesa/vbo/vbo_exec_array.c
+++ b/mesalib/src/mesa/vbo/vbo_exec_array.c
@@ -99,24 +99,24 @@ vbo_sizeof_ib_type(GLenum type)
* If primitive restart is enabled, we need to ignore restart
* indexes when computing min/max.
*/
-void
+static void
vbo_get_minmax_index(struct gl_context *ctx,
const struct _mesa_prim *prim,
const struct _mesa_index_buffer *ib,
- GLuint *min_index, GLuint *max_index)
+ GLuint *min_index, GLuint *max_index,
+ const GLuint count)
{
const GLboolean restart = ctx->Array.PrimitiveRestart;
const GLuint restartIndex = ctx->Array.RestartIndex;
- const GLuint count = prim->count;
- const void *indices;
+ const int index_size = vbo_sizeof_ib_type(ib->type);
+ const char *indices;
GLuint i;
+ indices = (char *) ib->ptr + prim->start * index_size;
if (_mesa_is_bufferobj(ib->obj)) {
- indices = ctx->Driver.MapBufferRange(ctx, (GLsizeiptr) ib->ptr,
- count * vbo_sizeof_ib_type(ib->type),
- GL_MAP_READ_BIT, ib->obj);
- } else {
- indices = ib->ptr;
+ GLsizeiptr size = MIN2(count * index_size, ib->obj->Size);
+ indices = ctx->Driver.MapBufferRange(ctx, (GLintptr) indices, size,
+ GL_MAP_READ_BIT, ib->obj);
}
switch (ib->type) {
@@ -196,6 +196,41 @@ vbo_get_minmax_index(struct gl_context *ctx,
}
}
+/**
+ * Compute min and max elements for nr_prims
+ */
+void
+vbo_get_minmax_indices(struct gl_context *ctx,
+ const struct _mesa_prim *prims,
+ const struct _mesa_index_buffer *ib,
+ GLuint *min_index,
+ GLuint *max_index,
+ GLuint nr_prims)
+{
+ GLuint tmp_min, tmp_max;
+ GLuint i;
+ GLuint count;
+
+ *min_index = ~0;
+ *max_index = 0;
+
+ for (i = 0; i < nr_prims; i++) {
+ const struct _mesa_prim *start_prim;
+
+ start_prim = &prims[i];
+ count = start_prim->count;
+ /* Do combination if possible to reduce map/unmap count */
+ while ((i + 1 < nr_prims) &&
+ (prims[i].start + prims[i].count == prims[i+1].start)) {
+ count += prims[i+1].count;
+ i++;
+ }
+ vbo_get_minmax_index(ctx, start_prim, ib, &tmp_min, &tmp_max, count);
+ *min_index = MIN2(*min_index, tmp_min);
+ *max_index = MAX2(*max_index, tmp_max);
+ }
+}
+
/**
* Check that element 'j' of the array has reasonable data.