diff options
Diffstat (limited to 'mesalib/src')
-rw-r--r-- | mesalib/src/glsl/ast_to_hir.cpp | 98 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_types.cpp | 18 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_types.h | 6 | ||||
-rw-r--r-- | mesalib/src/glsl/ir.h | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/main/shaderapi.c | 14 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_atom_texture.c | 14 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_drawpixels.c | 28 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_texture.c | 30 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_format.c | 35 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_format.h | 3 |
10 files changed, 186 insertions, 64 deletions
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 49093d88f..92065f5b7 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -2821,30 +2821,46 @@ ast_declarator_list::hir(exec_list *instructions, } } - /* Integer vertex outputs must be qualified with 'flat'. + /* Integer fragment inputs must be qualified with 'flat'. In GLSL ES, + * so must integer vertex outputs. * - * From section 4.3.6 of the GLSL 1.30 spec: - * "If a vertex output is a signed or unsigned integer or integer - * vector, then it must be qualified with the interpolation qualifier - * flat." - * - * From section 4.3.4 of the GLSL 3.00 ES spec: + * From section 4.3.4 ("Inputs") of the GLSL 1.50 spec: * "Fragment shader inputs that are signed or unsigned integers or * integer vectors must be qualified with the interpolation qualifier * flat." * - * Since vertex outputs and fragment inputs must have matching - * qualifiers, these two requirements are equivalent. + * From section 4.3.4 ("Input Variables") of the GLSL 3.00 ES spec: + * "Fragment shader inputs that are, or contain, signed or unsigned + * integers or integer vectors must be qualified with the + * interpolation qualifier flat." + * + * From section 4.3.6 ("Output Variables") of the GLSL 3.00 ES spec: + * "Vertex shader outputs that are, or contain, signed or unsigned + * integers or integer vectors must be qualified with the + * interpolation qualifier flat." + * + * Note that prior to GLSL 1.50, this requirement applied to vertex + * outputs rather than fragment inputs. That creates problems in the + * presence of geometry shaders, so we adopt the GLSL 1.50 rule for all + * desktop GL shaders. For GLSL ES shaders, we follow the spec and + * apply the restriction to both vertex outputs and fragment inputs. + * + * Note also that the desktop GLSL specs are missing the text "or + * contain"; this is presumably an oversight, since there is no + * reasonable way to interpolate a fragment shader input that contains + * an integer. */ - if (state->is_version(130, 300) - && state->target == vertex_shader - && state->current_function == NULL - && var->type->is_integer() - && var->mode == ir_var_shader_out - && var->interpolation != INTERP_QUALIFIER_FLAT) { - - _mesa_glsl_error(&loc, state, "If a vertex output is an integer, " - "then it must be qualified with 'flat'"); + if (state->is_version(130, 300) && + var->type->contains_integer() && + var->interpolation != INTERP_QUALIFIER_FLAT && + ((state->target == fragment_shader && var->mode == ir_var_shader_in) + || (state->target == vertex_shader && var->mode == ir_var_shader_out + && state->es_shader))) { + const char *var_type = (state->target == vertex_shader) ? + "vertex output" : "fragment input"; + _mesa_glsl_error(&loc, state, "If a %s is (or contains) " + "an integer, then it must be qualified with 'flat'", + var_type); } @@ -3967,6 +3983,47 @@ ast_iteration_statement::hir(exec_list *instructions, } +/** + * Determine if the given type is valid for establishing a default precision + * qualifier. + * + * From GLSL ES 3.00 section 4.5.4 ("Default Precision Qualifiers"): + * + * "The precision statement + * + * precision precision-qualifier type; + * + * can be used to establish a default precision qualifier. The type field + * can be either int or float or any of the sampler types, and the + * precision-qualifier can be lowp, mediump, or highp." + * + * GLSL ES 1.00 has similar language. GLSL 1.30 doesn't allow precision + * qualifiers on sampler types, but this seems like an oversight (since the + * intention of including these in GLSL 1.30 is to allow compatibility with ES + * shaders). So we allow int, float, and all sampler types regardless of GLSL + * version. + */ +static bool +is_valid_default_precision_type(const struct _mesa_glsl_parse_state *state, + const char *type_name) +{ + const struct glsl_type *type = state->symbols->get_type(type_name); + if (type == NULL) + return false; + + switch (type->base_type) { + case GLSL_TYPE_INT: + case GLSL_TYPE_FLOAT: + /* "int" and "float" are valid, but vectors and matrices are not. */ + return type->vector_elements == 1 && type->matrix_columns == 1; + case GLSL_TYPE_SAMPLER: + return true; + default: + return false; + } +} + + ir_rvalue * ast_type_specifier::hir(exec_list *instructions, struct _mesa_glsl_parse_state *state) @@ -4007,11 +4064,10 @@ ast_type_specifier::hir(exec_list *instructions, "arrays"); return NULL; } - if (strcmp(this->type_name, "float") != 0 && - strcmp(this->type_name, "int") != 0) { + if (!is_valid_default_precision_type(state, this->type_name)) { _mesa_glsl_error(&loc, state, "default precision statements apply only to types " - "float and int"); + "float, int, and sampler types"); return NULL; } diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 3b066d099..82aeb84ed 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -158,6 +158,24 @@ glsl_type::contains_sampler() const } } + +bool +glsl_type::contains_integer() const +{ + if (this->is_array()) { + return this->fields.array->contains_integer(); + } else if (this->is_record()) { + for (unsigned int i = 0; i < this->length; i++) { + if (this->fields.structure[i].type->contains_integer()) + return true; + } + return false; + } else { + return this->is_integer(); + } +} + + gl_texture_index glsl_type::sampler_index() const { diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h index b0db2bf11..8cfd8dd02 100644 --- a/mesalib/src/glsl/glsl_types.h +++ b/mesalib/src/glsl/glsl_types.h @@ -360,6 +360,12 @@ struct glsl_type { } /** + * Query whether or not type is an integral type, or for struct and array + * types, contains an integral type. + */ + bool contains_integer() const; + + /** * Query whether or not a type is a float type */ bool is_float() const diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index efd80dad8..1e09988e5 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -1448,8 +1448,8 @@ enum ir_texture_opcode { class ir_texture : public ir_rvalue { public: ir_texture(enum ir_texture_opcode op) - : op(op), coordinate(NULL), projector(NULL), shadow_comparitor(NULL), - offset(NULL) + : op(op), sampler(NULL), coordinate(NULL), projector(NULL), + shadow_comparitor(NULL), offset(NULL) { this->ir_type = ir_type_texture; } diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 2590abe7e..be6946798 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -207,6 +207,8 @@ attach_shader(struct gl_context *ctx, GLuint program, GLuint shader) struct gl_shader *sh; GLuint i, n; + const bool same_type_disallowed = _mesa_is_gles(ctx); + shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader"); if (!shProg) return; @@ -227,6 +229,18 @@ attach_shader(struct gl_context *ctx, GLuint program, GLuint shader) */ _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader"); return; + } else if (same_type_disallowed && + shProg->Shaders[i]->Type == sh->Type) { + /* Shader with the same type is already attached to this program, + * OpenGL ES 2.0 and 3.0 specs say: + * + * "Multiple shader objects of the same type may not be attached + * to a single program object. [...] The error INVALID_OPERATION + * is generated if [...] another shader object of the same type + * as shader is already attached to program." + */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader"); + return; } } diff --git a/mesalib/src/mesa/state_tracker/st_atom_texture.c b/mesalib/src/mesa/state_tracker/st_atom_texture.c index 28327bc14..fc2d69013 100644 --- a/mesalib/src/mesa/state_tracker/st_atom_texture.c +++ b/mesalib/src/mesa/state_tracker/st_atom_texture.c @@ -234,11 +234,17 @@ update_single_texture(struct st_context *st, } /* Determine the format of the texture sampler view */ - view_format = stObj->pt->format; + if (texObj->Target == GL_TEXTURE_BUFFER) { + view_format = + st_mesa_format_to_pipe_format(stObj->base._BufferObjectFormat); + } + else { + view_format = stObj->pt->format; - /* If sRGB decoding is off, use the linear format */ - if (samp->sRGBDecode == GL_SKIP_DECODE_EXT) { - view_format = util_format_linear(view_format); + /* If sRGB decoding is off, use the linear format */ + if (samp->sRGBDecode == GL_SKIP_DECODE_EXT) { + view_format = util_format_linear(view_format); + } } /* if sampler view has changed dereference it */ diff --git a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c index ba4f17a3d..e282bf98d 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/mesalib/src/mesa/state_tracker/st_cb_drawpixels.c @@ -484,19 +484,29 @@ make_texture(struct st_context *st, gl_format mformat; struct pipe_resource *pt; enum pipe_format pipeFormat; - GLenum baseInternalFormat, intFormat; - - intFormat = internal_format(ctx, format, type); - baseInternalFormat = _mesa_base_tex_format(ctx, intFormat); + GLenum baseInternalFormat; /* Choose a pixel format for the temp texture which will hold the * image to draw. */ - pipeFormat = st_choose_format(st, intFormat, format, type, - PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, - FALSE); - assert(pipeFormat != PIPE_FORMAT_NONE); - mformat = st_pipe_format_to_mesa_format(pipeFormat); + pipeFormat = st_choose_matching_format(pipe->screen, PIPE_BIND_SAMPLER_VIEW, + format, type, unpack->SwapBytes); + + if (pipeFormat != PIPE_FORMAT_NONE) { + mformat = st_pipe_format_to_mesa_format(pipeFormat); + baseInternalFormat = _mesa_get_format_base_format(mformat); + } + else { + /* Use the generic approach. */ + GLenum intFormat = internal_format(ctx, format, type); + + baseInternalFormat = _mesa_base_tex_format(ctx, intFormat); + pipeFormat = st_choose_format(st, intFormat, format, type, + PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, + FALSE); + assert(pipeFormat != PIPE_FORMAT_NONE); + mformat = st_pipe_format_to_mesa_format(pipeFormat); + } pixels = _mesa_map_pbo_source(ctx, unpack, pixels); if (!pixels) diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index ac70e9292..f8ff024db 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -560,32 +560,6 @@ st_CompressedTexImage(struct gl_context *ctx, GLuint dims, } -static enum pipe_format -choose_matching_format(struct pipe_screen *screen, unsigned bind, - GLenum format, GLenum type, GLboolean swapBytes) -{ - gl_format mesa_format; - - for (mesa_format = 1; mesa_format < MESA_FORMAT_COUNT; mesa_format++) { - if (_mesa_get_format_color_encoding(mesa_format) == GL_SRGB) { - continue; - } - - if (_mesa_format_matches_format_and_type(mesa_format, format, type, - swapBytes)) { - enum pipe_format format = st_mesa_format_to_pipe_format(mesa_format); - - if (format && - screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, - bind)) { - return format; - } - /* It's unlikely to find 2 matching Mesa formats. */ - break; - } - } - return PIPE_FORMAT_NONE; -} /** @@ -683,8 +657,8 @@ st_GetTexImage(struct gl_context * ctx, /* Choose the destination format by finding the best match * for the format+type combo. */ - dst_format = choose_matching_format(screen, bind, format, type, - ctx->Pack.SwapBytes); + dst_format = st_choose_matching_format(screen, bind, format, type, + ctx->Pack.SwapBytes); if (dst_format == PIPE_FORMAT_NONE) { GLenum dst_glformat; diff --git a/mesalib/src/mesa/state_tracker/st_format.c b/mesalib/src/mesa/state_tracker/st_format.c index 02969b995..5fd44e76d 100644 --- a/mesalib/src/mesa/state_tracker/st_format.c +++ b/mesalib/src/mesa/state_tracker/st_format.c @@ -1675,6 +1675,41 @@ st_choose_renderbuffer_format(struct st_context *st, /** + * Given an OpenGL user-requested format and type, and swapBytes state, + * return the format which exactly matches those parameters, so that + * a memcpy-based transfer can be done. + * + * If no format is supported, return PIPE_FORMAT_NONE. + */ +enum pipe_format +st_choose_matching_format(struct pipe_screen *screen, unsigned bind, + GLenum format, GLenum type, GLboolean swapBytes) +{ + gl_format mesa_format; + + for (mesa_format = 1; mesa_format < MESA_FORMAT_COUNT; mesa_format++) { + if (_mesa_get_format_color_encoding(mesa_format) == GL_SRGB) { + continue; + } + + if (_mesa_format_matches_format_and_type(mesa_format, format, type, + swapBytes)) { + enum pipe_format format = st_mesa_format_to_pipe_format(mesa_format); + + if (format && + screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, + bind)) { + return format; + } + /* It's unlikely to find 2 matching Mesa formats. */ + break; + } + } + return PIPE_FORMAT_NONE; +} + + +/** * Called via ctx->Driver.ChooseTextureFormat(). */ gl_format diff --git a/mesalib/src/mesa/state_tracker/st_format.h b/mesalib/src/mesa/state_tracker/st_format.h index aee624d24..3db409b74 100644 --- a/mesalib/src/mesa/state_tracker/st_format.h +++ b/mesalib/src/mesa/state_tracker/st_format.h @@ -57,6 +57,9 @@ extern enum pipe_format st_choose_renderbuffer_format(struct st_context *st, GLenum internalFormat, unsigned sample_count); +extern enum pipe_format +st_choose_matching_format(struct pipe_screen *screen, unsigned bind, + GLenum format, GLenum type, GLboolean swapBytes); extern gl_format st_ChooseTextureFormat(struct gl_context * ctx, GLenum target, |