aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src')
-rw-r--r--mesalib/src/gallium/auxiliary/SConscript2
-rw-r--r--mesalib/src/glsl/ast_array_index.cpp6
-rw-r--r--mesalib/src/glsl/glsl_parser.yy80
-rw-r--r--mesalib/src/glsl/opt_algebraic.cpp23
-rw-r--r--mesalib/src/mapi/glapi/gen/ARB_texture_multisample.xml4
-rw-r--r--mesalib/src/mapi/glapi/gen/Makefile.am8
-rw-r--r--mesalib/src/mesa/main/teximage.c47
-rw-r--r--mesalib/src/mesa/main/teximage.h4
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom.c1
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom.h1
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_constbuf.c17
-rw-r--r--mesalib/src/mesa/state_tracker/st_context.c6
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp101
-rw-r--r--mesalib/src/mesa/state_tracker/st_program.c128
-rw-r--r--mesalib/src/mesa/vbo/vbo_save_api.c39
15 files changed, 347 insertions, 120 deletions
diff --git a/mesalib/src/gallium/auxiliary/SConscript b/mesalib/src/gallium/auxiliary/SConscript
index 3ac311225..31dfed316 100644
--- a/mesalib/src/gallium/auxiliary/SConscript
+++ b/mesalib/src/gallium/auxiliary/SConscript
@@ -46,8 +46,6 @@ source = env.ParseSourceList('Makefile.sources', [
])
if env['llvm']:
- env.Append(CXXFLAGS = env['LLVM_CXXFLAGS'])
-
source += env.ParseSourceList('Makefile.sources', [
'GALLIVM_SOURCES',
'GALLIVM_CPP_SOURCES'
diff --git a/mesalib/src/glsl/ast_array_index.cpp b/mesalib/src/glsl/ast_array_index.cpp
index da96cc10e..b457ec899 100644
--- a/mesalib/src/glsl/ast_array_index.cpp
+++ b/mesalib/src/glsl/ast_array_index.cpp
@@ -69,9 +69,9 @@ update_max_array_access(ir_rvalue *ir, unsigned idx, YYLTYPE *loc,
}
if (deref_var != NULL) {
- const glsl_type *interface_type =
- deref_var->var->get_interface_type();
- if (interface_type != NULL) {
+ if (deref_var->var->is_interface_instance()) {
+ const glsl_type *interface_type =
+ deref_var->var->get_interface_type();
unsigned field_index =
deref_record->record->type->field_index(deref_record->field);
assert(field_index < interface_type->length);
diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy
index a1d593fab..00589e28e 100644
--- a/mesalib/src/glsl/glsl_parser.yy
+++ b/mesalib/src/glsl/glsl_parser.yy
@@ -43,6 +43,38 @@ _mesa_glsl_lex(YYSTYPE *val, YYLTYPE *loc, _mesa_glsl_parse_state *state)
{
return _mesa_glsl_lexer_lex(val, loc, state->scanner);
}
+
+static bool match_layout_qualifier(const char *s1, const char *s2,
+ _mesa_glsl_parse_state *state)
+{
+ /* From the GLSL 1.50 spec, section 4.3.8 (Layout Qualifiers):
+ *
+ * "The tokens in any layout-qualifier-id-list ... are not case
+ * sensitive, unless explicitly noted otherwise."
+ *
+ * The text "unless explicitly noted otherwise" appears to be
+ * vacuous--no desktop GLSL spec (up through GLSL 4.40) notes
+ * otherwise.
+ *
+ * However, the GLSL ES 3.00 spec says, in section 4.3.8 (Layout
+ * Qualifiers):
+ *
+ * "As for other identifiers, they are case sensitive."
+ *
+ * So we need to do a case-sensitive or a case-insensitive match,
+ * depending on whether we are compiling for GLSL ES.
+ */
+ if (state->es_shader)
+ return strcmp(s1, s2);
+ else {
+#if defined(_MSC_VER)
+ /* MSVC doesn't have a strcasecmp() function; instead it has _stricmp. */
+ return _stricmp(s1, s2);
+#else
+ return strcasecmp(s1, s2);
+#endif
+ }
+}
%}
%expect 0
@@ -1160,9 +1192,10 @@ layout_qualifier_id:
/* Layout qualifiers for ARB_fragment_coord_conventions. */
if (!$$.flags.i && (state->ARB_fragment_coord_conventions_enable ||
state->is_version(150, 0))) {
- if (strcmp($1, "origin_upper_left") == 0) {
+ if (match_layout_qualifier($1, "origin_upper_left", state) == 0) {
$$.flags.q.origin_upper_left = 1;
- } else if (strcmp($1, "pixel_center_integer") == 0) {
+ } else if (match_layout_qualifier($1, "pixel_center_integer",
+ state) == 0) {
$$.flags.q.pixel_center_integer = 1;
}
@@ -1177,13 +1210,14 @@ layout_qualifier_id:
if (!$$.flags.i &&
(state->AMD_conservative_depth_enable ||
state->ARB_conservative_depth_enable)) {
- if (strcmp($1, "depth_any") == 0) {
+ if (match_layout_qualifier($1, "depth_any", state) == 0) {
$$.flags.q.depth_any = 1;
- } else if (strcmp($1, "depth_greater") == 0) {
+ } else if (match_layout_qualifier($1, "depth_greater", state) == 0) {
$$.flags.q.depth_greater = 1;
- } else if (strcmp($1, "depth_less") == 0) {
+ } else if (match_layout_qualifier($1, "depth_less", state) == 0) {
$$.flags.q.depth_less = 1;
- } else if (strcmp($1, "depth_unchanged") == 0) {
+ } else if (match_layout_qualifier($1, "depth_unchanged",
+ state) == 0) {
$$.flags.q.depth_unchanged = 1;
}
@@ -1201,20 +1235,32 @@ layout_qualifier_id:
/* See also interface_block_layout_qualifier. */
if (!$$.flags.i && state->has_uniform_buffer_objects()) {
- if (strcmp($1, "std140") == 0) {
+ if (match_layout_qualifier($1, "std140", state) == 0) {
$$.flags.q.std140 = 1;
- } else if (strcmp($1, "shared") == 0) {
+ } else if (match_layout_qualifier($1, "shared", state) == 0) {
$$.flags.q.shared = 1;
- } else if (strcmp($1, "column_major") == 0) {
+ } else if (match_layout_qualifier($1, "column_major", state) == 0) {
$$.flags.q.column_major = 1;
/* "row_major" is a reserved word in GLSL 1.30+. Its token is parsed
* below in the interface_block_layout_qualifier rule.
*
* It is not a reserved word in GLSL ES 3.00, so it's handled here as
* an identifier.
+ *
+ * Also, this takes care of alternate capitalizations of
+ * "row_major" (which is necessary because layout qualifiers
+ * are case-insensitive in desktop GLSL).
*/
- } else if (strcmp($1, "row_major") == 0) {
+ } else if (match_layout_qualifier($1, "row_major", state) == 0) {
$$.flags.q.row_major = 1;
+ /* "packed" is a reserved word in GLSL, and its token is
+ * parsed below in the interface_block_layout_qualifier rule.
+ * However, we must take care of alternate capitalizations of
+ * "packed", because layout qualifiers are case-insensitive
+ * in desktop GLSL.
+ */
+ } else if (match_layout_qualifier($1, "packed", state) == 0) {
+ $$.flags.q.packed = 1;
}
if ($$.flags.i && state->ARB_uniform_buffer_object_warn) {
@@ -1239,7 +1285,7 @@ layout_qualifier_id:
{ "triangle_strip", GL_TRIANGLE_STRIP },
};
for (unsigned i = 0; i < Elements(map); i++) {
- if (strcmp($1, map[i].s) == 0) {
+ if (match_layout_qualifier($1, map[i].s, state) == 0) {
$$.flags.q.prim_type = 1;
$$.prim_type = map[i].e;
break;
@@ -1263,7 +1309,7 @@ layout_qualifier_id:
memset(& $$, 0, sizeof($$));
if (state->has_explicit_attrib_location()) {
- if (strcmp("location", $1) == 0) {
+ if (match_layout_qualifier("location", $1, state) == 0) {
$$.flags.q.explicit_location = 1;
if ($3 >= 0) {
@@ -1275,7 +1321,7 @@ layout_qualifier_id:
}
}
- if (strcmp("index", $1) == 0) {
+ if (match_layout_qualifier("index", $1, state) == 0) {
$$.flags.q.explicit_index = 1;
if ($3 >= 0) {
@@ -1289,12 +1335,12 @@ layout_qualifier_id:
}
if (state->ARB_shading_language_420pack_enable &&
- strcmp("binding", $1) == 0) {
+ match_layout_qualifier("binding", $1, state) == 0) {
$$.flags.q.explicit_binding = 1;
$$.binding = $3;
}
- if (strcmp("max_vertices", $1) == 0) {
+ if (match_layout_qualifier("max_vertices", $1, state) == 0) {
$$.flags.q.max_vertices = 1;
if ($3 < 0) {
@@ -1344,6 +1390,10 @@ layout_qualifier_id:
* (due to them being reserved keywords) instead of identifiers like
* most qualifiers. See the any_identifier path of
* layout_qualifier_id for the others.
+ *
+ * Note that since layout qualifiers are case-insensitive in desktop
+ * GLSL, all of these qualifiers need to be handled as identifiers as
+ * well (by the any_identifier path of layout_qualifier_id).
*/
interface_block_layout_qualifier:
ROW_MAJOR
diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp
index d706a6ad1..3e5802e18 100644
--- a/mesalib/src/glsl/opt_algebraic.cpp
+++ b/mesalib/src/glsl/opt_algebraic.cpp
@@ -85,6 +85,12 @@ is_vec_one(ir_constant *ir)
}
static inline bool
+is_vec_negative_one(ir_constant *ir)
+{
+ return (ir == NULL) ? false : ir->is_negative_one();
+}
+
+static inline bool
is_vec_basis(ir_constant *ir)
{
return (ir == NULL) ? false : ir->is_basis();
@@ -287,6 +293,23 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
this->progress = true;
return ir_constant::zero(ir, ir->type);
}
+ if (is_vec_negative_one(op_const[0])) {
+ this->progress = true;
+ temp = new(mem_ctx) ir_expression(ir_unop_neg,
+ ir->operands[1]->type,
+ ir->operands[1],
+ NULL);
+ return swizzle_if_required(ir, temp);
+ }
+ if (is_vec_negative_one(op_const[1])) {
+ this->progress = true;
+ temp = new(mem_ctx) ir_expression(ir_unop_neg,
+ ir->operands[0]->type,
+ ir->operands[0],
+ NULL);
+ return swizzle_if_required(ir, temp);
+ }
+
/* Reassociate multiplication of constants so that we can do
* constant folding.
diff --git a/mesalib/src/mapi/glapi/gen/ARB_texture_multisample.xml b/mesalib/src/mapi/glapi/gen/ARB_texture_multisample.xml
index f0dd4f5f7..1f65a8bcf 100644
--- a/mesalib/src/mapi/glapi/gen/ARB_texture_multisample.xml
+++ b/mesalib/src/mapi/glapi/gen/ARB_texture_multisample.xml
@@ -37,7 +37,7 @@
<function name="TexImage2DMultisample" offset="assign">
<param name="target" type="GLenum"/>
<param name="samples" type="GLsizei"/>
- <param name="internalformat" type="GLint"/>
+ <param name="internalformat" type="GLenum"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="fixedsamplelocations" type="GLboolean"/>
@@ -46,7 +46,7 @@
<function name="TexImage3DMultisample" offset="assign">
<param name="target" type="GLenum"/>
<param name="samples" type="GLsizei"/>
- <param name="internalformat" type="GLint"/>
+ <param name="internalformat" type="GLenum"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
<param name="depth" type="GLsizei"/>
diff --git a/mesalib/src/mapi/glapi/gen/Makefile.am b/mesalib/src/mapi/glapi/gen/Makefile.am
index 6bb2f1ec7..d71d5d2a8 100644
--- a/mesalib/src/mapi/glapi/gen/Makefile.am
+++ b/mesalib/src/mapi/glapi/gen/Makefile.am
@@ -89,11 +89,13 @@ XORG_OUTPUTS = \
API_XML = \
gl_API.xml \
ARB_base_instance.xml \
+ ARB_blend_func_extended.xml \
ARB_color_buffer_float.xml \
ARB_copy_buffer.xml \
ARB_debug_output.xml \
ARB_depth_buffer_float.xml \
ARB_depth_clamp.xml \
+ ARB_draw_buffers.xml \
ARB_draw_buffers_blend.xml \
ARB_draw_elements_base_vertex.xml \
ARB_draw_instanced.xml \
@@ -102,6 +104,8 @@ API_XML = \
ARB_framebuffer_object.xml \
ARB_geometry_shader4.xml \
ARB_instanced_arrays.xml \
+ ARB_internalformat_query.xml \
+ ARB_invalidate_subdata.xml \
ARB_map_buffer_range.xml \
ARB_robustness.xml \
ARB_sampler_objects.xml \
@@ -110,9 +114,13 @@ API_XML = \
ARB_texture_buffer_object.xml \
ARB_texture_buffer_range.xml \
ARB_texture_compression_rgtc.xml \
+ ARB_texture_cube_map_array.xml \
ARB_texture_float.xml \
ARB_texture_gather.xml \
+ ARB_texture_multisample.xml \
+ ARB_texture_rgb10_a2ui.xml \
ARB_texture_rg.xml \
+ ARB_texture_storage_multisample.xml \
ARB_texture_storage.xml \
ARB_vertex_array_object.xml \
AMD_draw_buffers_blend.xml \
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index e6cae0034..793c5d382 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -1112,7 +1112,6 @@ _mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height,
case GL_TEXTURE_CUBE_MAP_ARRAY:
case GL_PROXY_TEXTURE_CUBE_MAP:
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
- ASSERT(width == height);
size = width;
break;
case GL_TEXTURE_2D:
@@ -1447,6 +1446,8 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
maxSize >>= level;
+ if (width != height)
+ return GL_FALSE;
if (width < 2 * border || width > 2 * border + maxSize)
return GL_FALSE;
if (height < 2 * border || height > 2 * border + maxSize)
@@ -1500,7 +1501,9 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
return GL_FALSE;
if (height < 2 * border || height > 2 * border + maxSize)
return GL_FALSE;
- if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers)
+ if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers || depth % 6)
+ return GL_FALSE;
+ if (width != height)
return GL_FALSE;
if (level >= ctx->Const.MaxCubeTextureLevels)
return GL_FALSE;
@@ -1991,27 +1994,6 @@ texture_error_check( struct gl_context *ctx,
}
}
- if ((target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
- _mesa_is_cube_face(target)) && width != height) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage2D(cube width != height)");
- return GL_TRUE;
- }
-
- if ((target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY ||
- target == GL_TEXTURE_CUBE_MAP_ARRAY) && width != height) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage3D(cube array width != height)");
- return GL_TRUE;
- }
-
- if ((target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY ||
- target == GL_TEXTURE_CUBE_MAP_ARRAY) && (depth % 6)) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage3D(cube array depth not multiple of 6)");
- return GL_TRUE;
- }
-
/* Check internalFormat */
if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
@@ -2243,14 +2225,6 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
goto error;
}
- /* For cube map, width must equal height */
- if ((target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
- _mesa_is_cube_face(target)) && width != height) {
- reason = "width != height";
- error = GL_INVALID_VALUE;
- goto error;
- }
-
/* check image size in bytes */
if (expectedSize != imageSize) {
/* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...]
@@ -2596,13 +2570,6 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
}
}
- if ((target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
- _mesa_is_cube_face(target)) && width != height) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glTexImage2D(cube width != height)");
- return GL_TRUE;
- }
-
if (_mesa_is_compressed_format(ctx, internalFormat)) {
if (!target_can_be_compressed(ctx, target, internalFormat)) {
_mesa_error(ctx, GL_INVALID_ENUM,
@@ -4388,7 +4355,7 @@ teximagemultisample(GLuint dims, GLenum target, GLsizei samples,
void GLAPIENTRY
_mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
- GLint internalformat, GLsizei width,
+ GLenum internalformat, GLsizei width,
GLsizei height, GLboolean fixedsamplelocations)
{
teximagemultisample(2, target, samples, internalformat,
@@ -4399,7 +4366,7 @@ _mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
void GLAPIENTRY
_mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
- GLint internalformat, GLsizei width,
+ GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth,
GLboolean fixedsamplelocations)
{
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 889524718..792383d2f 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -296,12 +296,12 @@ _mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
extern void GLAPIENTRY
_mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
- GLint internalformat, GLsizei width,
+ GLenum internalformat, GLsizei width,
GLsizei height, GLboolean fixedsamplelocations);
extern void GLAPIENTRY
_mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
- GLint internalformat, GLsizei width,
+ GLenum internalformat, GLsizei width,
GLsizei height, GLsizei depth,
GLboolean fixedsamplelocations);
diff --git a/mesalib/src/mesa/state_tracker/st_atom.c b/mesalib/src/mesa/state_tracker/st_atom.c
index 1abaf8f3e..682073ed6 100644
--- a/mesalib/src/mesa/state_tracker/st_atom.c
+++ b/mesalib/src/mesa/state_tracker/st_atom.c
@@ -66,6 +66,7 @@ static const struct st_tracked_state *atoms[] =
&st_update_fs_constants,
&st_bind_vs_ubos,
&st_bind_fs_ubos,
+ &st_bind_gs_ubos,
&st_update_pixel_transfer,
/* this must be done after the vertex program update */
diff --git a/mesalib/src/mesa/state_tracker/st_atom.h b/mesalib/src/mesa/state_tracker/st_atom.h
index 101a3a6bd..ef24face9 100644
--- a/mesalib/src/mesa/state_tracker/st_atom.h
+++ b/mesalib/src/mesa/state_tracker/st_atom.h
@@ -69,6 +69,7 @@ extern const struct st_tracked_state st_update_gs_constants;
extern const struct st_tracked_state st_update_vs_constants;
extern const struct st_tracked_state st_bind_fs_ubos;
extern const struct st_tracked_state st_bind_vs_ubos;
+extern const struct st_tracked_state st_bind_gs_ubos;
extern const struct st_tracked_state st_update_pixel_transfer;
diff --git a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
index 723ab561c..f3c457625 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_constbuf.c
@@ -254,4 +254,21 @@ const struct st_tracked_state st_bind_fs_ubos = {
bind_fs_ubos
};
+static void bind_gs_ubos(struct st_context *st)
+{
+ struct gl_shader_program *prog = st->ctx->Shader.CurrentGeometryProgram;
+
+ if (!prog)
+ return;
+
+ st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_GEOMETRY], PIPE_SHADER_GEOMETRY);
+}
+const struct st_tracked_state st_bind_gs_ubos = {
+ "st_bind_gs_ubos",
+ {
+ 0,
+ ST_NEW_GEOMETRY_PROGRAM | ST_NEW_UNIFORM_BUFFER,
+ },
+ bind_gs_ubos
+};
diff --git a/mesalib/src/mesa/state_tracker/st_context.c b/mesalib/src/mesa/state_tracker/st_context.c
index 80393cff7..4e0d98cc3 100644
--- a/mesalib/src/mesa/state_tracker/st_context.c
+++ b/mesalib/src/mesa/state_tracker/st_context.c
@@ -125,6 +125,9 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
st->dirty.mesa = ~0;
st->dirty.st = ~0;
+ /* Create upload manager for vertex data for glBitmap, glDrawPixels,
+ * glClear, etc.
+ */
st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) {
@@ -148,7 +151,8 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
st_init_draw( st );
st_init_generate_mipmap(st);
- if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES))
+ /* Choose texture target for glDrawPixels, glBitmap, renderbuffers */
+ if (pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES))
st->internal_target = PIPE_TEXTURE_2D;
else
st->internal_target = PIPE_TEXTURE_RECT;
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 8d06ac6f7..3e11cce24 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -114,6 +114,8 @@ public:
this->index2D = 0;
this->type = type ? type->base_type : GLSL_TYPE_ERROR;
this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
}
st_src_reg(gl_register_file file, int index, int type)
@@ -125,6 +127,8 @@ public:
this->swizzle = SWIZZLE_XYZW;
this->negate = 0;
this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
}
st_src_reg(gl_register_file file, int index, int type, int index2D)
@@ -136,6 +140,8 @@ public:
this->swizzle = SWIZZLE_XYZW;
this->negate = 0;
this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
}
st_src_reg()
@@ -147,6 +153,8 @@ public:
this->swizzle = 0;
this->negate = 0;
this->reladdr = NULL;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
}
explicit st_src_reg(st_dst_reg reg);
@@ -159,10 +167,22 @@ public:
int type; /** GLSL_TYPE_* from GLSL IR (enum glsl_base_type) */
/** Register index should be offset by the integer in this reg. */
st_src_reg *reladdr;
+ st_src_reg *reladdr2;
+ bool has_index2;
};
class st_dst_reg {
public:
+ st_dst_reg(gl_register_file file, int writemask, int type, int index)
+ {
+ this->file = file;
+ this->index = index;
+ this->writemask = writemask;
+ this->cond_mask = COND_TR;
+ this->reladdr = NULL;
+ this->type = type;
+ }
+
st_dst_reg(gl_register_file file, int writemask, int type)
{
this->file = file;
@@ -203,6 +223,8 @@ st_src_reg::st_src_reg(st_dst_reg reg)
this->negate = 0;
this->reladdr = reg.reladdr;
this->index2D = 0;
+ this->reladdr2 = NULL;
+ this->has_index2 = false;
}
st_dst_reg::st_dst_reg(st_src_reg reg)
@@ -449,7 +471,8 @@ static st_src_reg undef_src = st_src_reg(PROGRAM_UNDEFINED, 0, GLSL_TYPE_ERROR);
static st_dst_reg undef_dst = st_dst_reg(PROGRAM_UNDEFINED, SWIZZLE_NOOP, GLSL_TYPE_ERROR);
-static st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT);
+static st_dst_reg address_reg = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT, 0);
+static st_dst_reg address_reg2 = st_dst_reg(PROGRAM_ADDRESS, WRITEMASK_X, GLSL_TYPE_FLOAT, 1);
static void
fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3);
@@ -515,9 +538,9 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
* sources into temps.
*/
num_reladdr += dst.reladdr != NULL;
- num_reladdr += src0.reladdr != NULL;
- num_reladdr += src1.reladdr != NULL;
- num_reladdr += src2.reladdr != NULL;
+ num_reladdr += src0.reladdr != NULL || src0.reladdr2 != NULL;
+ num_reladdr += src1.reladdr != NULL || src1.reladdr2 != NULL;
+ num_reladdr += src2.reladdr != NULL || src2.reladdr2 != NULL;
reladdr_to_temp(ir, &src2, &num_reladdr);
reladdr_to_temp(ir, &src1, &num_reladdr);
@@ -539,9 +562,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
inst->function = NULL;
- if (op == TGSI_OPCODE_ARL || op == TGSI_OPCODE_UARL)
- this->num_address_regs = 1;
-
/* Update indirect addressing status used by TGSI */
if (dst.reladdr) {
switch(dst.file) {
@@ -765,6 +785,10 @@ glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT)
op = TGSI_OPCODE_UARL;
+ assert(dst.file == PROGRAM_ADDRESS);
+ if (dst.index >= this->num_address_regs)
+ this->num_address_regs = dst.index + 1;
+
emit(NULL, op, dst, src0);
}
@@ -1328,10 +1352,11 @@ void
glsl_to_tgsi_visitor::reladdr_to_temp(ir_instruction *ir,
st_src_reg *reg, int *num_reladdr)
{
- if (!reg->reladdr)
+ if (!reg->reladdr && !reg->reladdr2)
return;
- emit_arl(ir, address_reg, *reg->reladdr);
+ if (reg->reladdr) emit_arl(ir, address_reg, *reg->reladdr);
+ if (reg->reladdr2) emit_arl(ir, address_reg2, *reg->reladdr2);
if (*num_reladdr != 1) {
st_src_reg temp = get_temp(glsl_type::vec4_type);
@@ -2098,14 +2123,26 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
ir_constant *index;
st_src_reg src;
int element_size = type_size(ir->type);
+ bool is_2D_input;
index = ir->array_index->constant_expression_value();
ir->array->accept(this);
src = this->result;
+ is_2D_input = this->prog->Target == GL_GEOMETRY_PROGRAM_NV &&
+ src.file == PROGRAM_INPUT &&
+ ir->array->ir_type != ir_type_dereference_array;
+
+ if (is_2D_input)
+ element_size = 1;
+
if (index) {
- src.index += index->value.i[0] * element_size;
+ if (is_2D_input) {
+ src.index2D = index->value.i[0];
+ src.has_index2 = true;
+ } else
+ src.index += index->value.i[0] * element_size;
} else {
/* Variable index array dereference. It eats the "vec4" of the
* base of the array and an index that offsets the TGSI register
@@ -2128,7 +2165,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
/* If there was already a relative address register involved, add the
* new and the old together to get the new offset.
*/
- if (src.reladdr != NULL) {
+ if (!is_2D_input && src.reladdr != NULL) {
st_src_reg accum_reg = get_temp(native_integers ?
glsl_type::int_type : glsl_type::float_type);
@@ -2138,8 +2175,15 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
index_reg = accum_reg;
}
- src.reladdr = ralloc(mem_ctx, st_src_reg);
- memcpy(src.reladdr, &index_reg, sizeof(index_reg));
+ if (is_2D_input) {
+ src.reladdr2 = ralloc(mem_ctx, st_src_reg);
+ memcpy(src.reladdr2, &index_reg, sizeof(index_reg));
+ src.index2D = 0;
+ src.has_index2 = true;
+ } else {
+ src.reladdr = ralloc(mem_ctx, st_src_reg);
+ memcpy(src.reladdr, &index_reg, sizeof(index_reg));
+ }
}
/* If the type is smaller than a vec4, replicate the last channel out. */
@@ -3018,16 +3062,19 @@ glsl_to_tgsi_visitor::visit(ir_if *ir)
if_inst = emit(ir->condition, TGSI_OPCODE_ENDIF);
}
+
void
glsl_to_tgsi_visitor::visit(ir_emit_vertex *ir)
{
- assert(!"Geometry shaders not supported.");
+ assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV);
+ emit(ir, TGSI_OPCODE_EMIT);
}
void
glsl_to_tgsi_visitor::visit(ir_end_primitive *ir)
{
- assert(!"Geometry shaders not supported.");
+ assert(this->prog->Target == GL_GEOMETRY_PROGRAM_NV);
+ emit(ir, TGSI_OPCODE_ENDPRIM);
}
glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
@@ -3440,7 +3487,8 @@ glsl_to_tgsi_visitor::copy_propagate(void)
int acp_base = inst->src[r].index * 4;
if (inst->src[r].file != PROGRAM_TEMPORARY ||
- inst->src[r].reladdr)
+ inst->src[r].reladdr ||
+ inst->src[r].reladdr2)
continue;
/* See if we can find entries in the ACP consisting of MOVs
@@ -3475,6 +3523,8 @@ glsl_to_tgsi_visitor::copy_propagate(void)
*/
inst->src[r].file = first->src[0].file;
inst->src[r].index = first->src[0].index;
+ inst->src[r].index2D = first->src[0].index2D;
+ inst->src[r].has_index2 = first->src[0].has_index2;
int swizzle = 0;
for (int i = 0; i < 4; i++) {
@@ -3579,6 +3629,7 @@ glsl_to_tgsi_visitor::copy_propagate(void)
!inst->dst.reladdr &&
!inst->saturate &&
!inst->src[0].reladdr &&
+ !inst->src[0].reladdr2 &&
!inst->src[0].negate) {
for (int i = 0; i < 4; i++) {
if (inst->dst.writemask & (1 << i)) {
@@ -4078,7 +4129,7 @@ struct st_translate {
struct ureg_src *immediates;
struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
- struct ureg_dst address[1];
+ struct ureg_dst address[2];
struct ureg_src samplers[PIPE_MAX_SAMPLERS];
struct ureg_src systemValues[SYSTEM_VALUE_MAX];
@@ -4355,6 +4406,15 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
{
struct ureg_src src = src_register(t, src_reg->file, src_reg->index, src_reg->index2D);
+ if (t->procType == TGSI_PROCESSOR_GEOMETRY && src_reg->has_index2) {
+ src = src_register(t, src_reg->file, src_reg->index, src_reg->index2D);
+ if (src_reg->reladdr2)
+ src = ureg_src_dimension_indirect(src, ureg_src(t->address[1]),
+ src_reg->index2D);
+ else
+ src = ureg_src_dimension(src, src_reg->index2D);
+ }
+
src = ureg_swizzle(src,
GET_SWZ(src_reg->swizzle, 0) & 0x3,
GET_SWZ(src_reg->swizzle, 1) & 0x3,
@@ -4844,8 +4904,10 @@ st_translate_program(
/* Declare address register.
*/
if (program->num_address_regs > 0) {
- assert(program->num_address_regs == 1);
+ assert(program->num_address_regs <= 2);
t->address[0] = ureg_DECL_address(ureg);
+ if (program->num_address_regs == 2)
+ t->address[1] = ureg_DECL_address(ureg);
}
/* Declare misc input registers
@@ -5166,6 +5228,9 @@ get_mesa_program(struct gl_context *ctx,
case GL_GEOMETRY_SHADER:
stgp = (struct st_geometry_program *)prog;
stgp->glsl_to_tgsi = v;
+ stgp->Base.InputType = shader_program->Geom.InputType;
+ stgp->Base.OutputType = shader_program->Geom.OutputType;
+ stgp->Base.VerticesOut = shader_program->Geom.VerticesOut;
break;
default:
assert(!"should not be reached");
diff --git a/mesalib/src/mesa/state_tracker/st_program.c b/mesalib/src/mesa/state_tracker/st_program.c
index 60cc37cf8..f010e1889 100644
--- a/mesalib/src/mesa/state_tracker/st_program.c
+++ b/mesalib/src/mesa/state_tracker/st_program.c
@@ -828,7 +828,6 @@ st_translate_geometry_program(struct st_context *st,
GLuint attr;
GLbitfield64 inputsRead;
GLuint vslot = 0;
- GLuint num_generic = 0;
uint gs_num_inputs = 0;
uint gs_builtin_inputs = 0;
@@ -848,7 +847,9 @@ st_translate_geometry_program(struct st_context *st,
if (!gpv)
return NULL;
- _mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_OUTPUT);
+ if (!stgp->glsl_to_tgsi) {
+ _mesa_remove_output_reads(&stgp->Base.Base, PROGRAM_OUTPUT);
+ }
ureg = ureg_create( TGSI_PROCESSOR_GEOMETRY );
if (ureg == NULL) {
@@ -910,15 +911,42 @@ st_translate_geometry_program(struct st_context *st,
stgp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
stgp->input_semantic_index[slot] = 0;
break;
+ case VARYING_SLOT_CLIP_VERTEX:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_CLIPVERTEX;
+ stgp->input_semantic_index[slot] = 0;
+ break;
+ case VARYING_SLOT_CLIP_DIST0:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
+ stgp->input_semantic_index[slot] = 0;
+ break;
+ case VARYING_SLOT_CLIP_DIST1:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
+ stgp->input_semantic_index[slot] = 1;
+ break;
+ case VARYING_SLOT_PSIZ:
+ stgp->input_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
+ stgp->input_semantic_index[slot] = 0;
+ break;
case VARYING_SLOT_TEX0:
+ case VARYING_SLOT_TEX1:
+ case VARYING_SLOT_TEX2:
+ case VARYING_SLOT_TEX3:
+ case VARYING_SLOT_TEX4:
+ case VARYING_SLOT_TEX5:
+ case VARYING_SLOT_TEX6:
+ case VARYING_SLOT_TEX7:
stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- stgp->input_semantic_index[slot] = num_generic++;
+ stgp->input_semantic_index[slot] = (attr - VARYING_SLOT_TEX0);
break;
case VARYING_SLOT_VAR0:
- /* fall-through */
default:
+ assert(attr >= VARYING_SLOT_VAR0 && attr < VARYING_SLOT_MAX);
stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- stgp->input_semantic_index[slot] = num_generic++;
+ stgp->input_semantic_index[slot] = (VARYING_SLOT_VAR0 -
+ VARYING_SLOT_TEX0 +
+ attr -
+ VARYING_SLOT_VAR0);
+ break;
}
}
}
@@ -929,7 +957,6 @@ st_translate_geometry_program(struct st_context *st,
gs_output_semantic_index[i] = 0;
}
- num_generic = 0;
/*
* Determine number of outputs, the (default) output register
* mapping and the semantic information for each output.
@@ -972,6 +999,26 @@ st_translate_geometry_program(struct st_context *st,
gs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
gs_output_semantic_index[slot] = 0;
break;
+ case VARYING_SLOT_CLIP_VERTEX:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPVERTEX;
+ gs_output_semantic_index[slot] = 0;
+ break;
+ case VARYING_SLOT_CLIP_DIST0:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
+ gs_output_semantic_index[slot] = 0;
+ break;
+ case VARYING_SLOT_CLIP_DIST1:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_CLIPDIST;
+ gs_output_semantic_index[slot] = 1;
+ break;
+ case VARYING_SLOT_LAYER:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_LAYER;
+ gs_output_semantic_index[slot] = 0;
+ break;
+ case VARYING_SLOT_PRIMITIVE_ID:
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_PRIMID;
+ gs_output_semantic_index[slot] = 0;
+ break;
case VARYING_SLOT_TEX0:
case VARYING_SLOT_TEX1:
case VARYING_SLOT_TEX2:
@@ -980,20 +1027,22 @@ st_translate_geometry_program(struct st_context *st,
case VARYING_SLOT_TEX5:
case VARYING_SLOT_TEX6:
case VARYING_SLOT_TEX7:
- /* fall-through */
+ gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ gs_output_semantic_index[slot] = (attr - VARYING_SLOT_TEX0);
+ break;
case VARYING_SLOT_VAR0:
- /* fall-through */
default:
assert(slot < Elements(gs_output_semantic_name));
- /* use default semantic info */
+ assert(attr >= VARYING_SLOT_VAR0);
gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
- gs_output_semantic_index[slot] = num_generic++;
+ gs_output_semantic_index[slot] = (VARYING_SLOT_VAR0 -
+ VARYING_SLOT_TEX0 +
+ attr -
+ VARYING_SLOT_VAR0);
}
}
}
- assert(gs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
-
/* find max output slot referenced to compute gs_num_outputs */
for (attr = 0; attr < VARYING_SLOT_MAX; attr++) {
if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
@@ -1031,23 +1080,44 @@ st_translate_geometry_program(struct st_context *st,
ureg_property_gs_output_prim(ureg, stgp->Base.OutputType);
ureg_property_gs_max_vertices(ureg, stgp->Base.VerticesOut);
- st_translate_mesa_program(st->ctx,
- TGSI_PROCESSOR_GEOMETRY,
- ureg,
- &stgp->Base.Base,
- /* inputs */
- gs_num_inputs,
- inputMapping,
- stgp->input_semantic_name,
- stgp->input_semantic_index,
- NULL,
- /* outputs */
- gs_num_outputs,
- outputMapping,
- gs_output_semantic_name,
- gs_output_semantic_index,
- FALSE,
- FALSE);
+ if (stgp->glsl_to_tgsi)
+ st_translate_program(st->ctx,
+ TGSI_PROCESSOR_GEOMETRY,
+ ureg,
+ stgp->glsl_to_tgsi,
+ &stgp->Base.Base,
+ /* inputs */
+ gs_num_inputs,
+ inputMapping,
+ stgp->input_semantic_name,
+ stgp->input_semantic_index,
+ NULL,
+ NULL,
+ /* outputs */
+ gs_num_outputs,
+ outputMapping,
+ gs_output_semantic_name,
+ gs_output_semantic_index,
+ FALSE,
+ FALSE);
+ else
+ st_translate_mesa_program(st->ctx,
+ TGSI_PROCESSOR_GEOMETRY,
+ ureg,
+ &stgp->Base.Base,
+ /* inputs */
+ gs_num_inputs,
+ inputMapping,
+ stgp->input_semantic_name,
+ stgp->input_semantic_index,
+ NULL,
+ /* outputs */
+ gs_num_outputs,
+ outputMapping,
+ gs_output_semantic_name,
+ gs_output_semantic_index,
+ FALSE,
+ FALSE);
stgp->num_inputs = gs_num_inputs;
stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
diff --git a/mesalib/src/mesa/vbo/vbo_save_api.c b/mesalib/src/mesa/vbo/vbo_save_api.c
index b5f951787..411c00604 100644
--- a/mesalib/src/mesa/vbo/vbo_save_api.c
+++ b/mesalib/src/mesa/vbo/vbo_save_api.c
@@ -237,16 +237,31 @@ GLfloat *
vbo_save_map_vertex_store(struct gl_context *ctx,
struct vbo_save_vertex_store *vertex_store)
{
+ const GLbitfield access = (GL_MAP_WRITE_BIT |
+ GL_MAP_INVALIDATE_RANGE_BIT |
+ GL_MAP_UNSYNCHRONIZED_BIT |
+ GL_MAP_FLUSH_EXPLICIT_BIT);
+
assert(vertex_store->bufferobj);
- assert(!vertex_store->buffer);
+ assert(!vertex_store->buffer); /* the buffer should not be mapped */
+
if (vertex_store->bufferobj->Size > 0) {
- vertex_store->buffer =
- (GLfloat *) ctx->Driver.MapBufferRange(ctx, 0,
- vertex_store->bufferobj->Size,
- GL_MAP_WRITE_BIT, /* not used */
- vertex_store->bufferobj);
- assert(vertex_store->buffer);
- return vertex_store->buffer + vertex_store->used;
+ /* Map the remaining free space in the VBO */
+ GLintptr offset = vertex_store->used * sizeof(GLfloat);
+ GLsizeiptr size = vertex_store->bufferobj->Size - offset;
+ GLfloat *range = (GLfloat *)
+ ctx->Driver.MapBufferRange(ctx, offset, size, access,
+ vertex_store->bufferobj);
+ if (range) {
+ /* compute address of start of whole buffer (needed elsewhere) */
+ vertex_store->buffer = range - vertex_store->used;
+ assert(vertex_store->buffer);
+ return range;
+ }
+ else {
+ vertex_store->buffer = NULL;
+ return NULL;
+ }
}
else {
/* probably ran out of memory for buffers */
@@ -260,6 +275,14 @@ vbo_save_unmap_vertex_store(struct gl_context *ctx,
struct vbo_save_vertex_store *vertex_store)
{
if (vertex_store->bufferobj->Size > 0) {
+ GLintptr offset = 0;
+ GLsizeiptr length = vertex_store->used * sizeof(GLfloat)
+ - vertex_store->bufferobj->Offset;
+
+ /* Explicitly flush the region we wrote to */
+ ctx->Driver.FlushMappedBufferRange(ctx, offset, length,
+ vertex_store->bufferobj);
+
ctx->Driver.UnmapBuffer(ctx, vertex_store->bufferobj);
}
vertex_store->buffer = NULL;