diff options
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/buffers.c | 71 | ||||
-rw-r--r-- | src/mesa/main/fbobject.c | 16 | ||||
-rw-r--r-- | src/mesa/main/ffvertex_prog.c | 17 | ||||
-rw-r--r-- | src/mesa/main/formatquery.c | 15 | ||||
-rw-r--r-- | src/mesa/main/genmipmap.c | 10 | ||||
-rw-r--r-- | src/mesa/main/get.c | 8 | ||||
-rw-r--r-- | src/mesa/main/get_hash_params.py | 6 | ||||
-rw-r--r-- | src/mesa/main/glformats.c | 31 | ||||
-rw-r--r-- | src/mesa/main/glformats.h | 3 | ||||
-rw-r--r-- | src/mesa/main/shader_query.cpp | 98 | ||||
-rw-r--r-- | src/mesa/main/texgetimage.c | 14 | ||||
-rw-r--r-- | src/mesa/main/teximage.c | 9 | ||||
-rw-r--r-- | src/mesa/main/texstorage.c | 4 |
13 files changed, 223 insertions, 79 deletions
diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index a28c583..d8815af 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -378,17 +378,48 @@ draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb, /* complicated error checking... */ for (output = 0; output < n; output++) { - /* Section 4.2 (Whole Framebuffer Operations) of the OpenGL 3.0 + destMask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]); + + /* From the OpenGL 3.0 specification, page 258: + * "Each buffer listed in bufs must be one of the values from tables + * 4.5 or 4.6. Otherwise, an INVALID_ENUM error is generated. + */ + if (destMask[output] == BAD_MASK) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", + caller, _mesa_enum_to_string(buffers[output])); + return; + } + + /* From the OpenGL 4.0 specification, page 256: + * "For both the default framebuffer and framebuffer objects, the + * constants FRONT, BACK, LEFT, RIGHT, and FRONT_AND_BACK are not + * valid in the bufs array passed to DrawBuffers, and will result in + * the error INVALID_ENUM. This restriction is because these + * constants may themselves refer to multiple buffers, as shown in + * table 4.4." + * Previous versions of the OpenGL specification say INVALID_OPERATION, + * but the Khronos conformance tests expect INVALID_ENUM. + */ + if (_mesa_bitcount(destMask[output]) > 1) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", + caller, _mesa_enum_to_string(buffers[output])); + return; + } + + /* Section 4.2 (Whole Framebuffer Operations) of the OpenGL ES 3.0 * specification says: * - * "Each buffer listed in bufs must be BACK, NONE, or one of the values - * from table 4.3 (NONE, COLOR_ATTACHMENTi)" + * "If the GL is bound to a draw framebuffer object, the ith buffer + * listed in bufs must be COLOR_ATTACHMENTi or NONE . Specifying a + * buffer out of order, BACK , or COLOR_ATTACHMENTm where m is greater + * than or equal to the value of MAX_- COLOR_ATTACHMENTS , will + * generate the error INVALID_OPERATION . */ - if (_mesa_is_gles3(ctx) && buffers[output] != GL_NONE && - buffers[output] != GL_BACK && + if (_mesa_is_gles3(ctx) && _mesa_is_user_fbo(fb) && + buffers[output] != GL_NONE && (buffers[output] < GL_COLOR_ATTACHMENT0 || buffers[output] >= GL_COLOR_ATTACHMENT0 + ctx->Const.MaxColorAttachments)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffers(buffer)"); + _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)"); return; } @@ -412,34 +443,6 @@ draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb, return; } - destMask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]); - - /* From the OpenGL 3.0 specification, page 258: - * "Each buffer listed in bufs must be one of the values from tables - * 4.5 or 4.6. Otherwise, an INVALID_ENUM error is generated. - */ - if (destMask[output] == BAD_MASK) { - _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", - caller, _mesa_enum_to_string(buffers[output])); - return; - } - - /* From the OpenGL 4.0 specification, page 256: - * "For both the default framebuffer and framebuffer objects, the - * constants FRONT, BACK, LEFT, RIGHT, and FRONT_AND_BACK are not - * valid in the bufs array passed to DrawBuffers, and will result in - * the error INVALID_ENUM. This restriction is because these - * constants may themselves refer to multiple buffers, as shown in - * table 4.4." - * Previous versions of the OpenGL specification say INVALID_OPERATION, - * but the Khronos conformance tests expect INVALID_ENUM. - */ - if (_mesa_bitcount(destMask[output]) > 1) { - _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid buffer %s)", - caller, _mesa_enum_to_string(buffers[output])); - return; - } - /* From the OpenGL 3.0 specification, page 259: * "If the GL is bound to the default framebuffer and DrawBuffers is * supplied with a constant (other than NONE) that does not indicate diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index bf47c1c..68da639 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -303,9 +303,21 @@ _mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, switch (attachment) { case GL_FRONT_LEFT: - return &fb->Attachment[BUFFER_FRONT_LEFT]; + /* Front buffers can be allocated on the first use, but + * glGetFramebufferAttachmentParameteriv must work even if that + * allocation hasn't happened yet. In such case, use the back buffer, + * which should be the same. + */ + if (fb->Attachment[BUFFER_FRONT_LEFT].Type == GL_NONE) + return &fb->Attachment[BUFFER_BACK_LEFT]; + else + return &fb->Attachment[BUFFER_FRONT_LEFT]; case GL_FRONT_RIGHT: - return &fb->Attachment[BUFFER_FRONT_RIGHT]; + /* Same as above. */ + if (fb->Attachment[BUFFER_FRONT_RIGHT].Type == GL_NONE) + return &fb->Attachment[BUFFER_BACK_RIGHT]; + else + return &fb->Attachment[BUFFER_FRONT_RIGHT]; case GL_BACK_LEFT: return &fb->Attachment[BUFFER_BACK_LEFT]; case GL_BACK_RIGHT: diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index d72bc71..18dffc3 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -293,10 +293,9 @@ struct ureg { GLuint file:4; GLint idx:9; /* relative addressing may be negative */ /* sizeof(idx) should == sizeof(prog_src_reg::Index) */ - GLuint abs:1; GLuint negate:1; GLuint swz:12; - GLuint pad:5; + GLuint pad:6; }; @@ -325,7 +324,6 @@ static const struct ureg undef = { 0, 0, 0, - 0, 0 }; @@ -344,7 +342,6 @@ static struct ureg make_ureg(GLuint file, GLint idx) struct ureg reg; reg.file = file; reg.idx = idx; - reg.abs = 0; reg.negate = 0; reg.swz = SWIZZLE_NOOP; reg.pad = 0; @@ -352,15 +349,6 @@ static struct ureg make_ureg(GLuint file, GLint idx) } - -static struct ureg absolute( struct ureg reg ) -{ - reg.abs = 1; - reg.negate = 0; - return reg; -} - - static struct ureg negate( struct ureg reg ) { reg.negate ^= 1; @@ -961,7 +949,8 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p, emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot_dir_norm); emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot); - emit_op2(p, OPCODE_POW, spot, 0, absolute(spot), swizzle1(attenuation, W)); + emit_op1(p, OPCODE_ABS, spot, 0, spot); + emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W)); emit_op2(p, OPCODE_MUL, att, 0, slt, spot); release_temp(p, spot); diff --git a/src/mesa/main/formatquery.c b/src/mesa/main/formatquery.c index 215c14f..e9727ea 100644 --- a/src/mesa/main/formatquery.c +++ b/src/mesa/main/formatquery.c @@ -387,13 +387,13 @@ _is_target_supported(struct gl_context *ctx, GLenum target) * "if a particular type of <target> is not supported by the * implementation the "unsupported" answer should be given. * This is not an error." + * + * For OpenGL ES, queries can only be used with GL_RENDERBUFFER or MS. */ switch(target){ + case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: - break; - - case GL_TEXTURE_1D: if (!_mesa_is_desktop_gl(ctx)) return false; break; @@ -404,12 +404,12 @@ _is_target_supported(struct gl_context *ctx, GLenum target) break; case GL_TEXTURE_2D_ARRAY: - if (!(_mesa_has_EXT_texture_array(ctx) || _mesa_is_gles3(ctx))) + if (!_mesa_has_EXT_texture_array(ctx)) return false; break; case GL_TEXTURE_CUBE_MAP: - if (!_mesa_has_ARB_texture_cube_map(ctx)) + if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_texture_cube_map(ctx)) return false; break; @@ -419,7 +419,7 @@ _is_target_supported(struct gl_context *ctx, GLenum target) break; case GL_TEXTURE_RECTANGLE: - if (!_mesa_has_NV_texture_rectangle(ctx)) + if (!_mesa_has_ARB_texture_rectangle(ctx)) return false; break; @@ -962,7 +962,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, switch (pname) { case GL_INTERNALFORMAT_DEPTH_SIZE: - if (!_mesa_has_ARB_depth_texture(ctx) && + if (ctx->API != API_OPENGL_CORE && + !_mesa_has_ARB_depth_texture(ctx) && target != GL_RENDERBUFFER && target != GL_TEXTURE_BUFFER) goto end; diff --git a/src/mesa/main/genmipmap.c b/src/mesa/main/genmipmap.c index d917220..2afe7be 100644 --- a/src/mesa/main/genmipmap.c +++ b/src/mesa/main/genmipmap.c @@ -85,10 +85,15 @@ _mesa_is_valid_generate_texture_mipmap_internalformat(struct gl_context *ctx, * not specified with an unsized internal format from table 8.3 or a * sized internal format that is both color-renderable and * texture-filterable according to table 8.10." + * + * GL_EXT_texture_format_BGRA8888 adds a GL_BGRA_EXT unsized internal + * format, and includes it in a very similar looking table. So we + * include it here as well. */ return internalformat == GL_RGBA || internalformat == GL_RGB || internalformat == GL_LUMINANCE_ALPHA || internalformat == GL_LUMINANCE || internalformat == GL_ALPHA || + internalformat == GL_BGRA_EXT || (_mesa_is_es3_color_renderable(internalformat) && _mesa_is_es3_texture_filterable(internalformat)); } @@ -144,6 +149,11 @@ _mesa_generate_texture_mipmap(struct gl_context *ctx, return; } + if (srcImage->Width == 0 || srcImage->Height == 0) { + _mesa_unlock_texture(ctx, texObj); + return; + } + if (target == GL_TEXTURE_CUBE_MAP) { GLuint face; for (face = 0; face < 6; face++) { diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 9f70749..7623b93 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -411,6 +411,14 @@ static const int extra_ARB_gpu_shader5_or_oes_geometry_shader[] = { static const int extra_ARB_gpu_shader5_or_OES_sample_variables[] = { EXT(ARB_gpu_shader5), EXT(OES_sample_variables), + EXTRA_END +}; + +static const int extra_KHR_robustness_or_GL[] = { + EXT(KHR_robustness), + EXTRA_API_GL, + EXTRA_API_GL_CORE, + EXTRA_END }; EXTRA_EXT(ARB_texture_cube_map); diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py index bfcbfd6..ea3649a 100644 --- a/src/mesa/main/get_hash_params.py +++ b/src/mesa/main/get_hash_params.py @@ -338,6 +338,9 @@ descriptor=[ # blend_func_extended [ "MAX_DUAL_SOURCE_DRAW_BUFFERS", "CONTEXT_INT(Const.MaxDualSourceDrawBuffers), extra_ARB_blend_func_extended" ], + +# GL_ARB_robustness / GL_KHR_robustness + [ "RESET_NOTIFICATION_STRATEGY_ARB", "CONTEXT_ENUM(Const.ResetStrategy), extra_KHR_robustness_or_GL" ], ]}, # GLES3 is not a typo. @@ -842,9 +845,6 @@ descriptor=[ # GL 3.2 [ "CONTEXT_PROFILE_MASK", "CONTEXT_INT(Const.ProfileMask), extra_version_32" ], -# GL_ARB_robustness - [ "RESET_NOTIFICATION_STRATEGY_ARB", "CONTEXT_ENUM(Const.ResetStrategy), NO_EXTRA" ], - # GL_ARB_timer_query [ "TIMESTAMP", "LOC_CUSTOM, TYPE_INT64, 0, extra_ARB_timer_query" ], diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c index 24ce7b0..6df09bb 100644 --- a/src/mesa/main/glformats.c +++ b/src/mesa/main/glformats.c @@ -907,6 +907,29 @@ _mesa_is_astc_format(GLenum internalFormat) } /** + * Test if the given format is an ETC2 format. + */ +GLboolean +_mesa_is_etc2_format(GLenum internalFormat) +{ + switch (internalFormat) { + case GL_COMPRESSED_RGB8_ETC2: + case GL_COMPRESSED_SRGB8_ETC2: + case GL_COMPRESSED_RGBA8_ETC2_EAC: + case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: + case GL_COMPRESSED_R11_EAC: + case GL_COMPRESSED_RG11_EAC: + case GL_COMPRESSED_SIGNED_R11_EAC: + case GL_COMPRESSED_SIGNED_RG11_EAC: + case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: + case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: + return true; + default: + return false; + } +} + +/** * Test if the given format is an integer (non-normalized) format. */ GLboolean @@ -2495,7 +2518,6 @@ _mesa_base_tex_format(const struct gl_context *ctx, GLint internalFormat) case GL_RGBA8I_EXT: case GL_RGBA16I_EXT: case GL_RGBA32I_EXT: - case GL_RGB10_A2UI: return GL_RGBA; case GL_RGB8UI_EXT: case GL_RGB16UI_EXT: @@ -2507,6 +2529,13 @@ _mesa_base_tex_format(const struct gl_context *ctx, GLint internalFormat) } } + if (ctx->Extensions.ARB_texture_rgb10_a2ui) { + switch (internalFormat) { + case GL_RGB10_A2UI: + return GL_RGBA; + } + } + if (ctx->Extensions.EXT_texture_integer) { switch (internalFormat) { case GL_ALPHA8UI_EXT: diff --git a/src/mesa/main/glformats.h b/src/mesa/main/glformats.h index c73f464..474ede2 100644 --- a/src/mesa/main/glformats.h +++ b/src/mesa/main/glformats.h @@ -61,6 +61,9 @@ extern GLboolean _mesa_is_astc_format(GLenum internalFormat); extern GLboolean +_mesa_is_etc2_format(GLenum internalFormat); + +extern GLboolean _mesa_is_type_unsigned(GLenum type); extern GLboolean diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 5956ce4..35ce0f2 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -1385,13 +1385,24 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg, static bool validate_io(struct gl_shader_program *producer, - struct gl_shader_program *consumer) + struct gl_shader_program *consumer, + gl_shader_stage producer_stage, + gl_shader_stage consumer_stage) { if (producer == consumer) return true; + const bool nonarray_stage_to_array_stage = + producer_stage != MESA_SHADER_TESS_CTRL && + (consumer_stage == MESA_SHADER_GEOMETRY || + consumer_stage == MESA_SHADER_TESS_CTRL || + consumer_stage == MESA_SHADER_TESS_EVAL); + bool valid = true; + void *name_buffer = NULL; + size_t name_buffer_size = 0; + gl_shader_variable const **outputs = (gl_shader_variable const **) calloc(producer->NumProgramResourceList, sizeof(gl_shader_variable *)); @@ -1463,11 +1474,52 @@ validate_io(struct gl_shader_program *producer, } } } else { + char *consumer_name = consumer_var->name; + + if (nonarray_stage_to_array_stage && + consumer_var->interface_type != NULL && + consumer_var->interface_type->is_array() && + !is_gl_identifier(consumer_var->name)) { + const size_t name_len = strlen(consumer_var->name); + + if (name_len >= name_buffer_size) { + free(name_buffer); + + name_buffer_size = name_len + 1; + name_buffer = malloc(name_buffer_size); + if (name_buffer == NULL) { + valid = false; + goto out; + } + } + + consumer_name = (char *) name_buffer; + + char *s = strchr(consumer_var->name, '['); + if (s == NULL) { + valid = false; + goto out; + } + + char *t = strchr(s, ']'); + if (t == NULL) { + valid = false; + goto out; + } + + assert(t[1] == '.' || t[1] == '['); + + const ptrdiff_t base_name_len = s - consumer_var->name; + + memcpy(consumer_name, consumer_var->name, base_name_len); + strcpy(consumer_name + base_name_len, t + 1); + } + for (unsigned j = 0; j < num_outputs; j++) { const gl_shader_variable *const var = outputs[j]; if (!var->explicit_location && - strcmp(consumer_var->name, var->name) == 0) { + strcmp(consumer_name, var->name) == 0) { producer_var = var; match_index = j; break; @@ -1529,25 +1581,53 @@ validate_io(struct gl_shader_program *producer, * Note that location mismatches are detected by the loops above that * find the producer variable that goes with the consumer variable. */ - if (producer_var->type != consumer_var->type || - producer_var->interpolation != consumer_var->interpolation || - producer_var->precision != consumer_var->precision) { + if (nonarray_stage_to_array_stage) { + if (!consumer_var->type->is_array() || + consumer_var->type->fields.array != producer_var->type) { + valid = false; + goto out; + } + + if (consumer_var->interface_type != NULL) { + if (!consumer_var->interface_type->is_array() || + consumer_var->interface_type->fields.array != producer_var->interface_type) { + valid = false; + goto out; + } + } else if (producer_var->interface_type != NULL) { + valid = false; + goto out; + } + } else { + if (producer_var->type != consumer_var->type) { + valid = false; + goto out; + } + + if (producer_var->interface_type != consumer_var->interface_type) { + valid = false; + goto out; + } + } + + if (producer_var->interpolation != consumer_var->interpolation) { valid = false; goto out; } - if (producer_var->outermost_struct_type != consumer_var->outermost_struct_type) { + if (producer_var->precision != consumer_var->precision) { valid = false; goto out; } - if (producer_var->interface_type != consumer_var->interface_type) { + if (producer_var->outermost_struct_type != consumer_var->outermost_struct_type) { valid = false; goto out; } } out: + free(name_buffer); free(outputs); return valid && num_outputs == 0; } @@ -1579,7 +1659,9 @@ _mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline) if (shProg[idx]->_LinkedShaders[idx]->Stage == MESA_SHADER_COMPUTE) break; - if (!validate_io(shProg[prev], shProg[idx])) + if (!validate_io(shProg[prev], shProg[idx], + shProg[prev]->_LinkedShaders[prev]->Stage, + shProg[idx]->_LinkedShaders[idx]->Stage)) return false; prev = idx; diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index fc3cc6b..3dde03f 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -502,13 +502,15 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, */ if (format == rgba_format) { rgba = dest; - } else if (rgba == NULL) { /* Allocate the RGBA buffer only once */ + } else { need_convert = true; - rgba = malloc(height * rgba_stride); - if (!rgba) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); - ctx->Driver.UnmapTextureImage(ctx, texImage, img); - return; + if (rgba == NULL) { /* Allocate the RGBA buffer only once */ + rgba = malloc(height * rgba_stride); + if (!rgba) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); + ctx->Driver.UnmapTextureImage(ctx, texImage, img); + return; + } } } diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 58b7f27..7b13a28 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1300,6 +1300,7 @@ bool _mesa_format_no_online_compression(const struct gl_context *ctx, GLenum format) { return _mesa_is_astc_format(format) || + _mesa_is_etc2_format(format) || compressedteximage_only_format(ctx, format); } @@ -2587,10 +2588,16 @@ check_rtt_cb(GLuint key, void *data, void *userData) att->Texture == texObj && att->TextureLevel == level && att->CubeMapFace == face) { - _mesa_update_texture_renderbuffer(ctx, ctx->DrawBuffer, att); + _mesa_update_texture_renderbuffer(ctx, fb, att); assert(att->Renderbuffer->TexImage); /* Mark fb status as indeterminate to force re-validation */ fb->_Status = 0; + + /* Make sure that the revalidation actually happens if this is + * being done to currently-bound buffers. + */ + if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer) + ctx->NewState |= _NEW_BUFFERS; } } } diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c index f4a0760..72ed869 100644 --- a/src/mesa/main/texstorage.c +++ b/src/mesa/main/texstorage.c @@ -179,9 +179,7 @@ clear_texture_fields(struct gl_context *ctx, return; } - _mesa_init_teximage_fields(ctx, texImage, - 0, 0, 0, 0, /* w, h, d, border */ - GL_NONE, MESA_FORMAT_NONE); + _mesa_clear_texture_image(ctx, texImage); } } } |