aboutsummaryrefslogtreecommitdiff
path: root/mesalib
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib')
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp20
-rw-r--r--mesalib/src/glsl/builtin_variables.cpp1
-rw-r--r--mesalib/src/glsl/ir.cpp3
-rw-r--r--mesalib/src/glsl/ir.h36
-rw-r--r--mesalib/src/glsl/ir_clone.cpp1
-rw-r--r--mesalib/src/glsl/link_interface_blocks.cpp102
-rw-r--r--mesalib/src/glsl/linker.cpp9
-rw-r--r--mesalib/src/glsl/linker.h10
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c52
-rw-r--r--mesalib/src/mesa/main/context.c2
-rw-r--r--mesalib/src/mesa/main/debug.c10
-rw-r--r--mesalib/src/mesa/main/debug.h2
-rw-r--r--mesalib/src/mesa/main/fbobject.c84
-rw-r--r--mesalib/src/mesa/main/mtypes.h8
-rw-r--r--mesalib/src/mesa/main/texparam.c16
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp7
-rw-r--r--mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c7
17 files changed, 302 insertions, 68 deletions
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 9715a203e..64a2c5af9 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 e0aee7a35..50c2f385a 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 );