diff options
-rw-r--r-- | X11/xtrans/Xtranssock.c | 32 | ||||
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 20 | ||||
-rw-r--r-- | mesalib/src/glsl/builtin_variables.cpp | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/ir.cpp | 3 | ||||
-rw-r--r-- | mesalib/src/glsl/ir.h | 36 | ||||
-rw-r--r-- | mesalib/src/glsl/ir_clone.cpp | 1 | ||||
-rw-r--r-- | mesalib/src/glsl/link_interface_blocks.cpp | 102 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.cpp | 9 | ||||
-rw-r--r-- | mesalib/src/glsl/linker.h | 10 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/common/meta.c | 52 | ||||
-rw-r--r-- | mesalib/src/mesa/main/context.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/main/debug.c | 10 | ||||
-rw-r--r-- | mesalib/src/mesa/main/debug.h | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/main/fbobject.c | 84 | ||||
-rw-r--r-- | mesalib/src/mesa/main/mtypes.h | 8 | ||||
-rw-r--r-- | mesalib/src/mesa/main/texparam.c | 16 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 7 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c | 7 |
18 files changed, 310 insertions, 92 deletions
diff --git a/X11/xtrans/Xtranssock.c b/X11/xtrans/Xtranssock.c index c9d103352..fdf1dd774 100644 --- a/X11/xtrans/Xtranssock.c +++ b/X11/xtrans/Xtranssock.c @@ -2197,27 +2197,11 @@ TRANS(SocketSendFdInvalid)(XtransConnInfo ciptr, int fd, int do_close) #define MAX_FDS 128 -struct fd_pass { +union fd_pass { struct cmsghdr cmsghdr; - int fd[MAX_FDS]; + char buf[CMSG_SPACE(MAX_FDS * sizeof(int))]; }; -static inline void init_msg_recv(struct msghdr *msg, struct iovec *iov, int niov, struct fd_pass *pass, int nfd) { - msg->msg_name = NULL; - msg->msg_namelen = 0; - msg->msg_iov = iov; - msg->msg_iovlen = niov; - msg->msg_control = pass; - msg->msg_controllen = sizeof (struct cmsghdr) + nfd * sizeof (int); -} - -static inline void init_msg_send(struct msghdr *msg, struct iovec *iov, int niov, struct fd_pass *pass, int nfd) { - init_msg_recv(msg, iov, niov, pass, nfd); - pass->cmsghdr.cmsg_len = msg->msg_controllen; - pass->cmsghdr.cmsg_level = SOL_SOCKET; - pass->cmsghdr.cmsg_type = SCM_RIGHTS; -} - #endif /* XTRANS_SEND_FDS */ static int @@ -2241,13 +2225,13 @@ TRANS(SocketRead) (XtransConnInfo ciptr, char *buf, int size) .iov_base = buf, .iov_len = size }; - char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)]; + union fd_pass cmsgbuf; struct msghdr msg = { .msg_name = NULL, .msg_namelen = 0, .msg_iov = &iov, .msg_iovlen = 1, - .msg_control = cmsgbuf, + .msg_control = cmsgbuf.buf, .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int)) }; @@ -2282,13 +2266,13 @@ TRANS(SocketReadv) (XtransConnInfo ciptr, struct iovec *buf, int size) #if XTRANS_SEND_FDS { - char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)]; + union fd_pass cmsgbuf; struct msghdr msg = { .msg_name = NULL, .msg_namelen = 0, .msg_iov = buf, .msg_iovlen = size, - .msg_control = cmsgbuf, + .msg_control = cmsgbuf.buf, .msg_controllen = CMSG_LEN(MAX_FDS * sizeof(int)) }; @@ -2324,7 +2308,7 @@ TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size) #if XTRANS_SEND_FDS if (ciptr->send_fds) { - char cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_FDS)]; + union fd_pass cmsgbuf; int nfd = nFd(&ciptr->send_fds); struct _XtransConnFd *cf = ciptr->send_fds; struct msghdr msg = { @@ -2332,7 +2316,7 @@ TRANS(SocketWritev) (XtransConnInfo ciptr, struct iovec *buf, int size) .msg_namelen = 0, .msg_iov = buf, .msg_iovlen = size, - .msg_control = cmsgbuf, + .msg_control = cmsgbuf.buf, .msg_controllen = CMSG_LEN(nfd * sizeof(int)) }; struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 76b256c73..01280478c 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -3355,6 +3355,15 @@ ast_declarator_list::hir(exec_list *instructions, ir_variable *earlier = get_variable_being_redeclared(var, decl->get_location(), state, false /* allow_all_redeclarations */); + if (earlier != NULL) { + if (strncmp(var->name, "gl_", 3) == 0 && + earlier->how_declared == ir_var_declared_in_block) { + _mesa_glsl_error(&loc, state, + "`%s' has already been redeclared using " + "gl_PerVertex", var->name); + } + earlier->how_declared = ir_var_declared_normally; + } if (decl->initializer != NULL) { result = process_initializer((earlier == NULL) ? var : earlier, @@ -5048,6 +5057,7 @@ ast_interface_block::hir(exec_list *instructions, _mesa_glsl_error(&loc, state, "`%s' redeclared", this->instance_name); } + earlier->how_declared = ir_var_declared_normally; earlier->type = var->type; earlier->reinit_interface_type(block_type); delete var; @@ -5078,7 +5088,11 @@ ast_interface_block::hir(exec_list *instructions, _mesa_glsl_error(&loc, state, "redeclaration of gl_PerVertex can only " "include built-in variables"); + } else if (earlier->how_declared == ir_var_declared_normally) { + _mesa_glsl_error(&loc, state, + "`%s' has already been redeclared", var->name); } else { + earlier->how_declared = ir_var_declared_in_block; earlier->reinit_interface_type(block_type); } continue; @@ -5125,6 +5139,12 @@ ast_interface_block::hir(exec_list *instructions, if (var != NULL && var->get_interface_type() == earlier_per_vertex && var->mode == var_mode) { + if (var->how_declared == ir_var_declared_normally) { + _mesa_glsl_error(&loc, state, + "redeclaration of gl_PerVertex cannot " + "follow a redeclaration of `%s'", + var->name); + } state->symbols->disable_variable(var->name); var->remove(); } diff --git a/mesalib/src/glsl/builtin_variables.cpp b/mesalib/src/glsl/builtin_variables.cpp index 4d441045a..d57324c2f 100644 --- a/mesalib/src/glsl/builtin_variables.cpp +++ b/mesalib/src/glsl/builtin_variables.cpp @@ -434,6 +434,7 @@ builtin_variable_generator::add_variable(const char *name, enum ir_variable_mode mode, int slot) { ir_variable *var = new(symtab) ir_variable(type, name, mode); + var->how_declared = ir_var_declared_implicitly; switch (var->mode) { case ir_var_auto: diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index 1b4973612..ffff2976a 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -1586,7 +1586,8 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name, ir_variable_mode mode) : max_array_access(0), max_ifc_array_access(NULL), read_only(false), centroid(false), invariant(false), - mode(mode), interpolation(INTERP_QUALIFIER_NONE), atomic() + how_declared(ir_var_declared_normally), mode(mode), + interpolation(INTERP_QUALIFIER_NONE), atomic() { this->ir_type = ir_type_variable; this->type = type; diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index 7859702ed..4f775da4b 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -294,6 +294,34 @@ enum ir_variable_mode { }; /** + * Enum keeping track of how a variable was declared. For error checking of + * the gl_PerVertex redeclaration rules. + */ +enum ir_var_declaration_type { + /** + * Normal declaration (for most variables, this means an explicit + * declaration. Exception: temporaries are always implicitly declared, but + * they still use ir_var_declared_normally). + * + * Note: an ir_variable that represents a named interface block uses + * ir_var_declared_normally. + */ + ir_var_declared_normally = 0, + + /** + * Variable was explicitly declared (or re-declared) in an unnamed + * interface block. + */ + ir_var_declared_in_block, + + /** + * Variable is an implicitly declared built-in that has not been explicitly + * re-declared by the shader. + */ + ir_var_declared_implicitly, +}; + +/** * \brief Layout qualifiers for gl_FragDepth. * * The AMD/ARB_conservative_depth extensions allow gl_FragDepth to be redeclared @@ -526,6 +554,14 @@ public: unsigned assigned:1; /** + * Enum indicating how the variable was declared. See + * ir_var_declaration_type. + * + * This is used to detect certain kinds of illegal variable redeclarations. + */ + unsigned how_declared:2; + + /** * Storage class of the variable. * * \sa ir_variable_mode diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp index b0f173a62..40ed33afc 100644 --- a/mesalib/src/glsl/ir_clone.cpp +++ b/mesalib/src/glsl/ir_clone.cpp @@ -68,6 +68,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const var->has_initializer = this->has_initializer; var->depth_layout = this->depth_layout; var->assigned = this->assigned; + var->how_declared = this->how_declared; var->used = this->used; var->num_state_slots = this->num_state_slots; diff --git a/mesalib/src/glsl/link_interface_blocks.cpp b/mesalib/src/glsl/link_interface_blocks.cpp index a7fceb9ba..6900fa94e 100644 --- a/mesalib/src/glsl/link_interface_blocks.cpp +++ b/mesalib/src/glsl/link_interface_blocks.cpp @@ -60,6 +60,7 @@ struct interface_block_definition if (var->type->is_array()) array_size = var->type->length; } + explicitly_declared = (var->how_declared != ir_var_declared_implicitly); } /** @@ -77,6 +78,12 @@ struct interface_block_definition * Otherwise -1. */ int array_size; + + /** + * True if this interface block was explicitly declared in the shader; + * false if it was an implicitly declared built-in interface block. + */ + bool explicitly_declared; }; @@ -91,8 +98,14 @@ intrastage_match(interface_block_definition *a, ir_variable_mode mode) { /* Types must match. */ - if (a->type != b->type) - return false; + if (a->type != b->type) { + /* Exception: if both the interface blocks are implicitly declared, + * don't force their types to match. They might mismatch due to the two + * shaders using different GLSL versions, and that's ok. + */ + if (a->explicitly_declared || b->explicitly_declared) + return false; + } /* Presence/absence of interface names must match. */ if ((a->instance_name == NULL) != (b->instance_name == NULL)) @@ -144,8 +157,14 @@ interstage_match(const interface_block_definition *producer, assert(producer->array_size != 0); /* Types must match. */ - if (consumer->type != producer->type) - return false; + if (consumer->type != producer->type) { + /* Exception: if both the interface blocks are implicitly declared, + * don't force their types to match. They might mismatch due to the two + * shaders using different GLSL versions, and that's ok. + */ + if (consumer->explicitly_declared || producer->explicitly_declared) + return false; + } if (extra_array_level) { /* Consumer must be an array, and producer must not. */ if (consumer->array_size == -1) @@ -289,57 +308,78 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog, } void -validate_interstage_interface_blocks(struct gl_shader_program *prog, - const gl_shader *producer, - const gl_shader *consumer) +validate_interstage_inout_blocks(struct gl_shader_program *prog, + const gl_shader *producer, + const gl_shader *consumer) { - interface_block_definitions inout_interfaces; - interface_block_definitions uniform_interfaces; + interface_block_definitions definitions; const bool extra_array_level = consumer->Type == GL_GEOMETRY_SHADER; - /* Add non-output interfaces from the consumer to the symbol table. */ + /* Add input interfaces from the consumer to the symbol table. */ foreach_list(node, consumer->ir) { ir_variable *var = ((ir_instruction *) node)->as_variable(); - if (!var || !var->get_interface_type() || var->mode == ir_var_shader_out) + if (!var || !var->get_interface_type() || var->mode != ir_var_shader_in) continue; - interface_block_definitions *definitions = var->mode == ir_var_uniform ? - &uniform_interfaces : &inout_interfaces; - definitions->store(interface_block_definition(var)); + definitions.store(interface_block_definition(var)); } - /* Verify that the producer's interfaces match. */ + /* Verify that the producer's output interfaces match. */ foreach_list(node, producer->ir) { ir_variable *var = ((ir_instruction *) node)->as_variable(); - if (!var || !var->get_interface_type() || var->mode == ir_var_shader_in) + if (!var || !var->get_interface_type() || var->mode != ir_var_shader_out) continue; - interface_block_definitions *definitions = var->mode == ir_var_uniform ? - &uniform_interfaces : &inout_interfaces; interface_block_definition *consumer_def = - definitions->lookup(var->get_interface_type()->name); + definitions.lookup(var->get_interface_type()->name); /* The consumer doesn't use this output block. Ignore it. */ if (consumer_def == NULL) continue; const interface_block_definition producer_def(var); - bool match; - if (var->mode == ir_var_uniform) { - /* Uniform matching rules are the same for interstage and intrastage - * linking. - */ - match = intrastage_match(consumer_def, &producer_def, - (ir_variable_mode) var->mode); - } else { - match = interstage_match(&producer_def, consumer_def, - extra_array_level); - } - if (!match) { + if (!interstage_match(&producer_def, consumer_def, extra_array_level)) { linker_error(prog, "definitions of interface block `%s' do not " "match\n", var->get_interface_type()->name); return; } } } + + +void +validate_interstage_uniform_blocks(struct gl_shader_program *prog, + gl_shader **stages, int num_stages) +{ + interface_block_definitions definitions; + + for (int i = 0; i < num_stages; i++) { + if (stages[i] == NULL) + continue; + + const gl_shader *stage = stages[i]; + foreach_list(node, stage->ir) { + ir_variable *var = ((ir_instruction *) node)->as_variable(); + if (!var || !var->get_interface_type() || var->mode != ir_var_uniform) + continue; + + interface_block_definition *old_def = + definitions.lookup(var->get_interface_type()->name); + const interface_block_definition new_def(var); + if (old_def == NULL) { + definitions.store(new_def); + } else { + /* Interstage uniform matching rules are the same as intrastage + * uniform matchin rules (for uniforms, it is as though all + * shaders are in the same shader stage). + */ + if (!intrastage_match(old_def, &new_def, ir_var_uniform)) { + linker_error(prog, "definitions of interface block `%s' do not " + "match\n", var->get_interface_type()->name); + return; + } + } + } + } +} diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index 1d53b6599..fac186a63 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -2154,8 +2154,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) if (prog->_LinkedShaders[i] == NULL) continue; - validate_interstage_interface_blocks(prog, prog->_LinkedShaders[prev], - prog->_LinkedShaders[i]); + validate_interstage_inout_blocks(prog, prog->_LinkedShaders[prev], + prog->_LinkedShaders[i]); if (!prog->LinkStatus) goto done; @@ -2168,6 +2168,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) prev = i; } + /* Cross-validate uniform blocks between shader stages */ + validate_interstage_uniform_blocks(prog, prog->_LinkedShaders, + MESA_SHADER_TYPES); + if (!prog->LinkStatus) + goto done; for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { if (prog->_LinkedShaders[i] != NULL) diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h index 7b1f6f9c5..130915db4 100644 --- a/mesalib/src/glsl/linker.h +++ b/mesalib/src/glsl/linker.h @@ -65,9 +65,13 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog, unsigned num_shaders); void -validate_interstage_interface_blocks(struct gl_shader_program *prog, - const gl_shader *producer, - const gl_shader *consumer); +validate_interstage_inout_blocks(struct gl_shader_program *prog, + const gl_shader *producer, + const gl_shader *consumer); + +void +validate_interstage_uniform_blocks(struct gl_shader_program *prog, + gl_shader **stages, int num_stages); extern void link_assign_atomic_counter_resources(struct gl_context *ctx, diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 99b02baad..7b41876b9 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -241,9 +241,11 @@ struct clear_state GLuint VBO; GLuint ShaderProg; GLint ColorLocation; + GLint LayerLocation; GLuint IntegerShaderProg; GLint IntegerColorLocation; + GLint IntegerLayerLocation; }; @@ -2145,6 +2147,19 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) "{\n" " gl_Position = position;\n" "}\n"; + const char *gs_source = + "#version 150\n" + "layout(triangles) in;\n" + "layout(triangle_strip, max_vertices = 4) out;\n" + "uniform int layer;\n" + "void main()\n" + "{\n" + " for (int i = 0; i < 3; i++) {\n" + " gl_Layer = layer;\n" + " gl_Position = gl_in[i].gl_Position;\n" + " EmitVertex();\n" + " }\n" + "}\n"; const char *fs_source = "#ifdef GL_ES\n" "precision highp float;\n" @@ -2154,7 +2169,7 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) "{\n" " gl_FragColor = color;\n" "}\n"; - GLuint vs, fs; + GLuint vs, gs = 0, fs; bool has_integer_textures; if (clear->ArrayObj != 0) @@ -2176,6 +2191,12 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) _mesa_ShaderSource(vs, 1, &vs_source, NULL); _mesa_CompileShader(vs); + if (_mesa_has_geometry_shaders(ctx)) { + gs = _mesa_CreateShaderObjectARB(GL_GEOMETRY_SHADER); + _mesa_ShaderSource(gs, 1, &gs_source, NULL); + _mesa_CompileShader(gs); + } + fs = _mesa_CreateShaderObjectARB(GL_FRAGMENT_SHADER); _mesa_ShaderSource(fs, 1, &fs_source, NULL); _mesa_CompileShader(fs); @@ -2183,6 +2204,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) clear->ShaderProg = _mesa_CreateProgramObjectARB(); _mesa_AttachShader(clear->ShaderProg, fs); _mesa_DeleteObjectARB(fs); + if (gs != 0) + _mesa_AttachShader(clear->ShaderProg, gs); _mesa_AttachShader(clear->ShaderProg, vs); _mesa_DeleteObjectARB(vs); _mesa_BindAttribLocation(clear->ShaderProg, 0, "position"); @@ -2190,6 +2213,10 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg, "color"); + if (gs != 0) { + clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg, + "layer"); + } has_integer_textures = _mesa_is_gles3(ctx) || (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130); @@ -2227,6 +2254,8 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) clear->IntegerShaderProg = _mesa_CreateProgramObjectARB(); _mesa_AttachShader(clear->IntegerShaderProg, fs); _mesa_DeleteObjectARB(fs); + if (gs != 0) + _mesa_AttachShader(clear->IntegerShaderProg, gs); _mesa_AttachShader(clear->IntegerShaderProg, vs); _mesa_DeleteObjectARB(vs); _mesa_BindAttribLocation(clear->IntegerShaderProg, 0, "position"); @@ -2240,7 +2269,13 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear) clear->IntegerColorLocation = _mesa_GetUniformLocation(clear->IntegerShaderProg, "color"); + if (gs != 0) { + clear->IntegerLayerLocation = + _mesa_GetUniformLocation(clear->IntegerShaderProg, "layer"); + } } + if (gs != 0) + _mesa_DeleteObjectARB(gs); } static void @@ -2371,8 +2406,19 @@ _mesa_meta_glsl_Clear(struct gl_context *ctx, GLbitfield buffers) _mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, GL_DYNAMIC_DRAW_ARB); - /* draw quad */ - _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + /* draw quad(s) */ + if (fb->NumLayers > 0) { + unsigned layer; + for (layer = 0; layer < fb->NumLayers; layer++) { + if (fb->_IntegerColor) + _mesa_Uniform1i(clear->IntegerLayerLocation, layer); + else + _mesa_Uniform1i(clear->LayerLocation, layer); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + } else { + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + } _mesa_meta_end(ctx); } diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 8cbc9352a..87a4a3545 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -1535,7 +1535,7 @@ _mesa_make_current( struct gl_context *newCtx, * information. */ if (_mesa_getenv("MESA_INFO")) { - _mesa_print_info(); + _mesa_print_info(newCtx); } newCtx->FirstTimeCurrent = GL_FALSE; diff --git a/mesalib/src/mesa/main/debug.c b/mesalib/src/mesa/main/debug.c index 9434c1ea2..99b214789 100644 --- a/mesalib/src/mesa/main/debug.c +++ b/mesalib/src/mesa/main/debug.c @@ -103,7 +103,7 @@ _mesa_print_state( const char *msg, GLuint state ) /** * Print information about this Mesa version and build options. */ -void _mesa_print_info( void ) +void _mesa_print_info( struct gl_context *ctx ) { _mesa_debug(NULL, "Mesa GL_VERSION = %s\n", (char *) _mesa_GetString(GL_VERSION)); @@ -111,8 +111,12 @@ void _mesa_print_info( void ) (char *) _mesa_GetString(GL_RENDERER)); _mesa_debug(NULL, "Mesa GL_VENDOR = %s\n", (char *) _mesa_GetString(GL_VENDOR)); - _mesa_debug(NULL, "Mesa GL_EXTENSIONS = %s\n", - (char *) _mesa_GetString(GL_EXTENSIONS)); + + /* use ctx as GL_EXTENSIONS will not work on 3.0 or higher + * core contexts. + */ + _mesa_debug(NULL, "Mesa GL_EXTENSIONS = %s\n", ctx->Extensions.String); + #if defined(THREADS) _mesa_debug(NULL, "Mesa thread-safe: YES\n"); #else diff --git a/mesalib/src/mesa/main/debug.h b/mesalib/src/mesa/main/debug.h index 8414c5ebd..902f59538 100644 --- a/mesalib/src/mesa/main/debug.h +++ b/mesalib/src/mesa/main/debug.h @@ -43,7 +43,7 @@ struct gl_texture_image; extern void _mesa_print_enable_flags( const char *msg, GLuint flags ); extern void _mesa_print_state( const char *msg, GLuint state ); -extern void _mesa_print_info( void ); +extern void _mesa_print_info( struct gl_context *ctx ); extern void _mesa_init_debug( struct gl_context *ctx ); extern void diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 9dd71612f..365062729 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -905,6 +905,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, struct gl_renderbuffer_attachment *att; GLenum f; gl_format attFormat; + GLenum att_tex_target = GL_NONE; /* * XXX for ARB_fbo, only check color buffers that are named by @@ -945,6 +946,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, */ if (att->Type == GL_TEXTURE) { const struct gl_texture_image *texImg = att->Renderbuffer->TexImage; + att_tex_target = att->Texture->Target; minWidth = MIN2(minWidth, texImg->Width); maxWidth = MAX2(maxWidth, texImg->Width); minHeight = MIN2(minHeight, texImg->Height); @@ -1057,7 +1059,14 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, } /* Check that layered rendering is consistent. */ - att_layer_count = att->Layered ? att->Renderbuffer->Depth : 0; + if (att->Layered) { + if (att_tex_target == GL_TEXTURE_CUBE_MAP) + att_layer_count = 6; + else + att_layer_count = att->Renderbuffer->Depth; + } else { + att_layer_count = 0; + } if (!layer_count_valid) { layer_count = att_layer_count; layer_count_valid = true; @@ -1073,7 +1082,7 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, } } - fb->Layered = layer_count > 0; + fb->NumLayers = layer_count; if (_mesa_is_desktop_gl(ctx) && !ctx->Extensions.ARB_ES2_compatibility) { /* Check that all DrawBuffers are present */ @@ -2298,8 +2307,13 @@ reuse_framebuffer_texture_attachment(struct gl_framebuffer *fb, /** * Common code called by glFramebufferTexture1D/2D/3DEXT() and * glFramebufferTextureLayerEXT(). - * Note: glFramebufferTextureLayerEXT() has no textarget parameter so we'll - * get textarget=0 in that case. + * + * \param textarget is the textarget that was passed to the + * glFramebufferTexture...() function, or 0 if the corresponding function + * doesn't have a textarget parameter. + * + * \param layered is true if this function was called from + * glFramebufferTexture(), false otherwise. */ static void framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, @@ -2334,16 +2348,46 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target, texObj = _mesa_lookup_texture(ctx, texture); if (texObj != NULL) { if (textarget == 0) { - /* If textarget == 0 it means we're being called by - * glFramebufferTextureLayer() and textarget is not used. - * The only legal texture types for that function are 3D and - * 1D/2D arrays textures. - */ - err = (texObj->Target != GL_TEXTURE_3D) && - (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) && - (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT) && - (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY) && - (texObj->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY); + if (layered) { + /* We're being called by glFramebufferTexture() and textarget + * is not used. + */ + switch (texObj->Target) { + case GL_TEXTURE_3D: + case GL_TEXTURE_1D_ARRAY_EXT: + case GL_TEXTURE_2D_ARRAY_EXT: + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_ARRAY: + case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: + err = false; + break; + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_RECTANGLE: + case GL_TEXTURE_2D_MULTISAMPLE: + /* These texture types are valid to pass to + * glFramebufferTexture(), but since they aren't layered, it + * is equivalent to calling glFramebufferTexture{1D,2D}(). + */ + err = false; + layered = false; + textarget = texObj->Target; + break; + default: + err = true; + break; + } + } else { + /* We're being called by glFramebufferTextureLayer() and + * textarget is not used. The only legal texture types for + * that function are 3D and 1D/2D arrays textures. + */ + err = (texObj->Target != GL_TEXTURE_3D) && + (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) && + (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT) && + (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY) && + (texObj->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY); + } } else { /* Make sure textarget is consistent with the texture's type */ @@ -2920,6 +2964,18 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, " invalid FBO attachment structure"); } return; + case GL_FRAMEBUFFER_ATTACHMENT_LAYERED: + if (!_mesa_has_geometry_shaders(ctx)) { + goto invalid_pname_enum; + } else if (att->Type == GL_TEXTURE) { + *params = att->Layered; + } else if (att->Type == GL_NONE) { + _mesa_error(ctx, err, + "glGetFramebufferAttachmentParameteriv(pname)"); + } else { + goto invalid_pname_enum; + } + return; default: goto invalid_pname_enum; } diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 8801d6f61..ecfb5e08f 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -2994,7 +2994,13 @@ struct gl_framebuffer struct gl_renderbuffer *_ColorDrawBuffers[MAX_DRAW_BUFFERS]; struct gl_renderbuffer *_ColorReadBuffer; - GLboolean Layered; + /** + * The number of layers in the framebuffer, or 0 if the framebuffer is not + * layered. For cube maps, this value is 6. For cube map arrays, this + * value is the "depth" value passed to TexImage3D (always a multiple of + * 6). + */ + GLuint NumLayers; /** Delete this framebuffer */ void (*Delete)(struct gl_framebuffer *fb); diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index d56b7d9d7..7092c630b 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -684,11 +684,8 @@ set_tex_parameterf(struct gl_context *ctx, return GL_FALSE; case GL_TEXTURE_LOD_BIAS: - /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. - * It was removed in core-profile, and it has never existed in OpenGL - * ES. - */ - if (ctx->API != API_OPENGL_COMPAT) + /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */ + if (_mesa_is_gles(ctx)) goto invalid_pname; if (!target_allows_setting_sampler_parameters(texObj->Target)) @@ -1513,7 +1510,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) *params = (GLfloat) obj->DepthMode; break; case GL_TEXTURE_LOD_BIAS: - if (ctx->API != API_OPENGL_COMPAT) + if (_mesa_is_gles(ctx)) goto invalid_pname; *params = obj->Sampler.LodBias; @@ -1701,10 +1698,13 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) *params = (GLint) obj->DepthMode; break; case GL_TEXTURE_LOD_BIAS: - if (ctx->API != API_OPENGL_COMPAT) + if (_mesa_is_gles(ctx)) goto invalid_pname; - *params = (GLint) obj->Sampler.LodBias; + /* GL spec 'Data Conversions' section specifies that floating-point + * value in integer Get function is rounded to nearest integer + */ + *params = IROUND(obj->Sampler.LodBias); break; case GL_TEXTURE_CROP_RECT_OES: if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) 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 6319079d5..74b3e5b58 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -4889,6 +4889,13 @@ st_translate_program( t->outputs[i] = ureg_DECL_output(ureg, outputSemanticName[i], outputSemanticIndex[i]); + if (outputSemanticName[i] == TGSI_SEMANTIC_FOG) { + /* force register to contain a fog coordinate in the form (F, 0, 0, 1). */ + ureg_MOV(ureg, + ureg_writemask(t->outputs[i], TGSI_WRITEMASK_XYZW & ~TGSI_WRITEMASK_X), + ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 1.0f)); + t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_X); + } } if (passthrough_edgeflags) emit_edgeflags(t); 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 921b0f9b8..7d79c6235 100644 --- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -1121,6 +1121,13 @@ st_translate_mesa_program( t->outputs[i] = ureg_DECL_output( ureg, outputSemanticName[i], outputSemanticIndex[i] ); + if (outputSemanticName[i] == TGSI_SEMANTIC_FOG) { + /* force register to contain a fog coordinate in the form (F, 0, 0, 1). */ + ureg_MOV(ureg, + ureg_writemask(t->outputs[i], TGSI_WRITEMASK_XYZW & ~TGSI_WRITEMASK_X), + ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 1.0f)); + t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_X); + } } if (passthrough_edgeflags) emit_edgeflags( t, program ); |