diff options
Diffstat (limited to 'mesalib/src')
-rw-r--r-- | mesalib/src/gallium/auxiliary/SConscript | 2 | ||||
-rw-r--r-- | mesalib/src/glsl/ast_array_index.cpp | 6 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser.yy | 80 | ||||
-rw-r--r-- | mesalib/src/glsl/opt_algebraic.cpp | 23 | ||||
-rw-r--r-- | mesalib/src/mapi/glapi/gen/ARB_texture_multisample.xml | 4 | ||||
-rw-r--r-- | mesalib/src/mapi/glapi/gen/Makefile.am | 8 | ||||
-rw-r--r-- | mesalib/src/mesa/main/teximage.c | 47 | ||||
-rw-r--r-- | mesalib/src/mesa/main/teximage.h | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom.c | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom.h | 1 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_constbuf.c | 17 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_context.c | 6 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 101 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_program.c | 128 | ||||
-rw-r--r-- | mesalib/src/mesa/vbo/vbo_save_api.c | 39 |
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; |