/** * Check if given blend destination factor is legal. * \return GL_TRUE if legal, GL_FALSE otherwise. */ static GLboolean legal_dst_factor(const struct gl_context *ctx, GLenum factor) { switch (factor) { case GL_DST_COLOR: case GL_ONE_MINUS_DST_COLOR: case GL_ZERO: case GL_ONE: case GL_SRC_COLOR: case GL_ONE_MINUS_SRC_COLOR: case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: case GL_DST_ALPHA: case GL_ONE_MINUS_DST_ALPHA: return GL_TRUE; case GL_CONSTANT_COLOR: case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: return _mesa_is_desktop_gl(ctx) || ctx->API == API_OPENGLES2; case GL_SRC_ALPHA_SATURATE: return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_blend_func_extended) || _mesa_is_gles3(ctx); case GL_SRC1_COLOR: case GL_SRC1_ALPHA: case GL_ONE_MINUS_SRC1_COLOR: case GL_ONE_MINUS_SRC1_ALPHA: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_blend_func_extended; default: return GL_FALSE; } }
void GLAPIENTRY _mesa_GetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label) { GET_CURRENT_CONTEXT(ctx); const char *callerstr; char **labelPtr; if (_mesa_is_desktop_gl(ctx)) callerstr = "glGetObjectLabel"; else callerstr = "glGetObjectLabelKHR"; if (bufSize < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize = %d)", callerstr, bufSize); return; } labelPtr = get_label_pointer(ctx, identifier, name, callerstr); if (!labelPtr) return; copy_label(*labelPtr, label, length, bufSize); }
void GLAPIENTRY _mesa_GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label) { GET_CURRENT_CONTEXT(ctx); struct gl_sync_object *const syncObj = (struct gl_sync_object *) ptr; const char *callerstr; char **labelPtr; if (_mesa_is_desktop_gl(ctx)) callerstr = "glGetObjectPtrLabel"; else callerstr = "glGetObjectPtrLabelKHR"; if (bufSize < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize = %d)", callerstr, bufSize); return; } if (!_mesa_validate_sync(ctx, syncObj)) { _mesa_error(ctx, GL_INVALID_VALUE, "%s (not a valid sync object)", callerstr); return; } labelPtr = &syncObj->Label; copy_label(*labelPtr, label, length, bufSize); }
/** * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(), * etc? The set of legal values depends on whether geometry shaders/programs * are supported. * Note: This may be called during display list compilation. */ bool _mesa_is_valid_prim_mode(struct gl_context *ctx, GLenum mode) { switch (mode) { case GL_POINTS: case GL_LINES: case GL_LINE_LOOP: case GL_LINE_STRIP: case GL_TRIANGLES: case GL_TRIANGLE_STRIP: case GL_TRIANGLE_FAN: return true; case GL_QUADS: case GL_QUAD_STRIP: case GL_POLYGON: return (ctx->API == API_OPENGL_COMPAT); case GL_LINES_ADJACENCY: case GL_LINE_STRIP_ADJACENCY: case GL_TRIANGLES_ADJACENCY: case GL_TRIANGLE_STRIP_ADJACENCY: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; default: return false; } }
static void setup_glsl_blit_framebuffer(struct gl_context *ctx, struct blit_state *blit, const struct gl_framebuffer *drawFb, struct gl_renderbuffer *src_rb, GLenum target, GLenum filter, bool is_scaled_blit, bool do_depth) { unsigned texcoord_size; bool is_target_multisample = target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY; bool is_filter_scaled_resolve = filter == GL_SCALED_RESOLVE_FASTEST_EXT || filter == GL_SCALED_RESOLVE_NICEST_EXT; /* target = GL_TEXTURE_RECTANGLE is not supported in GLES 3.0 */ assert(_mesa_is_desktop_gl(ctx) || target == GL_TEXTURE_2D); texcoord_size = 2 + (src_rb->Depth > 1 ? 1 : 0); _mesa_meta_setup_vertex_objects(ctx, &blit->VAO, &blit->buf_obj, true, 2, texcoord_size, 0); if (is_target_multisample && is_filter_scaled_resolve && is_scaled_blit) { setup_glsl_msaa_blit_scaled_shader(ctx, blit, src_rb, target, filter); } else if (is_target_multisample) { setup_glsl_msaa_blit_shader(ctx, blit, drawFb, src_rb, target); } else { _mesa_meta_setup_blit_shader(ctx, target, do_depth, do_depth ? &blit->shaders_with_depth : &blit->shaders_without_depth); } }
/** * Return whether an image format should be supported based on the current API * version of the context. */ static bool is_image_format_supported(const struct gl_context *ctx, GLenum format) { switch (format) { /* Formats supported on both desktop and ES GL, c.f. table 8.27 of the * OpenGL ES 3.1 specification. */ case GL_RGBA32F: case GL_RGBA16F: case GL_R32F: case GL_RGBA32UI: case GL_RGBA16UI: case GL_RGBA8UI: case GL_R32UI: case GL_RGBA32I: case GL_RGBA16I: case GL_RGBA8I: case GL_R32I: case GL_RGBA8: case GL_RGBA8_SNORM: return true; /* Formats supported on unextended desktop GL and the original * ARB_shader_image_load_store extension, c.f. table 3.21 of the OpenGL 4.2 * specification. */ case GL_RG32F: case GL_RG16F: case GL_R11F_G11F_B10F: case GL_R16F: case GL_RGB10_A2UI: case GL_RG32UI: case GL_RG16UI: case GL_RG8UI: case GL_R16UI: case GL_R8UI: case GL_RG32I: case GL_RG16I: case GL_RG8I: case GL_R16I: case GL_R8I: case GL_RGBA16: case GL_RGB10_A2: case GL_RG16: case GL_RG8: case GL_R16: case GL_R8: case GL_RGBA16_SNORM: case GL_RG16_SNORM: case GL_RG8_SNORM: case GL_R16_SNORM: case GL_R8_SNORM: return _mesa_is_desktop_gl(ctx); default: return false; } }
struct gl_image_unit _mesa_default_image_unit(struct gl_context *ctx) { const GLenum format = _mesa_is_desktop_gl(ctx) ? GL_R8 : GL_R32UI; const struct gl_image_unit u = { .Access = GL_READ_ONLY, .Format = format, ._ActualFormat = _mesa_get_shader_image_format(format) }; return u; }
/** * Initialize the dispatch table with the VBO functions for drawing. */ void vbo_initialize_exec_dispatch(const struct gl_context *ctx, struct _glapi_table *exec) { SET_DrawArrays(exec, vbo_exec_DrawArrays); SET_DrawElements(exec, vbo_exec_DrawElements); if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { SET_DrawRangeElements(exec, vbo_exec_DrawRangeElements); } SET_MultiDrawElementsEXT(exec, vbo_exec_MultiDrawElements); if (ctx->API == API_OPENGL_COMPAT) { SET_Rectf(exec, vbo_exec_Rectf); SET_EvalMesh1(exec, vbo_exec_EvalMesh1); SET_EvalMesh2(exec, vbo_exec_EvalMesh2); } if (_mesa_is_desktop_gl(ctx)) { SET_DrawElementsBaseVertex(exec, vbo_exec_DrawElementsBaseVertex); SET_DrawRangeElementsBaseVertex(exec, vbo_exec_DrawRangeElementsBaseVertex); SET_MultiDrawElementsBaseVertex(exec, vbo_exec_MultiDrawElementsBaseVertex); SET_DrawArraysInstancedBaseInstance(exec, vbo_exec_DrawArraysInstancedBaseInstance); SET_DrawElementsInstancedBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseInstance); SET_DrawElementsInstancedBaseVertex(exec, vbo_exec_DrawElementsInstancedBaseVertex); SET_DrawElementsInstancedBaseVertexBaseInstance(exec, vbo_exec_DrawElementsInstancedBaseVertexBaseInstance); } if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { SET_DrawArraysInstancedARB(exec, vbo_exec_DrawArraysInstanced); SET_DrawElementsInstancedARB(exec, vbo_exec_DrawElementsInstanced); } if (_mesa_is_desktop_gl(ctx)) { SET_DrawTransformFeedback(exec, vbo_exec_DrawTransformFeedback); SET_DrawTransformFeedbackStream(exec, vbo_exec_DrawTransformFeedbackStream); SET_DrawTransformFeedbackInstanced(exec, vbo_exec_DrawTransformFeedbackInstanced); SET_DrawTransformFeedbackStreamInstanced(exec, vbo_exec_DrawTransformFeedbackStreamInstanced); } }
/** * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D * into the corresponding Mesa texture target index. * Note that proxy targets are not valid here. * \return TEXTURE_x_INDEX or -1 if target is invalid */ static GLint target_enum_to_index(struct gl_context *ctx, GLenum target) { switch (target) { case GL_TEXTURE_1D: return _mesa_is_desktop_gl(ctx) ? TEXTURE_1D_INDEX : -1; case GL_TEXTURE_2D: return TEXTURE_2D_INDEX; case GL_TEXTURE_3D: return TEXTURE_3D_INDEX; case GL_TEXTURE_CUBE_MAP_ARB: return ctx->Extensions.ARB_texture_cube_map ? TEXTURE_CUBE_INDEX : -1; case GL_TEXTURE_RECTANGLE_NV: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle ? TEXTURE_RECT_INDEX : -1; case GL_TEXTURE_1D_ARRAY_EXT: return _mesa_is_desktop_gl(ctx) && (ctx->Extensions.EXT_texture_array || ctx->Extensions.MESA_texture_array) ? TEXTURE_1D_ARRAY_INDEX : -1; case GL_TEXTURE_2D_ARRAY_EXT: return (_mesa_is_desktop_gl(ctx) && (ctx->Extensions.EXT_texture_array || ctx->Extensions.MESA_texture_array)) || _mesa_is_gles3(ctx) ? TEXTURE_2D_ARRAY_INDEX : -1; case GL_TEXTURE_BUFFER_ARB: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_buffer_object ? TEXTURE_BUFFER_INDEX : -1; case GL_TEXTURE_EXTERNAL_OES: return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external ? TEXTURE_EXTERNAL_INDEX : -1; case GL_TEXTURE_CUBE_MAP_ARRAY: return TEXTURE_CUBE_ARRAY_INDEX; default: return -1; } }
/** * Confirm that the a shader type is valid and supported by the implementation * * \param ctx Current GL context * \param type Shader target * */ static bool validate_shader_target(const struct gl_context *ctx, GLenum type) { switch (type) { case GL_FRAGMENT_SHADER: return ctx->Extensions.ARB_fragment_shader; case GL_VERTEX_SHADER: return ctx->Extensions.ARB_vertex_shader; case GL_GEOMETRY_SHADER_ARB: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; default: return false; } }
/** * Called via glMinSampleShadingARB */ void GLAPIENTRY _mesa_MinSampleShading(GLclampf value) { GET_CURRENT_CONTEXT(ctx); if (!ctx->Extensions.ARB_sample_shading || !_mesa_is_desktop_gl(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMinSampleShading"); return; } FLUSH_VERTICES(ctx, 0); ctx->Multisample.MinSampleShadingValue = CLAMP(value, 0.0, 1.0); ctx->NewState |= _NEW_MULTISAMPLE; }
static GLuint set_sampler_cube_map_seamless(struct gl_context *ctx, struct gl_sampler_object *samp, GLboolean param) { if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.AMD_seamless_cubemap_per_texture) return INVALID_PNAME; if (samp->CubeMapSeamless == param) return GL_FALSE; if (param != GL_TRUE && param != GL_FALSE) return INVALID_VALUE; flush(ctx); samp->CubeMapSeamless = param; return GL_TRUE; }
void GLAPIENTRY _mesa_ObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) { GET_CURRENT_CONTEXT(ctx); const char *callerstr; char **labelPtr; if (_mesa_is_desktop_gl(ctx)) callerstr = "glObjectLabel"; else callerstr = "glObjectLabelKHR"; labelPtr = get_label_pointer(ctx, identifier, name, callerstr); if (!labelPtr) return; set_label(ctx, labelPtr, label, length, callerstr); }
/** * Fixes up the context for GLES23 with our default-to-sRGB-capable behavior * on window system framebuffers. * * Desktop GL is fairly reasonable in its handling of sRGB: You can ask if * your renderbuffer can do sRGB encode, and you can flip a switch that does * sRGB encode if the renderbuffer can handle it. You can ask specifically * for a visual where you're guaranteed to be capable, but it turns out that * everyone just makes all their ARGB8888 visuals capable and doesn't offer * incapable ones, becuase there's no difference between the two in resources * used. Applications thus get built that accidentally rely on the default * visual choice being sRGB, so we make ours sRGB capable. Everything sounds * great... * * But for GLES2/3, they decided that it was silly to not turn on sRGB encode * for sRGB renderbuffers you made with the GL_EXT_texture_sRGB equivalent. * So they removed the enable knob and made it "if the renderbuffer is sRGB * capable, do sRGB encode". Then, for your window system renderbuffers, you * can ask for sRGB visuals and get sRGB encode, or not ask for sRGB visuals * and get no sRGB encode (assuming that both kinds of visual are available). * Thus our choice to support sRGB by default on our visuals for desktop would * result in broken rendering of GLES apps that aren't expecting sRGB encode. * * Unfortunately, renderbuffer setup happens before a context is created. So * in intel_screen.c we always set up sRGB, and here, if you're a GLES2/3 * context (without an sRGB visual, though we don't have sRGB visuals exposed * yet), we go turn that back off before anyone finds out. */ static void intel_gles3_srgb_workaround(struct brw_context *brw, struct gl_framebuffer *fb) { struct gl_context *ctx = &brw->ctx; if (_mesa_is_desktop_gl(ctx) || !fb->Visual.sRGBCapable) return; /* Some day when we support the sRGB capable bit on visuals available for * GLES, we'll need to respect that and not disable things here. */ fb->Visual.sRGBCapable = false; for (int i = 0; i < BUFFER_COUNT; i++) { if (fb->Attachment[i].Renderbuffer && fb->Attachment[i].Renderbuffer->Format == MESA_FORMAT_SARGB8) { fb->Attachment[i].Renderbuffer->Format = MESA_FORMAT_ARGB8888; } } }
static void setup_glsl_blit_framebuffer(struct gl_context *ctx, struct blit_state *blit, struct gl_renderbuffer *src_rb, GLenum target) { unsigned texcoord_size; /* target = GL_TEXTURE_RECTANGLE is not supported in GLES 3.0 */ assert(_mesa_is_desktop_gl(ctx) || target == GL_TEXTURE_2D); texcoord_size = 2 + (src_rb->Depth > 1 ? 1 : 0); _mesa_meta_setup_vertex_objects(&blit->VAO, &blit->VBO, true, 2, texcoord_size, 0); if (target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { setup_glsl_msaa_blit_shader(ctx, blit, src_rb, target); } else { _mesa_meta_setup_blit_shader(ctx, target, &blit->shaders); } }
/** Convert GL datatype enum into a <type>_BIT value seen above */ static GLbitfield type_to_bit(const struct gl_context *ctx, GLenum type) { switch (type) { case GL_BOOL: return BOOL_BIT; case GL_BYTE: return BYTE_BIT; case GL_UNSIGNED_BYTE: return UNSIGNED_BYTE_BIT; case GL_SHORT: return SHORT_BIT; case GL_UNSIGNED_SHORT: return UNSIGNED_SHORT_BIT; case GL_INT: return INT_BIT; case GL_UNSIGNED_INT: return UNSIGNED_INT_BIT; case GL_HALF_FLOAT: if (ctx->Extensions.ARB_half_float_vertex) return HALF_BIT; else return 0x0; case GL_FLOAT: return FLOAT_BIT; case GL_DOUBLE: return DOUBLE_BIT; case GL_FIXED: return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT; case GL_UNSIGNED_INT_2_10_10_10_REV: return UNSIGNED_INT_2_10_10_10_REV_BIT; case GL_INT_2_10_10_10_REV: return INT_2_10_10_10_REV_BIT; default: return 0; } }
/** * glGetProgramiv() - get shader program state. * Note that this is for GLSL shader programs, not ARB vertex/fragment * programs (see glGetProgramivARB). */ static void get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params) { struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); /* Is transform feedback available in this context? */ const bool has_xfb = (ctx->API == API_OPENGL && ctx->Extensions.EXT_transform_feedback) || ctx->API == API_OPENGL_CORE || _mesa_is_gles3(ctx); /* Are geometry shaders available in this context? */ const bool has_gs = _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; /* Are uniform buffer objects available in this context? */ const bool has_ubo = (ctx->API == API_OPENGL && ctx->Extensions.ARB_uniform_buffer_object) || ctx->API == API_OPENGL_CORE || _mesa_is_gles3(ctx); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); return; } switch (pname) { case GL_DELETE_STATUS: *params = shProg->DeletePending; return; case GL_LINK_STATUS: *params = shProg->LinkStatus; return; case GL_VALIDATE_STATUS: *params = shProg->Validated; return; case GL_INFO_LOG_LENGTH: *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0; return; case GL_ATTACHED_SHADERS: *params = shProg->NumShaders; return; case GL_ACTIVE_ATTRIBUTES: *params = _mesa_count_active_attribs(shProg); return; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: *params = _mesa_longest_attribute_name_length(shProg); return; case GL_ACTIVE_UNIFORMS: *params = shProg->NumUserUniformStorage; return; case GL_ACTIVE_UNIFORM_MAX_LENGTH: { unsigned i; GLint max_len = 0; for (i = 0; i < shProg->NumUserUniformStorage; i++) { /* Add one for the terminating NUL character. */ const GLint len = strlen(shProg->UniformStorage[i].name) + 1; if (len > max_len) max_len = len; } *params = max_len; return; } case GL_TRANSFORM_FEEDBACK_VARYINGS: if (!has_xfb) break; *params = shProg->TransformFeedback.NumVarying; return; case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: if (!has_xfb) break; *params = longest_feedback_varying_name(shProg) + 1; return; case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: if (!has_xfb) break; *params = shProg->TransformFeedback.BufferMode; return; case GL_GEOMETRY_VERTICES_OUT_ARB: if (!has_gs) break; *params = shProg->Geom.VerticesOut; return; case GL_GEOMETRY_INPUT_TYPE_ARB: if (!has_gs) break; *params = shProg->Geom.InputType; return; case GL_GEOMETRY_OUTPUT_TYPE_ARB: if (!has_gs) break; *params = shProg->Geom.OutputType; return; case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: { unsigned i; GLint max_len = 0; if (!has_ubo) break; for (i = 0; i < shProg->NumUniformBlocks; i++) { /* Add one for the terminating NUL character. */ const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1; if (len > max_len) max_len = len; } *params = max_len; return; } case GL_ACTIVE_UNIFORM_BLOCKS: if (!has_ubo) break; *params = shProg->NumUniformBlocks; return; default: break; } _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)", _mesa_lookup_enum_by_nr(pname)); }
/** * Install per-vertex functions into the API dispatch table for display * list compilation. */ void _mesa_install_save_vtxfmt(struct gl_context *ctx, const GLvertexformat *vfmt) { if (_mesa_is_desktop_gl(ctx)) install_vtxfmt( ctx, ctx->Save, vfmt ); }
/** * Called via glUniform*() functions. */ extern "C" void _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, GLint location, GLsizei count, const GLvoid *values, enum glsl_base_type basicType, unsigned src_components) { unsigned offset; int size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1; struct gl_uniform_storage *const uni = validate_uniform_parameters(ctx, shProg, location, count, &offset, "glUniform"); if (uni == NULL) return; if (uni->type->is_matrix()) { /* Can't set matrix uniforms (like mat4) with glUniform */ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform%u(uniform \"%s\"@%d is matrix)", src_components, uni->name, location); return; } /* Verify that the types are compatible. */ const unsigned components = uni->type->is_sampler() ? 1 : uni->type->vector_elements; if (components != src_components) { /* glUniformN() must match float/vecN type */ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform%u(\"%s\"@%u has %u components, not %u)", src_components, uni->name, location, components, src_components); return; } bool match; switch (uni->type->base_type) { case GLSL_TYPE_BOOL: match = (basicType != GLSL_TYPE_DOUBLE); break; case GLSL_TYPE_SAMPLER: match = (basicType == GLSL_TYPE_INT); break; case GLSL_TYPE_IMAGE: match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx)); break; default: match = (basicType == uni->type->base_type); break; } if (!match) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform%u(\"%s\"@%d is %s, not %s)", src_components, uni->name, location, glsl_type_name(uni->type->base_type), glsl_type_name(basicType)); return; } if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) { log_uniform(values, basicType, components, 1, count, false, shProg, location, uni); } /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says: * * "Setting a sampler's value to i selects texture image unit number * i. The values of i range from zero to the implementation- dependent * maximum supported number of texture image units." * * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of * the PDF) says: * * "Error Description Offending command * ignored? * ... * INVALID_VALUE Numeric argument out of range Yes" * * Based on that, when an invalid sampler is specified, we generate a * GL_INVALID_VALUE error and ignore the command. */ if (uni->type->is_sampler()) { for (int i = 0; i < count; i++) { const unsigned texUnit = ((unsigned *) values)[i]; /* check that the sampler (tex unit index) is legal */ if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) { _mesa_error(ctx, GL_INVALID_VALUE, "glUniform1i(invalid sampler/tex unit index for " "uniform %d)", location); return; } } } if (uni->type->is_image()) { for (int i = 0; i < count; i++) { const int unit = ((GLint *) values)[i]; /* check that the image unit is legal */ if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) { _mesa_error(ctx, GL_INVALID_VALUE, "glUniform1i(invalid image unit index for uniform %d)", location); return; } } } /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: * * "When loading N elements starting at an arbitrary position k in a * uniform declared as an array, elements k through k + N - 1 in the * array will be replaced with the new values. Values for any array * element that exceeds the highest array element index used, as * reported by GetActiveUniform, will be ignored by the GL." * * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 * will have already generated an error. */ if (uni->array_elements != 0) { count = MIN2(count, (int) (uni->array_elements - offset)); } FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); /* Store the data in the "actual type" backing storage for the uniform. */ if (!uni->type->is_boolean()) { memcpy(&uni->storage[size_mul * components * offset], values, sizeof(uni->storage[0]) * components * count * size_mul); } else { const union gl_constant_value *src = (const union gl_constant_value *) values; union gl_constant_value *dst = &uni->storage[components * offset]; const unsigned elems = components * count; for (unsigned i = 0; i < elems; i++) { if (basicType == GLSL_TYPE_FLOAT) { dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0; } else { dst[i].i = src[i].i != 0 ? ctx->Const.UniformBooleanTrue : 0; } } } uni->initialized = true; _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); /* If the uniform is a sampler, do the extra magic necessary to propagate * the changes through. */ if (uni->type->is_sampler()) { bool flushed = false; for (int i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_shader *const sh = shProg->_LinkedShaders[i]; /* If the shader stage doesn't use the sampler uniform, skip this. */ if (sh == NULL || !uni->sampler[i].active) continue; for (int j = 0; j < count; j++) { sh->SamplerUnits[uni->sampler[i].index + offset + j] = ((unsigned *) values)[j]; } struct gl_program *const prog = sh->Program; assert(sizeof(prog->SamplerUnits) == sizeof(sh->SamplerUnits)); /* Determine if any of the samplers used by this shader stage have * been modified. */ bool changed = false; for (unsigned j = 0; j < ARRAY_SIZE(prog->SamplerUnits); j++) { if ((sh->active_samplers & (1U << j)) != 0 && (prog->SamplerUnits[j] != sh->SamplerUnits[j])) { changed = true; break; } } if (changed) { if (!flushed) { FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM); flushed = true; } memcpy(prog->SamplerUnits, sh->SamplerUnits, sizeof(sh->SamplerUnits)); _mesa_update_shader_textures_used(shProg, prog); if (ctx->Driver.SamplerUniformChange) ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog); } } } /* If the uniform is an image, update the mapping from image * uniforms to image units present in the shader data structure. */ if (uni->type->is_image()) { for (int i = 0; i < MESA_SHADER_STAGES; i++) { if (uni->image[i].active) { struct gl_shader *sh = shProg->_LinkedShaders[i]; for (int j = 0; j < count; j++) sh->ImageUnits[uni->image[i].index + offset + j] = ((GLint *) values)[j]; } } ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; } }
/** * Check if the given texture target is a legal texture object target * for a glTexStorage() command. * This is a bit different than legal_teximage_target() when it comes * to cube maps. */ static bool legal_texobj_target(const struct gl_context *ctx, GLuint dims, GLenum target) { if (dims < 1 || dims > 3) { _mesa_problem(ctx, "invalid dims=%u in legal_texobj_target()", dims); return false; } switch (dims) { case 2: switch (target) { case GL_TEXTURE_2D: return true; case GL_TEXTURE_CUBE_MAP: return ctx->Extensions.ARB_texture_cube_map; } break; case 3: switch (target) { case GL_TEXTURE_3D: return true; case GL_TEXTURE_2D_ARRAY: return ctx->Extensions.EXT_texture_array; case GL_TEXTURE_CUBE_MAP_ARRAY: return _mesa_has_texture_cube_map_array(ctx); } break; } if (!_mesa_is_desktop_gl(ctx)) return false; switch (dims) { case 1: switch (target) { case GL_TEXTURE_1D: case GL_PROXY_TEXTURE_1D: return true; default: return false; } case 2: switch (target) { case GL_PROXY_TEXTURE_2D: return true; case GL_PROXY_TEXTURE_CUBE_MAP: return ctx->Extensions.ARB_texture_cube_map; case GL_TEXTURE_RECTANGLE: case GL_PROXY_TEXTURE_RECTANGLE: return ctx->Extensions.NV_texture_rectangle; case GL_TEXTURE_1D_ARRAY: case GL_PROXY_TEXTURE_1D_ARRAY: return ctx->Extensions.EXT_texture_array; default: return false; } case 3: switch (target) { case GL_PROXY_TEXTURE_3D: return true; case GL_PROXY_TEXTURE_2D_ARRAY: return ctx->Extensions.EXT_texture_array; case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: return ctx->Extensions.ARB_texture_cube_map_array; default: return false; } default: unreachable("impossible dimensions"); } }
/** * Use the per-vertex functions found in <vfmt> to initialize the given * API dispatch table. */ static void install_vtxfmt(struct gl_context *ctx, struct _glapi_table *tab, const GLvertexformat *vfmt) { assert(ctx->Version > 0); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_Color4f(tab, vfmt->Color4f); } if (ctx->API == API_OPENGL_COMPAT) { _mesa_install_arrayelt_vtxfmt(tab, vfmt); SET_Color3f(tab, vfmt->Color3f); SET_Color3fv(tab, vfmt->Color3fv); SET_Color4fv(tab, vfmt->Color4fv); SET_EdgeFlag(tab, vfmt->EdgeFlag); } if (ctx->API == API_OPENGL_COMPAT) { _mesa_install_eval_vtxfmt(tab, vfmt); } if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_Materialfv(tab, vfmt->Materialfv); SET_MultiTexCoord4fARB(tab, vfmt->MultiTexCoord4fARB); SET_Normal3f(tab, vfmt->Normal3f); } if (ctx->API == API_OPENGL_COMPAT) { SET_FogCoordfEXT(tab, vfmt->FogCoordfEXT); SET_FogCoordfvEXT(tab, vfmt->FogCoordfvEXT); SET_Indexf(tab, vfmt->Indexf); SET_Indexfv(tab, vfmt->Indexfv); SET_MultiTexCoord1fARB(tab, vfmt->MultiTexCoord1fARB); SET_MultiTexCoord1fvARB(tab, vfmt->MultiTexCoord1fvARB); SET_MultiTexCoord2fARB(tab, vfmt->MultiTexCoord2fARB); SET_MultiTexCoord2fvARB(tab, vfmt->MultiTexCoord2fvARB); SET_MultiTexCoord3fARB(tab, vfmt->MultiTexCoord3fARB); SET_MultiTexCoord3fvARB(tab, vfmt->MultiTexCoord3fvARB); SET_MultiTexCoord4fvARB(tab, vfmt->MultiTexCoord4fvARB); SET_Normal3fv(tab, vfmt->Normal3fv); } if (ctx->API == API_OPENGL_COMPAT) { SET_SecondaryColor3fEXT(tab, vfmt->SecondaryColor3fEXT); SET_SecondaryColor3fvEXT(tab, vfmt->SecondaryColor3fvEXT); SET_TexCoord1f(tab, vfmt->TexCoord1f); SET_TexCoord1fv(tab, vfmt->TexCoord1fv); SET_TexCoord2f(tab, vfmt->TexCoord2f); SET_TexCoord2fv(tab, vfmt->TexCoord2fv); SET_TexCoord3f(tab, vfmt->TexCoord3f); SET_TexCoord3fv(tab, vfmt->TexCoord3fv); SET_TexCoord4f(tab, vfmt->TexCoord4f); SET_TexCoord4fv(tab, vfmt->TexCoord4fv); SET_Vertex2f(tab, vfmt->Vertex2f); SET_Vertex2fv(tab, vfmt->Vertex2fv); SET_Vertex3f(tab, vfmt->Vertex3f); SET_Vertex3fv(tab, vfmt->Vertex3fv); SET_Vertex4f(tab, vfmt->Vertex4f); SET_Vertex4fv(tab, vfmt->Vertex4fv); } if (ctx->API == API_OPENGL_COMPAT) { _mesa_install_dlist_vtxfmt(tab, vfmt); /* glCallList / glCallLists */ SET_Begin(tab, vfmt->Begin); SET_End(tab, vfmt->End); SET_PrimitiveRestartNV(tab, vfmt->PrimitiveRestartNV); SET_Rectf(tab, vfmt->Rectf); } SET_DrawArrays(tab, vfmt->DrawArrays); SET_DrawElements(tab, vfmt->DrawElements); if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { SET_DrawRangeElements(tab, vfmt->DrawRangeElements); } SET_MultiDrawElementsEXT(tab, vfmt->MultiDrawElementsEXT); if (_mesa_is_desktop_gl(ctx)) { SET_DrawElementsBaseVertex(tab, vfmt->DrawElementsBaseVertex); SET_DrawRangeElementsBaseVertex(tab, vfmt->DrawRangeElementsBaseVertex); SET_MultiDrawElementsBaseVertex(tab, vfmt->MultiDrawElementsBaseVertex); SET_DrawArraysInstancedBaseInstance(tab, vfmt->DrawArraysInstancedBaseInstance); SET_DrawElementsInstancedBaseInstance(tab, vfmt->DrawElementsInstancedBaseInstance); SET_DrawElementsInstancedBaseVertex(tab, vfmt->DrawElementsInstancedBaseVertex); SET_DrawElementsInstancedBaseVertexBaseInstance(tab, vfmt->DrawElementsInstancedBaseVertexBaseInstance); } if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { SET_DrawArraysInstancedARB(tab, vfmt->DrawArraysInstanced); SET_DrawElementsInstancedARB(tab, vfmt->DrawElementsInstanced); } if (_mesa_is_desktop_gl(ctx)) { SET_DrawTransformFeedback(tab, vfmt->DrawTransformFeedback); SET_DrawTransformFeedbackStream(tab, vfmt->DrawTransformFeedbackStream); SET_DrawTransformFeedbackInstanced(tab, vfmt->DrawTransformFeedbackInstanced); SET_DrawTransformFeedbackStreamInstanced(tab, vfmt->DrawTransformFeedbackStreamInstanced); } /* Originally for GL_NV_vertex_program, this is also used by dlist.c */ if (ctx->API == API_OPENGL_COMPAT) { SET_VertexAttrib1fNV(tab, vfmt->VertexAttrib1fNV); SET_VertexAttrib1fvNV(tab, vfmt->VertexAttrib1fvNV); SET_VertexAttrib2fNV(tab, vfmt->VertexAttrib2fNV); SET_VertexAttrib2fvNV(tab, vfmt->VertexAttrib2fvNV); SET_VertexAttrib3fNV(tab, vfmt->VertexAttrib3fNV); SET_VertexAttrib3fvNV(tab, vfmt->VertexAttrib3fvNV); SET_VertexAttrib4fNV(tab, vfmt->VertexAttrib4fNV); SET_VertexAttrib4fvNV(tab, vfmt->VertexAttrib4fvNV); } if (ctx->API != API_OPENGLES) { SET_VertexAttrib1fARB(tab, vfmt->VertexAttrib1fARB); SET_VertexAttrib1fvARB(tab, vfmt->VertexAttrib1fvARB); SET_VertexAttrib2fARB(tab, vfmt->VertexAttrib2fARB); SET_VertexAttrib2fvARB(tab, vfmt->VertexAttrib2fvARB); SET_VertexAttrib3fARB(tab, vfmt->VertexAttrib3fARB); SET_VertexAttrib3fvARB(tab, vfmt->VertexAttrib3fvARB); SET_VertexAttrib4fARB(tab, vfmt->VertexAttrib4fARB); SET_VertexAttrib4fvARB(tab, vfmt->VertexAttrib4fvARB); } /* GL_EXT_gpu_shader4 / OpenGL 3.0 */ if (_mesa_is_desktop_gl(ctx)) { SET_VertexAttribI1iEXT(tab, vfmt->VertexAttribI1i); SET_VertexAttribI2iEXT(tab, vfmt->VertexAttribI2i); SET_VertexAttribI3iEXT(tab, vfmt->VertexAttribI3i); SET_VertexAttribI2ivEXT(tab, vfmt->VertexAttribI2iv); SET_VertexAttribI3ivEXT(tab, vfmt->VertexAttribI3iv); SET_VertexAttribI1uiEXT(tab, vfmt->VertexAttribI1ui); SET_VertexAttribI2uiEXT(tab, vfmt->VertexAttribI2ui); SET_VertexAttribI3uiEXT(tab, vfmt->VertexAttribI3ui); SET_VertexAttribI2uivEXT(tab, vfmt->VertexAttribI2uiv); SET_VertexAttribI3uivEXT(tab, vfmt->VertexAttribI3uiv); } if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { SET_VertexAttribI4iEXT(tab, vfmt->VertexAttribI4i); SET_VertexAttribI4ivEXT(tab, vfmt->VertexAttribI4iv); SET_VertexAttribI4uiEXT(tab, vfmt->VertexAttribI4ui); SET_VertexAttribI4uivEXT(tab, vfmt->VertexAttribI4uiv); } if (ctx->API == API_OPENGL_COMPAT) { /* GL_ARB_vertex_type_10_10_10_2_rev / GL 3.3 */ SET_VertexP2ui(tab, vfmt->VertexP2ui); SET_VertexP2uiv(tab, vfmt->VertexP2uiv); SET_VertexP3ui(tab, vfmt->VertexP3ui); SET_VertexP3uiv(tab, vfmt->VertexP3uiv); SET_VertexP4ui(tab, vfmt->VertexP4ui); SET_VertexP4uiv(tab, vfmt->VertexP4uiv); SET_TexCoordP1ui(tab, vfmt->TexCoordP1ui); SET_TexCoordP1uiv(tab, vfmt->TexCoordP1uiv); SET_TexCoordP2ui(tab, vfmt->TexCoordP2ui); SET_TexCoordP2uiv(tab, vfmt->TexCoordP2uiv); SET_TexCoordP3ui(tab, vfmt->TexCoordP3ui); SET_TexCoordP3uiv(tab, vfmt->TexCoordP3uiv); SET_TexCoordP4ui(tab, vfmt->TexCoordP4ui); SET_TexCoordP4uiv(tab, vfmt->TexCoordP4uiv); SET_MultiTexCoordP1ui(tab, vfmt->MultiTexCoordP1ui); SET_MultiTexCoordP2ui(tab, vfmt->MultiTexCoordP2ui); SET_MultiTexCoordP3ui(tab, vfmt->MultiTexCoordP3ui); SET_MultiTexCoordP4ui(tab, vfmt->MultiTexCoordP4ui); SET_MultiTexCoordP1uiv(tab, vfmt->MultiTexCoordP1uiv); SET_MultiTexCoordP2uiv(tab, vfmt->MultiTexCoordP2uiv); SET_MultiTexCoordP3uiv(tab, vfmt->MultiTexCoordP3uiv); SET_MultiTexCoordP4uiv(tab, vfmt->MultiTexCoordP4uiv); SET_NormalP3ui(tab, vfmt->NormalP3ui); SET_NormalP3uiv(tab, vfmt->NormalP3uiv); SET_ColorP3ui(tab, vfmt->ColorP3ui); SET_ColorP4ui(tab, vfmt->ColorP4ui); SET_ColorP3uiv(tab, vfmt->ColorP3uiv); SET_ColorP4uiv(tab, vfmt->ColorP4uiv); SET_SecondaryColorP3ui(tab, vfmt->SecondaryColorP3ui); SET_SecondaryColorP3uiv(tab, vfmt->SecondaryColorP3uiv); } if (_mesa_is_desktop_gl(ctx)) { SET_VertexAttribP1ui(tab, vfmt->VertexAttribP1ui); SET_VertexAttribP2ui(tab, vfmt->VertexAttribP2ui); SET_VertexAttribP3ui(tab, vfmt->VertexAttribP3ui); SET_VertexAttribP4ui(tab, vfmt->VertexAttribP4ui); SET_VertexAttribP1uiv(tab, vfmt->VertexAttribP1uiv); SET_VertexAttribP2uiv(tab, vfmt->VertexAttribP2uiv); SET_VertexAttribP3uiv(tab, vfmt->VertexAttribP3uiv); SET_VertexAttribP4uiv(tab, vfmt->VertexAttribP4uiv); } }
/** * Create a framebuffer from a manager interface. */ static struct st_framebuffer * st_framebuffer_create(struct st_context *st, struct st_framebuffer_iface *stfbi) { struct st_framebuffer *stfb; struct gl_config mode; gl_buffer_index idx; if (!stfbi) return NULL; stfb = CALLOC_STRUCT(st_framebuffer); if (!stfb) return NULL; st_visual_to_context_mode(stfbi->visual, &mode); /* * For desktop GL, sRGB framebuffer write is controlled by both the * capability of the framebuffer and GL_FRAMEBUFFER_SRGB. We should * advertise the capability when the pipe driver (and core Mesa) supports * it so that applications can enable sRGB write when they want to. * * This is not to be confused with GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB. When * the attribute is GLX_TRUE, it tells the st manager to pick a color * format such that util_format_srgb(visual->color_format) can be supported * by the pipe driver. We still need to advertise the capability here. * * For GLES, however, sRGB framebuffer write is controlled only by the * capability of the framebuffer. There is GL_EXT_sRGB_write_control to * give applications the control back, but sRGB write is still enabled by * default. To avoid unexpected results, we should not advertise the * capability. This could change when we add support for * EGL_KHR_gl_colorspace. */ if (_mesa_is_desktop_gl(st->ctx)) { struct pipe_screen *screen = st->pipe->screen; const enum pipe_format srgb_format = util_format_srgb(stfbi->visual->color_format); if (srgb_format != PIPE_FORMAT_NONE && st_pipe_format_to_mesa_format(srgb_format) != MESA_FORMAT_NONE && screen->is_format_supported(screen, srgb_format, PIPE_TEXTURE_2D, stfbi->visual->samples, PIPE_BIND_RENDER_TARGET)) mode.sRGBCapable = GL_TRUE; } _mesa_initialize_window_framebuffer(&stfb->Base, &mode); stfb->iface = stfbi; stfb->iface_stamp = p_atomic_read(&stfbi->stamp) - 1; /* add the color buffer */ idx = stfb->Base._ColorDrawBufferIndexes[0]; if (!st_framebuffer_add_renderbuffer(stfb, idx)) { free(stfb); return NULL; } st_framebuffer_add_renderbuffer(stfb, BUFFER_DEPTH); st_framebuffer_add_renderbuffer(stfb, BUFFER_ACCUM); stfb->stamp = 0; st_framebuffer_update_attachments(stfb); return stfb; }
void GLAPIENTRY _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) { GLint buffer[16]; GLsizei count = 0; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (!ctx->Extensions.ARB_internalformat_query) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ"); return; } assert(ctx->Driver.QuerySamplesForFormat != NULL); /* The ARB_internalformat_query spec says: * * "If the <target> parameter to GetInternalformativ is not one of * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY or RENDERBUFFER * then an INVALID_ENUM error is generated." */ switch (target) { case GL_RENDERBUFFER: break; case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: /* These enums are only valid if ARB_texture_multisample is supported */ if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample) break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(target=%s)", _mesa_lookup_enum_by_nr(target)); return; } /* The ARB_internalformat_query spec says: * * "If the <internalformat> parameter to GetInternalformativ is not * color-, depth- or stencil-renderable, then an INVALID_ENUM error is * generated." * * Page 243 of the GLES 3.0.4 spec says this for GetInternalformativ: * * "internalformat must be color-renderable, depth-renderable or * stencilrenderable (as defined in section 4.4.4)." * * Section 4.4.4 on page 212 of the same spec says: * * "An internal format is color-renderable if it is one of the * formats from table 3.13 noted as color-renderable or if it * is unsized format RGBA or RGB." * * Therefore, we must accept GL_RGB and GL_RGBA here. */ if (internalformat != GL_RGB && internalformat != GL_RGBA && _mesa_base_fbo_format(ctx, internalformat) == 0) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(internalformat=%s)", _mesa_lookup_enum_by_nr(internalformat)); return; } /* The ARB_internalformat_query spec says: * * "If the <bufSize> parameter to GetInternalformativ is negative, then * an INVALID_VALUE error is generated." */ if (bufSize < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetInternalformativ(target=%s)", _mesa_lookup_enum_by_nr(target)); return; } switch (pname) { case GL_SAMPLES: count = ctx->Driver.QuerySamplesForFormat(ctx, target, internalformat, buffer); break; case GL_NUM_SAMPLE_COUNTS: { if (_mesa_is_gles3(ctx) && _mesa_is_enum_format_integer(internalformat)) { /* From GL ES 3.0 specification, section 6.1.15 page 236: "Since * multisampling is not supported for signed and unsigned integer * internal formats, the value of NUM_SAMPLE_COUNTS will be zero * for such formats. */ buffer[0] = 0; count = 1; } else { size_t num_samples; /* The driver can return 0, and we should pass that along to the * application. The ARB decided that ARB_internalformat_query should * behave as ARB_internalformat_query2 in this situation. * * The ARB_internalformat_query2 spec says: * * "- NUM_SAMPLE_COUNTS: The number of sample counts that would be * returned by querying SAMPLES is returned in <params>. * * If <internalformat> is not color-renderable, * depth-renderable, or stencil-renderable (as defined in * section 4.4.4), or if <target> does not support multiple * samples (ie other than TEXTURE_2D_MULTISAMPLE, * TEXTURE_2D_MULTISAMPLE_ARRAY, or RENDERBUFFER), 0 is * returned." */ num_samples = ctx->Driver.QuerySamplesForFormat(ctx, target, internalformat, buffer); /* QuerySamplesForFormat writes some stuff to buffer, so we have to * separately over-write it with the requested value. */ buffer[0] = (GLint) num_samples; count = 1; } break; } default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(pname=%s)", _mesa_lookup_enum_by_nr(pname)); return; } if (bufSize != 0 && params == NULL) { /* Emit a warning to aid application debugging, but go ahead and do the * memcpy (and probably crash) anyway. */ _mesa_warning(ctx, "glGetInternalformativ(bufSize = %d, but params = NULL)", bufSize); } /* Copy the data from the temporary buffer to the buffer supplied by the * application. Clamp the size of the copy to the size supplied by the * application. */ memcpy(params, buffer, MIN2(count, bufSize) * sizeof(GLint)); return; }
void GLAPIENTRY _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) { GLint buffer[16]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); /* ARB_internalformat_query is also mandatory for ARB_internalformat_query2 */ if (!(_mesa_has_ARB_internalformat_query(ctx) || _mesa_is_gles3(ctx))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ"); return; } assert(ctx->Driver.QueryInternalFormat != NULL); if (!_legal_parameters(ctx, target, internalformat, pname, bufSize, params)) return; /* initialize the contents of the temporary buffer */ memcpy(buffer, params, MIN2(bufSize, 16) * sizeof(GLint)); /* Use the 'unsupported' response defined by the spec for every pname * as the default answer. */ _set_default_response(pname, buffer); if (!_is_target_supported(ctx, target) || !_is_internalformat_supported(ctx, target, internalformat) || !_is_resource_supported(ctx, target, internalformat, pname)) goto end; switch (pname) { case GL_SAMPLES: /* fall-through */ case GL_NUM_SAMPLE_COUNTS: /* The ARB_internalformat_query2 sets the response as 'unsupported' for * SAMPLES and NUM_SAMPLE_COUNTS: * * "If <internalformat> is not color-renderable, depth-renderable, or * stencil-renderable (as defined in section 4.4.4), or if <target> * does not support multiple samples (ie other than * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY, * or RENDERBUFFER)." */ if ((target != GL_RENDERBUFFER && target != GL_TEXTURE_2D_MULTISAMPLE && target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) || !_is_renderable(ctx, internalformat)) goto end; /* The GL ES 3.0 specification, section 6.1.15 page 236 says: * * "Since multisampling is not supported for signed and unsigned * integer internal formats, the value of NUM_SAMPLE_COUNTS will be * zero for such formats. * * Since OpenGL ES 3.1 adds support for multisampled integer formats, we * have to check the version for 30 exactly. */ if (pname == GL_NUM_SAMPLE_COUNTS && ctx->API == API_OPENGLES2 && ctx->Version == 30 && _mesa_is_enum_format_integer(internalformat)) { goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_INTERNALFORMAT_SUPPORTED: /* Having a supported <internalformat> is implemented as a prerequisite * for all the <pnames>. Thus, if we reach this point, the internalformat is * supported. */ buffer[0] = GL_TRUE; break; case GL_INTERNALFORMAT_PREFERRED: /* The ARB_internalformat_query2 spec says: * * "- INTERNALFORMAT_PREFERRED: The implementation-preferred internal * format for representing resources of the specified <internalformat> is * returned in <params>. * * Therefore, we let the driver answer. Note that if we reach this * point, it means that the internalformat is supported, so the driver * is called just to try to get a preferred format. If not supported, * GL_NONE was already returned and the driver is not called. */ ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_INTERNALFORMAT_RED_SIZE: case GL_INTERNALFORMAT_GREEN_SIZE: case GL_INTERNALFORMAT_BLUE_SIZE: case GL_INTERNALFORMAT_ALPHA_SIZE: case GL_INTERNALFORMAT_DEPTH_SIZE: case GL_INTERNALFORMAT_STENCIL_SIZE: case GL_INTERNALFORMAT_SHARED_SIZE: case GL_INTERNALFORMAT_RED_TYPE: case GL_INTERNALFORMAT_GREEN_TYPE: case GL_INTERNALFORMAT_BLUE_TYPE: case GL_INTERNALFORMAT_ALPHA_TYPE: case GL_INTERNALFORMAT_DEPTH_TYPE: case GL_INTERNALFORMAT_STENCIL_TYPE: { GLint baseformat; mesa_format texformat; if (target != GL_RENDERBUFFER) { if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, true)) goto end; baseformat = _mesa_base_tex_format(ctx, internalformat); } else { baseformat = _mesa_base_fbo_format(ctx, internalformat); } /* Let the driver choose the texture format. * * Disclaimer: I am considering that drivers use for renderbuffers the * same format-choice logic as for textures. */ texformat = ctx->Driver.ChooseTextureFormat(ctx, target, internalformat, GL_NONE /*format */, GL_NONE /* type */); if (texformat == MESA_FORMAT_NONE || baseformat <= 0) goto end; /* Implementation based on what Mesa does for glGetTexLevelParameteriv * and glGetRenderbufferParameteriv functions. */ if (pname == GL_INTERNALFORMAT_SHARED_SIZE) { if (_mesa_has_EXT_texture_shared_exponent(ctx) && target != GL_TEXTURE_BUFFER && target != GL_RENDERBUFFER && texformat == MESA_FORMAT_R9G9B9E5_FLOAT) { buffer[0] = 5; } goto end; } if (!_mesa_base_format_has_channel(baseformat, pname)) goto end; switch (pname) { case GL_INTERNALFORMAT_DEPTH_SIZE: if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_depth_texture(ctx) && target != GL_RENDERBUFFER && target != GL_TEXTURE_BUFFER) goto end; /* fallthrough */ case GL_INTERNALFORMAT_RED_SIZE: case GL_INTERNALFORMAT_GREEN_SIZE: case GL_INTERNALFORMAT_BLUE_SIZE: case GL_INTERNALFORMAT_ALPHA_SIZE: case GL_INTERNALFORMAT_STENCIL_SIZE: buffer[0] = _mesa_get_format_bits(texformat, pname); break; case GL_INTERNALFORMAT_DEPTH_TYPE: if (!_mesa_has_ARB_texture_float(ctx)) goto end; /* fallthrough */ case GL_INTERNALFORMAT_RED_TYPE: case GL_INTERNALFORMAT_GREEN_TYPE: case GL_INTERNALFORMAT_BLUE_TYPE: case GL_INTERNALFORMAT_ALPHA_TYPE: case GL_INTERNALFORMAT_STENCIL_TYPE: buffer[0] = _mesa_get_format_datatype(texformat); break; default: break; } break; } /* For WIDTH/HEIGHT/DEPTH/LAYERS there is no reason to think that the * returned values should be different to the values returned by * GetInteger with MAX_TEXTURE_SIZE, MAX_3D_TEXTURE_SIZE, etc.*/ case GL_MAX_WIDTH: case GL_MAX_HEIGHT: case GL_MAX_DEPTH: { GLenum get_pname; GLint dimensions; GLint min_dimensions; /* From query2:MAX_HEIGHT spec (as example): * * "If the resource does not have at least two dimensions, or if the * resource is unsupported, zero is returned." */ dimensions = _get_target_dimensions(target); min_dimensions = _get_min_dimensions(pname); if (dimensions < min_dimensions) goto end; get_pname = _equivalent_size_pname(target, pname); if (get_pname == 0) goto end; _mesa_GetIntegerv(get_pname, buffer); break; } case GL_MAX_LAYERS: if (!_mesa_has_EXT_texture_array(ctx)) goto end; if (!_mesa_is_array_texture(target)) goto end; _mesa_GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, buffer); break; case GL_MAX_COMBINED_DIMENSIONS:{ GLint64 combined_value = 1; GLenum max_dimensions_pnames[] = { GL_MAX_WIDTH, GL_MAX_HEIGHT, GL_MAX_DEPTH, GL_SAMPLES }; unsigned i; GLint current_value; /* Combining the dimensions. Note that for array targets, this would * automatically include the value of MAX_LAYERS, as that value is * returned as MAX_HEIGHT or MAX_DEPTH */ for (i = 0; i < 4; i++) { if (max_dimensions_pnames[i] == GL_SAMPLES && !_is_multisample_target(target)) continue; _mesa_GetInternalformativ(target, internalformat, max_dimensions_pnames[i], 1, ¤t_value); if (current_value != 0) combined_value *= current_value; } if (_mesa_is_cube_map_texture(target)) combined_value *= 6; /* We pack the 64-bit value on two 32-bit values. Calling the 32-bit * query, this would work as far as the value can be hold on a 32-bit * signed integer. For the 64-bit query, the wrapper around the 32-bit * query will unpack the value */ memcpy(buffer, &combined_value, sizeof(GLint64)); break; } case GL_COLOR_COMPONENTS: /* The ARB_internalformat_query2 spec says: * * "- COLOR_COMPONENTS: If the internal format contains any color * components (R, G, B, or A), TRUE is returned in <params>. * If the internal format is unsupported or contains no color * components, FALSE is returned." */ if (_mesa_is_color_format(internalformat)) buffer[0] = GL_TRUE; break; case GL_DEPTH_COMPONENTS: /* The ARB_internalformat_query2 spec says: * * "- DEPTH_COMPONENTS: If the internal format contains a depth * component (D), TRUE is returned in <params>. If the internal format * is unsupported or contains no depth component, FALSE is returned." */ if (_mesa_is_depth_format(internalformat) || _mesa_is_depthstencil_format(internalformat)) buffer[0] = GL_TRUE; break; case GL_STENCIL_COMPONENTS: /* The ARB_internalformat_query2 spec says: * * "- STENCIL_COMPONENTS: If the internal format contains a stencil * component (S), TRUE is returned in <params>. If the internal format * is unsupported or contains no stencil component, FALSE is returned. */ if (_mesa_is_stencil_format(internalformat) || _mesa_is_depthstencil_format(internalformat)) buffer[0] = GL_TRUE; break; case GL_COLOR_RENDERABLE: case GL_DEPTH_RENDERABLE: case GL_STENCIL_RENDERABLE: if (!_is_renderable(ctx, internalformat)) goto end; if (pname == GL_COLOR_RENDERABLE) { if (!_mesa_is_color_format(internalformat)) goto end; } else { GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat); if (baseFormat != GL_DEPTH_STENCIL && ((pname == GL_DEPTH_RENDERABLE && baseFormat != GL_DEPTH_COMPONENT) || (pname == GL_STENCIL_RENDERABLE && baseFormat != GL_STENCIL_INDEX))) goto end; } buffer[0] = GL_TRUE; break; case GL_FRAMEBUFFER_RENDERABLE_LAYERED: if (!_mesa_has_EXT_texture_array(ctx) || _legal_target_for_framebuffer_texture_layer(ctx, target)) goto end; /* fallthrough */ case GL_FRAMEBUFFER_RENDERABLE: case GL_FRAMEBUFFER_BLEND: if (!_mesa_has_ARB_framebuffer_object(ctx)) goto end; if (target == GL_TEXTURE_BUFFER || !_is_renderable(ctx, internalformat)) goto end; ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_READ_PIXELS: case GL_READ_PIXELS_FORMAT: case GL_READ_PIXELS_TYPE: ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_TEXTURE_IMAGE_FORMAT: case GL_GET_TEXTURE_IMAGE_FORMAT: case GL_TEXTURE_IMAGE_TYPE: case GL_GET_TEXTURE_IMAGE_TYPE: ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_MIPMAP: case GL_MANUAL_GENERATE_MIPMAP: case GL_AUTO_GENERATE_MIPMAP: if (!_mesa_is_valid_generate_texture_mipmap_target(ctx, target) || !_mesa_is_valid_generate_texture_mipmap_internalformat(ctx, internalformat)) { goto end; } if (pname == GL_MIPMAP) { buffer[0] = GL_TRUE; goto end; } else if (pname == GL_MANUAL_GENERATE_MIPMAP) { if (!_mesa_has_ARB_framebuffer_object(ctx)) goto end; } else { /* From ARB_internalformat_query2: * "Dependencies on OpenGL 3.2 (Core Profile) * In core profiles for OpenGL 3.2 and later versions, queries * for the AUTO_GENERATE_MIPMAP <pname> return the appropriate * unsupported response." */ if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 32) goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_COLOR_ENCODING: if (!_mesa_is_color_format(internalformat)) goto end; if (_mesa_is_srgb_format(internalformat)) buffer[0] = GL_SRGB; else buffer[0] = GL_LINEAR; break; case GL_SRGB_READ: if (!_mesa_has_EXT_texture_sRGB(ctx) || !_mesa_is_srgb_format(internalformat)) { goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_SRGB_WRITE: if (!_mesa_has_EXT_framebuffer_sRGB(ctx) || !_mesa_is_color_format(internalformat)) { goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_SRGB_DECODE_ARB: /* Presence of EXT_texture_sRGB_decode was already verified */ if (!_mesa_has_EXT_texture_sRGB(ctx) || target == GL_RENDERBUFFER || !_mesa_is_srgb_format(internalformat)) { goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_FILTER: /* If it doesn't allow to set sampler parameters then it would not allow * to set a filter different to GL_NEAREST. In practice, this method * only filters out MULTISAMPLE/MULTISAMPLE_ARRAY */ if (!_mesa_target_allows_setting_sampler_parameters(target)) goto end; if (_mesa_is_enum_format_integer(internalformat)) goto end; if (target == GL_TEXTURE_BUFFER) goto end; /* At this point we know that multi-texel filtering is supported. We * need to call the driver to know if it is CAVEAT_SUPPORT or * FULL_SUPPORT. */ ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_VERTEX_TEXTURE: case GL_TESS_CONTROL_TEXTURE: case GL_TESS_EVALUATION_TEXTURE: case GL_GEOMETRY_TEXTURE: case GL_FRAGMENT_TEXTURE: case GL_COMPUTE_TEXTURE: if (target == GL_RENDERBUFFER) goto end; if ((pname == GL_TESS_CONTROL_TEXTURE || pname == GL_TESS_EVALUATION_TEXTURE) && !_mesa_has_tessellation(ctx)) goto end; if (pname == GL_GEOMETRY_TEXTURE && !_mesa_has_geometry_shaders(ctx)) goto end; if (pname == GL_COMPUTE_TEXTURE && !_mesa_has_compute_shaders(ctx)) goto end; ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_TEXTURE_GATHER: case GL_TEXTURE_GATHER_SHADOW: if (!_mesa_has_ARB_texture_gather(ctx)) goto end; /* fallthrough */ case GL_TEXTURE_SHADOW: /* Only depth or depth-stencil image formats make sense in shadow samplers */ if (pname != GL_TEXTURE_GATHER && !_mesa_is_depth_format(internalformat) && !_mesa_is_depthstencil_format(internalformat)) goto end; /* Validate the target for shadow and gather operations */ switch (target) { case GL_TEXTURE_2D: case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_TEXTURE_RECTANGLE: break; case GL_TEXTURE_1D: case GL_TEXTURE_1D_ARRAY: /* 1D and 1DArray textures are not admitted in gather operations */ if (pname != GL_TEXTURE_SHADOW) goto end; break; default: goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_SHADER_IMAGE_LOAD: case GL_SHADER_IMAGE_STORE: if (!_mesa_has_ARB_shader_image_load_store(ctx)) goto end; /* We call to _mesa_is_shader_image_format_supported * using "internalformat" as parameter, because the * the ARB_internalformat_query2 spec says: * "In this case the <internalformat> is the value of the <format> * parameter that is passed to BindImageTexture." */ if (target == GL_RENDERBUFFER || !_mesa_is_shader_image_format_supported(ctx, internalformat)) goto end; ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_SHADER_IMAGE_ATOMIC: if (!_mesa_has_ARB_shader_image_load_store(ctx)) goto end; ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_IMAGE_TEXEL_SIZE: { mesa_format image_format; if (!_mesa_has_ARB_shader_image_load_store(ctx) || target == GL_RENDERBUFFER) goto end; image_format = _mesa_get_shader_image_format(internalformat); if (image_format == MESA_FORMAT_NONE) goto end; /* We return bits */ buffer[0] = (_mesa_get_format_bytes(image_format) * 8); break; } case GL_IMAGE_COMPATIBILITY_CLASS: if (!_mesa_has_ARB_shader_image_load_store(ctx) || target == GL_RENDERBUFFER) goto end; buffer[0] = _mesa_get_image_format_class(internalformat); break; case GL_IMAGE_PIXEL_FORMAT: { GLint base_format; if (!_mesa_has_ARB_shader_image_load_store(ctx) || target == GL_RENDERBUFFER || !_mesa_is_shader_image_format_supported(ctx, internalformat)) goto end; base_format = _mesa_base_tex_format(ctx, internalformat); if (base_format == -1) goto end; if (_mesa_is_enum_format_integer(internalformat)) buffer[0] = _mesa_base_format_to_integer_format(base_format); else buffer[0] = base_format; break; } case GL_IMAGE_PIXEL_TYPE: { mesa_format image_format; GLenum datatype; GLuint comps; if (!_mesa_has_ARB_shader_image_load_store(ctx) || target == GL_RENDERBUFFER) goto end; image_format = _mesa_get_shader_image_format(internalformat); if (image_format == MESA_FORMAT_NONE) goto end; _mesa_uncompressed_format_to_type_and_comps(image_format, &datatype, &comps); if (!datatype) goto end; buffer[0] = datatype; break; } case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: { if (!_mesa_has_ARB_shader_image_load_store(ctx)) goto end; if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, true)) goto end; /* From spec: "Equivalent to calling GetTexParameter with <value> set * to IMAGE_FORMAT_COMPATIBILITY_TYPE." * * GetTexParameter just returns * tex_obj->ImageFormatCompatibilityType. We create a fake tex_obj * just with the purpose of getting the value. */ struct gl_texture_object *tex_obj = _mesa_new_texture_object(ctx, 0, target); buffer[0] = tex_obj->ImageFormatCompatibilityType; _mesa_delete_texture_object(ctx, tex_obj); break; } case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: if (target == GL_RENDERBUFFER) goto end; if (!_mesa_is_depthstencil_format(internalformat)) { if (((pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST || pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE) && !_mesa_is_depth_format(internalformat)) || ((pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST || pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE) && !_mesa_is_stencil_format(internalformat))) goto end; } ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_TEXTURE_COMPRESSED: buffer[0] = _mesa_is_compressed_format(ctx, internalformat); break; case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH: case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT: case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: { mesa_format mesaformat; GLint block_size; mesaformat = _mesa_glenum_to_compressed_format(internalformat); if (mesaformat == MESA_FORMAT_NONE) goto end; block_size = _mesa_get_format_bytes(mesaformat); assert(block_size > 0); if (pname == GL_TEXTURE_COMPRESSED_BLOCK_SIZE) { buffer[0] = block_size; } else { GLuint bwidth, bheight; /* Returns the width and height in pixels. We return bytes */ _mesa_get_format_block_size(mesaformat, &bwidth, &bheight); assert(bwidth > 0 && bheight > 0); if (pname == GL_TEXTURE_COMPRESSED_BLOCK_WIDTH) buffer[0] = block_size / bheight; else buffer[0] = block_size / bwidth; } break; } case GL_CLEAR_BUFFER: if (target != GL_TEXTURE_BUFFER) goto end; ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; case GL_TEXTURE_VIEW: case GL_VIEW_COMPATIBILITY_CLASS: if (!_mesa_has_ARB_texture_view(ctx) || target == GL_TEXTURE_BUFFER || target == GL_RENDERBUFFER) goto end; if (pname == GL_TEXTURE_VIEW) { ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, buffer); } else { GLenum view_class = _mesa_texture_view_lookup_view_class(ctx, internalformat); if (view_class == GL_FALSE) goto end; buffer[0] = view_class; } break; default: unreachable("bad param"); } end: if (bufSize != 0 && params == NULL) { /* Emit a warning to aid application debugging, but go ahead and do the * memcpy (and probably crash) anyway. */ _mesa_warning(ctx, "glGetInternalformativ(bufSize = %d, but params = NULL)", bufSize); } /* Copy the data from the temporary buffer to the buffer supplied by the * application. Clamp the size of the copy to the size supplied by the * application. */ memcpy(params, buffer, MIN2(bufSize, 16) * sizeof(GLint)); return; }
static bool _is_target_supported(struct gl_context *ctx, GLenum target) { /* The ARB_internalformat_query2 spec says: * * "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: if (!_mesa_is_desktop_gl(ctx)) return false; break; case GL_TEXTURE_1D_ARRAY: if (!_mesa_has_EXT_texture_array(ctx)) return false; break; case GL_TEXTURE_2D_ARRAY: if (!_mesa_has_EXT_texture_array(ctx)) return false; break; case GL_TEXTURE_CUBE_MAP: if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_texture_cube_map(ctx)) return false; break; case GL_TEXTURE_CUBE_MAP_ARRAY: if (!_mesa_has_ARB_texture_cube_map_array(ctx)) return false; break; case GL_TEXTURE_RECTANGLE: if (!_mesa_has_ARB_texture_rectangle(ctx)) return false; break; case GL_TEXTURE_BUFFER: if (!_mesa_has_ARB_texture_buffer_object(ctx)) return false; break; case GL_RENDERBUFFER: if (!(_mesa_has_ARB_framebuffer_object(ctx) || _mesa_is_gles3(ctx))) return false; break; case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: if (!(_mesa_has_ARB_texture_multisample(ctx) || _mesa_is_gles31(ctx))) return false; break; default: unreachable("invalid target"); } return true; }
void GLAPIENTRY _mesa_Hint( GLenum target, GLenum mode ) { GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glHint %s %s\n", _mesa_enum_to_string(target), _mesa_enum_to_string(mode)); if (mode != GL_NICEST && mode != GL_FASTEST && mode != GL_DONT_CARE) { _mesa_error(ctx, GL_INVALID_ENUM, "glHint(mode)"); return; } switch (target) { case GL_FOG_HINT: if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) goto invalid_target; if (ctx->Hint.Fog == mode) return; FLUSH_VERTICES(ctx, _NEW_HINT); ctx->Hint.Fog = mode; break; case GL_LINE_SMOOTH_HINT: if (!_mesa_is_desktop_gl(ctx) && ctx->API != API_OPENGLES) goto invalid_target; if (ctx->Hint.LineSmooth == mode) return; FLUSH_VERTICES(ctx, _NEW_HINT); ctx->Hint.LineSmooth = mode; break; case GL_PERSPECTIVE_CORRECTION_HINT: if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) goto invalid_target; if (ctx->Hint.PerspectiveCorrection == mode) return; FLUSH_VERTICES(ctx, _NEW_HINT); ctx->Hint.PerspectiveCorrection = mode; break; case GL_POINT_SMOOTH_HINT: if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) goto invalid_target; if (ctx->Hint.PointSmooth == mode) return; FLUSH_VERTICES(ctx, _NEW_HINT); ctx->Hint.PointSmooth = mode; break; case GL_POLYGON_SMOOTH_HINT: if (!_mesa_is_desktop_gl(ctx)) goto invalid_target; if (ctx->Hint.PolygonSmooth == mode) return; FLUSH_VERTICES(ctx, _NEW_HINT); ctx->Hint.PolygonSmooth = mode; break; /* GL_ARB_texture_compression */ case GL_TEXTURE_COMPRESSION_HINT_ARB: if (!_mesa_is_desktop_gl(ctx)) goto invalid_target; if (ctx->Hint.TextureCompression == mode) return; FLUSH_VERTICES(ctx, _NEW_HINT); ctx->Hint.TextureCompression = mode; break; /* GL_SGIS_generate_mipmap */ case GL_GENERATE_MIPMAP_HINT_SGIS: if (ctx->API == API_OPENGL_CORE) goto invalid_target; if (ctx->Hint.GenerateMipmap == mode) return; FLUSH_VERTICES(ctx, _NEW_HINT); ctx->Hint.GenerateMipmap = mode; break; /* GL_ARB_fragment_shader */ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: if (ctx->API == API_OPENGLES || !ctx->Extensions.ARB_fragment_shader) goto invalid_target; if (ctx->Hint.FragmentShaderDerivative == mode) return; FLUSH_VERTICES(ctx, _NEW_HINT); ctx->Hint.FragmentShaderDerivative = mode; break; default: goto invalid_target; } return; invalid_target: _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)"); return; }
/** * Return pointer-valued state, such as a vertex array pointer. * * \param pname names state to be queried * \param params returns the pointer value * * \sa glGetPointerv(). * * Tries to get the specified pointer via dd_function_table::GetPointerv, * otherwise gets the specified pointer from the current context. */ void GLAPIENTRY _mesa_GetPointerv( GLenum pname, GLvoid **params ) { GET_CURRENT_CONTEXT(ctx); const GLuint clientUnit = ctx->Array.ActiveTexture; ASSERT_OUTSIDE_BEGIN_END(ctx); if (!params) return; if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glGetPointerv %s\n", _mesa_lookup_enum_by_nr(pname)); switch (pname) { case GL_VERTEX_ARRAY_POINTER: if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) goto invalid_pname; *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Ptr; break; case GL_NORMAL_ARRAY_POINTER: if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) goto invalid_pname; *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Ptr; break; case GL_COLOR_ARRAY_POINTER: if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) goto invalid_pname; *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Ptr; break; case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT: if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Ptr; break; case GL_FOG_COORDINATE_ARRAY_POINTER_EXT: if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG].Ptr; break; case GL_INDEX_ARRAY_POINTER: if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Ptr; break; case GL_TEXTURE_COORD_ARRAY_POINTER: if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) goto invalid_pname; *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_TEX(clientUnit)].Ptr; break; case GL_EDGE_FLAG_ARRAY_POINTER: if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Ptr; break; case GL_FEEDBACK_BUFFER_POINTER: if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; *params = ctx->Feedback.Buffer; break; case GL_SELECTION_BUFFER_POINTER: if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; *params = ctx->Select.Buffer; break; case GL_POINT_SIZE_ARRAY_POINTER_OES: if (ctx->API != API_OPENGLES) goto invalid_pname; *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Ptr; break; case GL_DEBUG_CALLBACK_FUNCTION_ARB: if (!_mesa_is_desktop_gl(ctx)) goto invalid_pname; *params = (GLvoid *) ctx->Debug.Callback; break; case GL_DEBUG_CALLBACK_USER_PARAM_ARB: if (!_mesa_is_desktop_gl(ctx)) goto invalid_pname; *params = ctx->Debug.CallbackData; break; default: goto invalid_pname; } return; invalid_pname: _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" ); return; }
void GLAPIENTRY _mesa_PixelStorei( GLenum pname, GLint param ) { /* NOTE: this call can't be compiled into the display list */ GET_CURRENT_CONTEXT(ctx); switch (pname) { case GL_PACK_SWAP_BYTES: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE; break; case GL_PACK_LSB_FIRST: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE; break; case GL_PACK_ROW_LENGTH: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Pack.RowLength = param; break; case GL_PACK_IMAGE_HEIGHT: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Pack.ImageHeight = param; break; case GL_PACK_SKIP_PIXELS: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Pack.SkipPixels = param; break; case GL_PACK_SKIP_ROWS: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Pack.SkipRows = param; break; case GL_PACK_SKIP_IMAGES: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Pack.SkipImages = param; break; case GL_PACK_ALIGNMENT: if (param!=1 && param!=2 && param!=4 && param!=8) goto invalid_value_error; ctx->Pack.Alignment = param; break; case GL_PACK_INVERT_MESA: if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.MESA_pack_invert) goto invalid_enum_error; ctx->Pack.Invert = param; break; case GL_PACK_COMPRESSED_BLOCK_WIDTH: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Pack.CompressedBlockWidth = param; break; case GL_PACK_COMPRESSED_BLOCK_HEIGHT: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Pack.CompressedBlockHeight = param; break; case GL_PACK_COMPRESSED_BLOCK_DEPTH: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Pack.CompressedBlockDepth = param; break; case GL_PACK_COMPRESSED_BLOCK_SIZE: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Pack.CompressedBlockSize = param; break; case GL_UNPACK_SWAP_BYTES: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE; break; case GL_UNPACK_LSB_FIRST: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE; break; case GL_UNPACK_ROW_LENGTH: if (ctx->API == API_OPENGLES) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Unpack.RowLength = param; break; case GL_UNPACK_IMAGE_HEIGHT: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Unpack.ImageHeight = param; break; case GL_UNPACK_SKIP_PIXELS: if (ctx->API == API_OPENGLES) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Unpack.SkipPixels = param; break; case GL_UNPACK_SKIP_ROWS: if (ctx->API == API_OPENGLES) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Unpack.SkipRows = param; break; case GL_UNPACK_SKIP_IMAGES: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; if (param < 0) goto invalid_value_error; ctx->Unpack.SkipImages = param; break; case GL_UNPACK_ALIGNMENT: if (param!=1 && param!=2 && param!=4 && param!=8) goto invalid_value_error; ctx->Unpack.Alignment = param; break; case GL_UNPACK_COMPRESSED_BLOCK_WIDTH: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Unpack.CompressedBlockWidth = param; break; case GL_UNPACK_COMPRESSED_BLOCK_HEIGHT: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Unpack.CompressedBlockHeight = param; break; case GL_UNPACK_COMPRESSED_BLOCK_DEPTH: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Unpack.CompressedBlockDepth = param; break; case GL_UNPACK_COMPRESSED_BLOCK_SIZE: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; if (param<0) goto invalid_value_error; ctx->Unpack.CompressedBlockSize = param; break; default: goto invalid_enum_error; } return; invalid_enum_error: _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" ); return; invalid_value_error: _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); return; }
/** * Initialize a dispatch table with pointers to Mesa's immediate-mode * commands. * * Pointers to glBegin()/glEnd() object commands and a few others * are provided via the GLvertexformat interface. * * \param ctx GL context to which \c exec belongs. * \param exec dispatch table. */ struct _glapi_table * _mesa_create_exec_table(struct gl_context *ctx) { struct _glapi_table *exec; exec = _mesa_alloc_dispatch_table(_gloffset_COUNT); if (exec == NULL) return NULL; #if _HAVE_FULL_GL _mesa_loopback_init_api_table( exec ); #endif /* load the dispatch slots we understand */ if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_AlphaFunc(exec, _mesa_AlphaFunc); } SET_BlendFunc(exec, _mesa_BlendFunc); SET_Clear(exec, _mesa_Clear); SET_ClearColor(exec, _mesa_ClearColor); SET_ClearStencil(exec, _mesa_ClearStencil); SET_ColorMask(exec, _mesa_ColorMask); SET_CullFace(exec, _mesa_CullFace); SET_Disable(exec, _mesa_Disable); #if FEATURE_draw_read_buffer if (ctx->API == API_OPENGL || ctx->API == API_OPENGL_CORE) SET_DrawBuffer(exec, _mesa_DrawBuffer); SET_ReadBuffer(exec, _mesa_ReadBuffer); #endif SET_Enable(exec, _mesa_Enable); SET_Finish(exec, _mesa_Finish); SET_Flush(exec, _mesa_Flush); SET_FrontFace(exec, _mesa_FrontFace); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_Frustum(exec, _mesa_Frustum); } SET_GetError(exec, _mesa_GetError); SET_GetFloatv(exec, _mesa_GetFloatv); SET_GetString(exec, _mesa_GetString); if (ctx->API == API_OPENGL) { SET_LineStipple(exec, _mesa_LineStipple); } SET_LineWidth(exec, _mesa_LineWidth); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_LoadIdentity(exec, _mesa_LoadIdentity); SET_LoadMatrixf(exec, _mesa_LoadMatrixf); } if (ctx->API != API_OPENGLES2) { SET_LogicOp(exec, _mesa_LogicOp); } if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_MatrixMode(exec, _mesa_MatrixMode); SET_MultMatrixf(exec, _mesa_MultMatrixf); SET_Ortho(exec, _mesa_Ortho); } SET_PixelStorei(exec, _mesa_PixelStorei); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_PopMatrix(exec, _mesa_PopMatrix); SET_PushMatrix(exec, _mesa_PushMatrix); SET_Rotatef(exec, _mesa_Rotatef); SET_Scalef(exec, _mesa_Scalef); } SET_Scissor(exec, _mesa_Scissor); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_ShadeModel(exec, _mesa_ShadeModel); } SET_StencilFunc(exec, _mesa_StencilFunc); SET_StencilMask(exec, _mesa_StencilMask); SET_StencilOp(exec, _mesa_StencilOp); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_TexEnvfv(exec, _mesa_TexEnvfv); SET_TexEnvi(exec, _mesa_TexEnvi); } SET_TexImage2D(exec, _mesa_TexImage2D); SET_TexParameteri(exec, _mesa_TexParameteri); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_Translatef(exec, _mesa_Translatef); } SET_Viewport(exec, _mesa_Viewport); if (ctx->API == API_OPENGL) { _mesa_init_accum_dispatch(exec); _mesa_init_dlist_dispatch(exec); } SET_ClearDepth(exec, _mesa_ClearDepth); if (ctx->API == API_OPENGL) { SET_ClearIndex(exec, _mesa_ClearIndex); SET_ClipPlane(exec, _mesa_ClipPlane); SET_ColorMaterial(exec, _mesa_ColorMaterial); } SET_DepthFunc(exec, _mesa_DepthFunc); SET_DepthMask(exec, _mesa_DepthMask); SET_DepthRange(exec, _mesa_DepthRange); if (ctx->API != API_OPENGLES2 && ctx->API != API_OPENGL_CORE) { _mesa_init_drawpix_dispatch(exec); } if (ctx->API == API_OPENGL) { _mesa_init_feedback_dispatch(exec); } if (ctx->API == API_OPENGL) { SET_FogCoordPointerEXT(exec, _mesa_FogCoordPointerEXT); SET_Fogf(exec, _mesa_Fogf); SET_Fogfv(exec, _mesa_Fogfv); SET_Fogi(exec, _mesa_Fogi); SET_Fogiv(exec, _mesa_Fogiv); SET_GetClipPlane(exec, _mesa_GetClipPlane); } SET_GetBooleanv(exec, _mesa_GetBooleanv); SET_GetDoublev(exec, _mesa_GetDoublev); SET_GetIntegerv(exec, _mesa_GetIntegerv); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_GetLightfv(exec, _mesa_GetLightfv); SET_GetLightiv(exec, _mesa_GetLightiv); SET_GetMaterialfv(exec, _mesa_GetMaterialfv); SET_GetMaterialiv(exec, _mesa_GetMaterialiv); SET_GetPolygonStipple(exec, _mesa_GetPolygonStipple); SET_GetTexEnvfv(exec, _mesa_GetTexEnvfv); SET_GetTexEnviv(exec, _mesa_GetTexEnviv); } if (ctx->API != API_OPENGLES2) { SET_GetTexLevelParameterfv(exec, _mesa_GetTexLevelParameterfv); SET_GetTexLevelParameteriv(exec, _mesa_GetTexLevelParameteriv); } SET_GetTexParameterfv(exec, _mesa_GetTexParameterfv); SET_GetTexParameteriv(exec, _mesa_GetTexParameteriv); if (ctx->API != API_OPENGLES2) { SET_GetTexImage(exec, _mesa_GetTexImage); } SET_Hint(exec, _mesa_Hint); if (ctx->API == API_OPENGL) { SET_IndexMask(exec, _mesa_IndexMask); } SET_IsEnabled(exec, _mesa_IsEnabled); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_LightModelf(exec, _mesa_LightModelf); SET_LightModelfv(exec, _mesa_LightModelfv); SET_LightModeli(exec, _mesa_LightModeli); SET_LightModeliv(exec, _mesa_LightModeliv); SET_Lightf(exec, _mesa_Lightf); SET_Lightfv(exec, _mesa_Lightfv); SET_Lighti(exec, _mesa_Lighti); SET_Lightiv(exec, _mesa_Lightiv); SET_LoadMatrixd(exec, _mesa_LoadMatrixd); } if (ctx->API == API_OPENGL) { _mesa_init_eval_dispatch(exec); SET_MultMatrixd(exec, _mesa_MultMatrixd); _mesa_init_pixel_dispatch(exec); } if (ctx->API != API_OPENGLES2) { SET_PixelStoref(exec, _mesa_PixelStoref); } SET_PointSize(exec, _mesa_PointSize); if (ctx->API != API_OPENGLES2) { SET_PolygonMode(exec, _mesa_PolygonMode); } SET_PolygonOffset(exec, _mesa_PolygonOffset); if (ctx->API == API_OPENGL) { SET_PolygonStipple(exec, _mesa_PolygonStipple); _mesa_init_attrib_dispatch(exec); _mesa_init_rastpos_dispatch(exec); } SET_ReadPixels(exec, _mesa_ReadPixels); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_Rotated(exec, _mesa_Rotated); SET_Scaled(exec, _mesa_Scaled); SET_SecondaryColorPointerEXT(exec, _mesa_SecondaryColorPointerEXT); SET_TexEnvf(exec, _mesa_TexEnvf); SET_TexEnviv(exec, _mesa_TexEnviv); } if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { _mesa_init_texgen_dispatch(exec); } if (ctx->API != API_OPENGLES2) { SET_TexImage1D(exec, _mesa_TexImage1D); } SET_TexParameterf(exec, _mesa_TexParameterf); SET_TexParameterfv(exec, _mesa_TexParameterfv); SET_TexParameteriv(exec, _mesa_TexParameteriv); if (ctx->API == API_OPENGL) { SET_Translated(exec, _mesa_Translated); } /* 1.1 */ SET_BindTexture(exec, _mesa_BindTexture); SET_DeleteTextures(exec, _mesa_DeleteTextures); SET_GenTextures(exec, _mesa_GenTextures); #if _HAVE_FULL_GL if (ctx->API == API_OPENGL) { SET_AreTexturesResident(exec, _mesa_AreTexturesResident); SET_ColorPointer(exec, _mesa_ColorPointer); } if (ctx->API != API_OPENGLES2) { SET_CopyTexImage1D(exec, _mesa_CopyTexImage1D); SET_CopyTexSubImage1D(exec, _mesa_CopyTexSubImage1D); SET_TexSubImage1D(exec, _mesa_TexSubImage1D); } SET_CopyTexImage2D(exec, _mesa_CopyTexImage2D); SET_CopyTexSubImage2D(exec, _mesa_CopyTexSubImage2D); SET_TexSubImage2D(exec, _mesa_TexSubImage2D); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_DisableClientState(exec, _mesa_DisableClientState); SET_EdgeFlagPointer(exec, _mesa_EdgeFlagPointer); SET_EnableClientState(exec, _mesa_EnableClientState); SET_GetPointerv(exec, _mesa_GetPointerv); SET_IndexPointer(exec, _mesa_IndexPointer); SET_InterleavedArrays(exec, _mesa_InterleavedArrays); } SET_IsTexture(exec, _mesa_IsTexture); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_NormalPointer(exec, _mesa_NormalPointer); SET_PrioritizeTextures(exec, _mesa_PrioritizeTextures); SET_TexCoordPointer(exec, _mesa_TexCoordPointer); } if (ctx->API != API_OPENGL_CORE) { SET_VertexPointer(exec, _mesa_VertexPointer); } #endif /* 1.2 */ #if _HAVE_FULL_GL SET_CopyTexSubImage3D(exec, _mesa_CopyTexSubImage3D); SET_TexImage3D(exec, _mesa_TexImage3D); SET_TexSubImage3D(exec, _mesa_TexSubImage3D); #endif /* OpenGL 1.2 GL_ARB_imaging */ SET_BlendColor(exec, _mesa_BlendColor); SET_BlendEquation(exec, _mesa_BlendEquation); SET_BlendEquationSeparateEXT(exec, _mesa_BlendEquationSeparateEXT); if (ctx->API == API_OPENGL) { _mesa_init_colortable_dispatch(exec); _mesa_init_convolve_dispatch(exec); _mesa_init_histogram_dispatch(exec); } /* OpenGL 2.0 */ SET_StencilFuncSeparate(exec, _mesa_StencilFuncSeparate); SET_StencilMaskSeparate(exec, _mesa_StencilMaskSeparate); SET_StencilOpSeparate(exec, _mesa_StencilOpSeparate); #if FEATURE_ARB_shader_objects _mesa_init_shader_dispatch(exec); _mesa_init_shader_uniform_dispatch(exec); #endif /* 2. GL_EXT_blend_color */ #if 0 /* SET_BlendColorEXT(exec, _mesa_BlendColorEXT); */ #endif /* 3. GL_EXT_polygon_offset */ #if _HAVE_FULL_GL if (ctx->API == API_OPENGL) { SET_PolygonOffsetEXT(exec, _mesa_PolygonOffsetEXT); } #endif /* 6. GL_EXT_texture3d */ #if 0 /* SET_CopyTexSubImage3DEXT(exec, _mesa_CopyTexSubImage3D); */ /* SET_TexImage3DEXT(exec, _mesa_TexImage3DEXT); */ /* SET_TexSubImage3DEXT(exec, _mesa_TexSubImage3D); */ #endif /* 11. GL_EXT_histogram */ #if 0 if (ctx->API == API_OPENGL) { SET_GetHistogramEXT(exec, _mesa_GetHistogram); SET_GetHistogramParameterfvEXT(exec, _mesa_GetHistogramParameterfv); SET_GetHistogramParameterivEXT(exec, _mesa_GetHistogramParameteriv); SET_GetMinmaxEXT(exec, _mesa_GetMinmax); SET_GetMinmaxParameterfvEXT(exec, _mesa_GetMinmaxParameterfv); SET_GetMinmaxParameterivEXT(exec, _mesa_GetMinmaxParameteriv); } #endif /* 14. SGI_color_table */ #if 0 if (ctx->API == API_OPENGL) { SET_ColorTableSGI(exec, _mesa_ColorTable); SET_ColorSubTableSGI(exec, _mesa_ColorSubTable); SET_GetColorTableSGI(exec, _mesa_GetColorTable); SET_GetColorTableParameterfvSGI(exec, _mesa_GetColorTableParameterfv); SET_GetColorTableParameterivSGI(exec, _mesa_GetColorTableParameteriv); } #endif /* 30. GL_EXT_vertex_array */ #if _HAVE_FULL_GL if (ctx->API == API_OPENGL) { SET_ColorPointerEXT(exec, _mesa_ColorPointerEXT); SET_EdgeFlagPointerEXT(exec, _mesa_EdgeFlagPointerEXT); SET_IndexPointerEXT(exec, _mesa_IndexPointerEXT); SET_NormalPointerEXT(exec, _mesa_NormalPointerEXT); SET_TexCoordPointerEXT(exec, _mesa_TexCoordPointerEXT); SET_VertexPointerEXT(exec, _mesa_VertexPointerEXT); } #endif /* 37. GL_EXT_blend_minmax */ #if 0 SET_BlendEquationEXT(exec, _mesa_BlendEquationEXT); #endif /* 54. GL_EXT_point_parameters */ #if _HAVE_FULL_GL SET_PointParameterfEXT(exec, _mesa_PointParameterf); SET_PointParameterfvEXT(exec, _mesa_PointParameterfv); #endif /* 95. GL_ARB_ES2_compatibility */ SET_ClearDepthf(exec, _mesa_ClearDepthf); SET_DepthRangef(exec, _mesa_DepthRangef); /* 97. GL_EXT_compiled_vertex_array */ #if _HAVE_FULL_GL if (ctx->API == API_OPENGL) { SET_LockArraysEXT(exec, _mesa_LockArraysEXT); SET_UnlockArraysEXT(exec, _mesa_UnlockArraysEXT); } #endif /* 148. GL_EXT_multi_draw_arrays */ #if _HAVE_FULL_GL SET_MultiDrawArraysEXT(exec, _mesa_MultiDrawArraysEXT); #endif /* 173. GL_INGR_blend_func_separate */ #if _HAVE_FULL_GL SET_BlendFuncSeparateEXT(exec, _mesa_BlendFuncSeparateEXT); #endif /* 196. GL_MESA_resize_buffers */ #if _HAVE_FULL_GL SET_ResizeBuffersMESA(exec, _mesa_ResizeBuffersMESA); #endif /* 197. GL_MESA_window_pos */ /* part of _mesa_init_rastpos_dispatch(exec); */ /* 200. GL_IBM_multimode_draw_arrays */ #if _HAVE_FULL_GL if (ctx->API != API_OPENGLES2) { SET_MultiModeDrawArraysIBM(exec, _mesa_MultiModeDrawArraysIBM); SET_MultiModeDrawElementsIBM(exec, _mesa_MultiModeDrawElementsIBM); } #endif /* 233. GL_NV_vertex_program */ #if FEATURE_NV_vertex_program if (ctx->API == API_OPENGL) { SET_BindProgramNV(exec, _mesa_BindProgram); SET_DeleteProgramsNV(exec, _mesa_DeletePrograms); SET_ExecuteProgramNV(exec, _mesa_ExecuteProgramNV); SET_GenProgramsNV(exec, _mesa_GenPrograms); SET_AreProgramsResidentNV(exec, _mesa_AreProgramsResidentNV); SET_RequestResidentProgramsNV(exec, _mesa_RequestResidentProgramsNV); SET_GetProgramParameterfvNV(exec, _mesa_GetProgramParameterfvNV); SET_GetProgramParameterdvNV(exec, _mesa_GetProgramParameterdvNV); SET_GetProgramivNV(exec, _mesa_GetProgramivNV); SET_GetProgramStringNV(exec, _mesa_GetProgramStringNV); SET_GetTrackMatrixivNV(exec, _mesa_GetTrackMatrixivNV); SET_GetVertexAttribdvNV(exec, _mesa_GetVertexAttribdvNV); SET_GetVertexAttribfvNV(exec, _mesa_GetVertexAttribfvNV); SET_GetVertexAttribivNV(exec, _mesa_GetVertexAttribivNV); SET_IsProgramNV(exec, _mesa_IsProgramARB); SET_LoadProgramNV(exec, _mesa_LoadProgramNV); SET_ProgramEnvParameter4dARB(exec, _mesa_ProgramEnvParameter4dARB); /* alias to ProgramParameter4dNV */ SET_ProgramEnvParameter4dvARB(exec, _mesa_ProgramEnvParameter4dvARB); /* alias to ProgramParameter4dvNV */ SET_ProgramEnvParameter4fARB(exec, _mesa_ProgramEnvParameter4fARB); /* alias to ProgramParameter4fNV */ SET_ProgramEnvParameter4fvARB(exec, _mesa_ProgramEnvParameter4fvARB); /* alias to ProgramParameter4fvNV */ SET_ProgramParameters4dvNV(exec, _mesa_ProgramParameters4dvNV); SET_ProgramParameters4fvNV(exec, _mesa_ProgramParameters4fvNV); SET_TrackMatrixNV(exec, _mesa_TrackMatrixNV); SET_VertexAttribPointerNV(exec, _mesa_VertexAttribPointerNV); /* glVertexAttrib*NV functions handled in api_loopback.c */ } #endif SET_GetVertexAttribPointervNV(exec, _mesa_GetVertexAttribPointervNV); /* 273. GL_APPLE_vertex_array_object */ if (ctx->API == API_OPENGL) { SET_BindVertexArrayAPPLE(exec, _mesa_BindVertexArrayAPPLE); SET_GenVertexArraysAPPLE(exec, _mesa_GenVertexArraysAPPLE); } /* Reused by ARB_vertex_array_object / OES_vertex_array_object */ SET_DeleteVertexArraysAPPLE(exec, _mesa_DeleteVertexArraysAPPLE); SET_IsVertexArrayAPPLE(exec, _mesa_IsVertexArrayAPPLE); /* 282. GL_NV_fragment_program */ #if FEATURE_NV_fragment_program if (ctx->API == API_OPENGL) { SET_ProgramNamedParameter4fNV(exec, _mesa_ProgramNamedParameter4fNV); SET_ProgramNamedParameter4dNV(exec, _mesa_ProgramNamedParameter4dNV); SET_ProgramNamedParameter4fvNV(exec, _mesa_ProgramNamedParameter4fvNV); SET_ProgramNamedParameter4dvNV(exec, _mesa_ProgramNamedParameter4dvNV); SET_GetProgramNamedParameterfvNV(exec, _mesa_GetProgramNamedParameterfvNV); SET_GetProgramNamedParameterdvNV(exec, _mesa_GetProgramNamedParameterdvNV); SET_ProgramLocalParameter4dARB(exec, _mesa_ProgramLocalParameter4dARB); SET_ProgramLocalParameter4dvARB(exec, _mesa_ProgramLocalParameter4dvARB); SET_ProgramLocalParameter4fARB(exec, _mesa_ProgramLocalParameter4fARB); SET_ProgramLocalParameter4fvARB(exec, _mesa_ProgramLocalParameter4fvARB); SET_GetProgramLocalParameterdvARB(exec, _mesa_GetProgramLocalParameterdvARB); SET_GetProgramLocalParameterfvARB(exec, _mesa_GetProgramLocalParameterfvARB); } #endif /* 262. GL_NV_point_sprite */ #if _HAVE_FULL_GL SET_PointParameteriNV(exec, _mesa_PointParameteri); SET_PointParameterivNV(exec, _mesa_PointParameteriv); #endif /* 268. GL_EXT_stencil_two_side */ #if _HAVE_FULL_GL if (ctx->API == API_OPENGL) { SET_ActiveStencilFaceEXT(exec, _mesa_ActiveStencilFaceEXT); } #endif /* 285. GL_NV_primitive_restart */ if (ctx->API != API_OPENGLES2) { SET_PrimitiveRestartIndexNV(exec, _mesa_PrimitiveRestartIndex); } /* ???. GL_EXT_depth_bounds_test */ if (ctx->API != API_OPENGLES2) { SET_DepthBoundsEXT(exec, _mesa_DepthBoundsEXT); } /* 352. GL_EXT_transform_feedback */ /* ARB 93. GL_ARB_transform_feedback2 */ if (ctx->API != API_OPENGLES2) { _mesa_init_transform_feedback_dispatch(exec); } /* 364. GL_EXT_provoking_vertex */ if (ctx->API != API_OPENGLES2) { SET_ProvokingVertexEXT(exec, _mesa_ProvokingVertexEXT); } /* ARB 1. GL_ARB_multitexture */ #if _HAVE_FULL_GL SET_ActiveTextureARB(exec, _mesa_ActiveTextureARB); if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { SET_ClientActiveTextureARB(exec, _mesa_ClientActiveTextureARB); } #endif /* ARB 3. GL_ARB_transpose_matrix */ #if _HAVE_FULL_GL if (ctx->API == API_OPENGL) { SET_LoadTransposeMatrixdARB(exec, _mesa_LoadTransposeMatrixdARB); SET_LoadTransposeMatrixfARB(exec, _mesa_LoadTransposeMatrixfARB); SET_MultTransposeMatrixdARB(exec, _mesa_MultTransposeMatrixdARB); SET_MultTransposeMatrixfARB(exec, _mesa_MultTransposeMatrixfARB); } #endif /* ARB 5. GL_ARB_multisample */ #if _HAVE_FULL_GL SET_SampleCoverageARB(exec, _mesa_SampleCoverageARB); #endif /* ARB 12. GL_ARB_texture_compression */ #if _HAVE_FULL_GL if (ctx->API != API_OPENGLES2) { SET_CompressedTexImage1DARB(exec, _mesa_CompressedTexImage1DARB); SET_CompressedTexSubImage1DARB(exec, _mesa_CompressedTexSubImage1DARB); SET_GetCompressedTexImageARB(exec, _mesa_GetCompressedTexImageARB); } SET_CompressedTexImage3DARB(exec, _mesa_CompressedTexImage3DARB); SET_CompressedTexImage2DARB(exec, _mesa_CompressedTexImage2DARB); SET_CompressedTexSubImage3DARB(exec, _mesa_CompressedTexSubImage3DARB); SET_CompressedTexSubImage2DARB(exec, _mesa_CompressedTexSubImage2DARB); /* ARB 104. GL_ARB_robustness */ if (ctx->API != API_OPENGLES2) { SET_GetnCompressedTexImageARB(exec, _mesa_GetnCompressedTexImageARB); } #endif /* ARB 14. GL_ARB_point_parameters */ /* reuse EXT_point_parameters functions */ /* ARB 26. GL_ARB_vertex_program */ /* ARB 27. GL_ARB_fragment_program */ #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program /* glVertexAttrib1sARB aliases glVertexAttrib1sNV */ /* glVertexAttrib1fARB aliases glVertexAttrib1fNV */ /* glVertexAttrib1dARB aliases glVertexAttrib1dNV */ /* glVertexAttrib2sARB aliases glVertexAttrib2sNV */ /* glVertexAttrib2fARB aliases glVertexAttrib2fNV */ /* glVertexAttrib2dARB aliases glVertexAttrib2dNV */ /* glVertexAttrib3sARB aliases glVertexAttrib3sNV */ /* glVertexAttrib3fARB aliases glVertexAttrib3fNV */ /* glVertexAttrib3dARB aliases glVertexAttrib3dNV */ /* glVertexAttrib4sARB aliases glVertexAttrib4sNV */ /* glVertexAttrib4fARB aliases glVertexAttrib4fNV */ /* glVertexAttrib4dARB aliases glVertexAttrib4dNV */ /* glVertexAttrib4NubARB aliases glVertexAttrib4NubNV */ /* glVertexAttrib1svARB aliases glVertexAttrib1svNV */ /* glVertexAttrib1fvARB aliases glVertexAttrib1fvNV */ /* glVertexAttrib1dvARB aliases glVertexAttrib1dvNV */ /* glVertexAttrib2svARB aliases glVertexAttrib2svNV */ /* glVertexAttrib2fvARB aliases glVertexAttrib2fvNV */ /* glVertexAttrib2dvARB aliases glVertexAttrib2dvNV */ /* glVertexAttrib3svARB aliases glVertexAttrib3svNV */ /* glVertexAttrib3fvARB aliases glVertexAttrib3fvNV */ /* glVertexAttrib3dvARB aliases glVertexAttrib3dvNV */ /* glVertexAttrib4svARB aliases glVertexAttrib4svNV */ /* glVertexAttrib4fvARB aliases glVertexAttrib4fvNV */ /* glVertexAttrib4dvARB aliases glVertexAttrib4dvNV */ /* glVertexAttrib4NubvARB aliases glVertexAttrib4NubvNV */ /* glVertexAttrib4bvARB handled in api_loopback.c */ /* glVertexAttrib4ivARB handled in api_loopback.c */ /* glVertexAttrib4ubvARB handled in api_loopback.c */ /* glVertexAttrib4usvARB handled in api_loopback.c */ /* glVertexAttrib4uivARB handled in api_loopback.c */ /* glVertexAttrib4NbvARB handled in api_loopback.c */ /* glVertexAttrib4NsvARB handled in api_loopback.c */ /* glVertexAttrib4NivARB handled in api_loopback.c */ /* glVertexAttrib4NusvARB handled in api_loopback.c */ /* glVertexAttrib4NuivARB handled in api_loopback.c */ SET_VertexAttribPointerARB(exec, _mesa_VertexAttribPointerARB); SET_EnableVertexAttribArrayARB(exec, _mesa_EnableVertexAttribArrayARB); SET_DisableVertexAttribArrayARB(exec, _mesa_DisableVertexAttribArrayARB); if (ctx->API != API_OPENGLES2) { SET_ProgramStringARB(exec, _mesa_ProgramStringARB); /* glBindProgramARB aliases glBindProgramNV */ /* glDeleteProgramsARB aliases glDeleteProgramsNV */ /* glGenProgramsARB aliases glGenProgramsNV */ /* glIsProgramARB aliases glIsProgramNV */ SET_GetVertexAttribdvARB(exec, _mesa_GetVertexAttribdvARB); } SET_GetVertexAttribfvARB(exec, _mesa_GetVertexAttribfvARB); SET_GetVertexAttribivARB(exec, _mesa_GetVertexAttribivARB); /* glGetVertexAttribPointervARB aliases glGetVertexAttribPointervNV */ if (ctx->API == API_OPENGL) { SET_ProgramEnvParameter4dARB(exec, _mesa_ProgramEnvParameter4dARB); SET_ProgramEnvParameter4dvARB(exec, _mesa_ProgramEnvParameter4dvARB); SET_ProgramEnvParameter4fARB(exec, _mesa_ProgramEnvParameter4fARB); SET_ProgramEnvParameter4fvARB(exec, _mesa_ProgramEnvParameter4fvARB); SET_ProgramLocalParameter4dARB(exec, _mesa_ProgramLocalParameter4dARB); SET_ProgramLocalParameter4dvARB(exec, _mesa_ProgramLocalParameter4dvARB); SET_ProgramLocalParameter4fARB(exec, _mesa_ProgramLocalParameter4fARB); SET_ProgramLocalParameter4fvARB(exec, _mesa_ProgramLocalParameter4fvARB); SET_GetProgramEnvParameterdvARB(exec, _mesa_GetProgramEnvParameterdvARB); SET_GetProgramEnvParameterfvARB(exec, _mesa_GetProgramEnvParameterfvARB); SET_GetProgramLocalParameterdvARB(exec, _mesa_GetProgramLocalParameterdvARB); SET_GetProgramLocalParameterfvARB(exec, _mesa_GetProgramLocalParameterfvARB); SET_GetProgramStringARB(exec, _mesa_GetProgramStringARB); } SET_GetProgramivARB(exec, _mesa_GetProgramivARB); #endif /* ARB 28. GL_ARB_vertex_buffer_object */ _mesa_init_bufferobj_dispatch(ctx, exec); /* ARB 29. GL_ARB_occlusion_query */ if (ctx->API != API_OPENGLES2) { _mesa_init_queryobj_dispatch(exec); } /* ARB 37. GL_ARB_draw_buffers */ #if FEATURE_draw_read_buffer SET_DrawBuffersARB(exec, _mesa_DrawBuffersARB); #endif /* ARB 66. GL_ARB_sync */ if (ctx->API != API_OPENGLES2) { _mesa_init_sync_dispatch(exec); } /* ARB 104. GL_ARB_debug_output */ if (ctx->API != API_OPENGLES2) { _mesa_init_errors_dispatch(exec); } /* ARB 105. GL_ARB_robustness */ if (ctx->API != API_OPENGLES2) { SET_GetGraphicsResetStatusARB(exec, _mesa_GetGraphicsResetStatusARB); SET_GetnPolygonStippleARB(exec, _mesa_GetnPolygonStippleARB); SET_GetnTexImageARB(exec, _mesa_GetnTexImageARB); SET_ReadnPixelsARB(exec, _mesa_ReadnPixelsARB); } /* GL_ATI_fragment_shader */ if (ctx->API == API_OPENGL) { _mesa_init_ati_fragment_shader_dispatch(exec); } /* GL_ATI_envmap_bumpmap */ if (ctx->API == API_OPENGL) { SET_GetTexBumpParameterivATI(exec, _mesa_GetTexBumpParameterivATI); SET_GetTexBumpParameterfvATI(exec, _mesa_GetTexBumpParameterfvATI); SET_TexBumpParameterivATI(exec, _mesa_TexBumpParameterivATI); SET_TexBumpParameterfvATI(exec, _mesa_TexBumpParameterfvATI); } #if FEATURE_EXT_framebuffer_object SET_IsRenderbufferEXT(exec, _mesa_IsRenderbufferEXT); SET_BindRenderbufferEXT(exec, _mesa_BindRenderbufferEXT); SET_DeleteRenderbuffersEXT(exec, _mesa_DeleteRenderbuffersEXT); SET_GenRenderbuffersEXT(exec, _mesa_GenRenderbuffersEXT); SET_RenderbufferStorageEXT(exec, _mesa_RenderbufferStorageEXT); SET_GetRenderbufferParameterivEXT(exec, _mesa_GetRenderbufferParameterivEXT); SET_IsFramebufferEXT(exec, _mesa_IsFramebufferEXT); SET_BindFramebufferEXT(exec, _mesa_BindFramebufferEXT); SET_DeleteFramebuffersEXT(exec, _mesa_DeleteFramebuffersEXT); SET_GenFramebuffersEXT(exec, _mesa_GenFramebuffersEXT); SET_CheckFramebufferStatusEXT(exec, _mesa_CheckFramebufferStatusEXT); if (ctx->API != API_OPENGLES2) { SET_FramebufferTexture1DEXT(exec, _mesa_FramebufferTexture1DEXT); } SET_FramebufferTexture2DEXT(exec, _mesa_FramebufferTexture2DEXT); SET_FramebufferTexture3DEXT(exec, _mesa_FramebufferTexture3DEXT); SET_FramebufferRenderbufferEXT(exec, _mesa_FramebufferRenderbufferEXT); SET_GetFramebufferAttachmentParameterivEXT(exec, _mesa_GetFramebufferAttachmentParameterivEXT); SET_GenerateMipmapEXT(exec, _mesa_GenerateMipmapEXT); #endif #if FEATURE_EXT_framebuffer_blit if (ctx->API != API_OPENGLES2) { SET_BlitFramebufferEXT(exec, _mesa_BlitFramebufferEXT); } #endif /* GL_EXT_gpu_program_parameters */ #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program if (ctx->API == API_OPENGL) { SET_ProgramEnvParameters4fvEXT(exec, _mesa_ProgramEnvParameters4fvEXT); SET_ProgramLocalParameters4fvEXT(exec, _mesa_ProgramLocalParameters4fvEXT); } #endif /* GL_MESA_texture_array / GL_EXT_texture_array */ #if FEATURE_EXT_framebuffer_object if (ctx->API != API_OPENGLES2) { SET_FramebufferTextureLayerEXT(exec, _mesa_FramebufferTextureLayerEXT); } #endif /* GL_ATI_separate_stencil */ if (ctx->API == API_OPENGL) { SET_StencilFuncSeparateATI(exec, _mesa_StencilFuncSeparateATI); } #if FEATURE_ARB_framebuffer_object /* The ARB_fbo functions are the union of * GL_EXT_fbo, GL_EXT_framebuffer_blit, GL_EXT_texture_array */ if (ctx->API != API_OPENGLES2) { SET_RenderbufferStorageMultisample(exec, _mesa_RenderbufferStorageMultisample); } #endif #if FEATURE_ARB_map_buffer_range if (ctx->API != API_OPENGLES2) { SET_MapBufferRange(exec, _mesa_MapBufferRange); SET_FlushMappedBufferRange(exec, _mesa_FlushMappedBufferRange); } #endif /* GL_ARB_copy_buffer */ if (ctx->API != API_OPENGLES2) { SET_CopyBufferSubData(exec, _mesa_CopyBufferSubData); } /* GL_ARB_vertex_array_object / GL_OES_vertex_array_object */ SET_BindVertexArray(exec, _mesa_BindVertexArray); SET_GenVertexArrays(exec, _mesa_GenVertexArrays); /* GL_EXT_draw_buffers2 */ if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { SET_ColorMaskIndexedEXT(exec, _mesa_ColorMaskIndexed); SET_GetBooleanIndexedvEXT(exec, _mesa_GetBooleanIndexedv); SET_GetIntegerIndexedvEXT(exec, _mesa_GetIntegerIndexedv); SET_EnableIndexedEXT(exec, _mesa_EnableIndexed); SET_DisableIndexedEXT(exec, _mesa_DisableIndexed); SET_IsEnabledIndexedEXT(exec, _mesa_IsEnabledIndexed); } /* GL_NV_conditional_render */ if (ctx->API != API_OPENGLES2) { SET_BeginConditionalRenderNV(exec, _mesa_BeginConditionalRender); SET_EndConditionalRenderNV(exec, _mesa_EndConditionalRender); } #if FEATURE_OES_EGL_image SET_EGLImageTargetTexture2DOES(exec, _mesa_EGLImageTargetTexture2DOES); SET_EGLImageTargetRenderbufferStorageOES(exec, _mesa_EGLImageTargetRenderbufferStorageOES); #endif #if FEATURE_APPLE_object_purgeable if (ctx->API != API_OPENGLES2) { SET_ObjectPurgeableAPPLE(exec, _mesa_ObjectPurgeableAPPLE); SET_ObjectUnpurgeableAPPLE(exec, _mesa_ObjectUnpurgeableAPPLE); SET_GetObjectParameterivAPPLE(exec, _mesa_GetObjectParameterivAPPLE); } #endif #if FEATURE_ARB_geometry_shader4 if (ctx->API != API_OPENGLES2) { SET_FramebufferTextureARB(exec, _mesa_FramebufferTextureARB); SET_FramebufferTextureFaceARB(exec, _mesa_FramebufferTextureFaceARB); } #endif if (ctx->API != API_OPENGLES2) { SET_ClampColorARB(exec, _mesa_ClampColorARB); } /* GL_EXT_texture_integer */ if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { SET_ClearColorIiEXT(exec, _mesa_ClearColorIiEXT); SET_ClearColorIuiEXT(exec, _mesa_ClearColorIuiEXT); } if (ctx->API != API_OPENGLES2) { SET_GetTexParameterIivEXT(exec, _mesa_GetTexParameterIiv); SET_GetTexParameterIuivEXT(exec, _mesa_GetTexParameterIuiv); SET_TexParameterIivEXT(exec, _mesa_TexParameterIiv); SET_TexParameterIuivEXT(exec, _mesa_TexParameterIuiv); } /* GL_EXT_gpu_shader4 / OpenGL 3.0 */ if (ctx->API != API_OPENGLES2) { SET_GetVertexAttribIivEXT(exec, _mesa_GetVertexAttribIiv); SET_GetVertexAttribIuivEXT(exec, _mesa_GetVertexAttribIuiv); SET_VertexAttribIPointerEXT(exec, _mesa_VertexAttribIPointer); } /* GL 3.0 (functions not covered by other extensions) */ if (ctx->API != API_OPENGLES2) { SET_ClearBufferiv(exec, _mesa_ClearBufferiv); SET_ClearBufferuiv(exec, _mesa_ClearBufferuiv); SET_ClearBufferfv(exec, _mesa_ClearBufferfv); SET_ClearBufferfi(exec, _mesa_ClearBufferfi); SET_GetStringi(exec, _mesa_GetStringi); SET_ClampColor(exec, _mesa_ClampColorARB); } /* GL_ARB_instanced_arrays */ if (ctx->API != API_OPENGLES2) { SET_VertexAttribDivisorARB(exec, _mesa_VertexAttribDivisor); } /* GL_ARB_draw_buffer_blend */ if (ctx->API != API_OPENGLES2) { SET_BlendFunciARB(exec, _mesa_BlendFunci); SET_BlendFuncSeparateiARB(exec, _mesa_BlendFuncSeparatei); SET_BlendEquationiARB(exec, _mesa_BlendEquationi); SET_BlendEquationSeparateiARB(exec, _mesa_BlendEquationSeparatei); } /* GL_NV_texture_barrier */ if (ctx->API != API_OPENGLES2) { SET_TextureBarrierNV(exec, _mesa_TextureBarrierNV); } /* GL_ARB_texture_buffer_object */ if (ctx->API != API_OPENGLES2) { SET_TexBufferARB(exec, _mesa_TexBuffer); } /* GL_ARB_texture_storage */ if (ctx->API != API_OPENGLES2) { SET_TexStorage1D(exec, _mesa_TexStorage1D); SET_TextureStorage1DEXT(exec, _mesa_TextureStorage1DEXT); } SET_TexStorage2D(exec, _mesa_TexStorage2D); SET_TexStorage3D(exec, _mesa_TexStorage3D); SET_TextureStorage2DEXT(exec, _mesa_TextureStorage2DEXT); SET_TextureStorage3DEXT(exec, _mesa_TextureStorage3DEXT); #if FEATURE_ARB_sampler_objects if (ctx->API != API_OPENGLES2) { _mesa_init_sampler_object_dispatch(exec); } #endif if (_mesa_is_desktop_gl(ctx)) { SET_InvalidateTexSubImage(exec, _mesa_InvalidateTexSubImage); SET_InvalidateTexImage(exec, _mesa_InvalidateTexImage); } if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { SET_InvalidateSubFramebuffer(exec, _mesa_InvalidateSubFramebuffer); SET_InvalidateFramebuffer(exec, _mesa_InvalidateFramebuffer); } return exec; }
void GLAPIENTRY _mesa_PointParameterfv( GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); /* Drivers that support point sprites must also support point parameters. * If point parameters aren't supported, then this function shouldn't even * exist. */ ASSERT(!(ctx->Extensions.ARB_point_sprite || ctx->Extensions.NV_point_sprite) || ctx->Extensions.EXT_point_parameters); if (!ctx->Extensions.EXT_point_parameters) { _mesa_error(ctx, GL_INVALID_OPERATION, "unsupported function called (unsupported extension)"); return; } switch (pname) { case GL_DISTANCE_ATTENUATION_EXT: if (TEST_EQ_3V(ctx->Point.Params, params)) return; FLUSH_VERTICES(ctx, _NEW_POINT); COPY_3V(ctx->Point.Params, params); ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 || ctx->Point.Params[1] != 0.0 || ctx->Point.Params[2] != 0.0); if (ctx->Point._Attenuated) ctx->_TriangleCaps |= DD_POINT_ATTEN; else ctx->_TriangleCaps &= ~DD_POINT_ATTEN; break; case GL_POINT_SIZE_MIN_EXT: if (params[0] < 0.0F) { _mesa_error( ctx, GL_INVALID_VALUE, "glPointParameterf[v]{EXT,ARB}(param)" ); return; } if (ctx->Point.MinSize == params[0]) return; FLUSH_VERTICES(ctx, _NEW_POINT); ctx->Point.MinSize = params[0]; break; case GL_POINT_SIZE_MAX_EXT: if (params[0] < 0.0F) { _mesa_error( ctx, GL_INVALID_VALUE, "glPointParameterf[v]{EXT,ARB}(param)" ); return; } if (ctx->Point.MaxSize == params[0]) return; FLUSH_VERTICES(ctx, _NEW_POINT); ctx->Point.MaxSize = params[0]; break; case GL_POINT_FADE_THRESHOLD_SIZE_EXT: if (params[0] < 0.0F) { _mesa_error( ctx, GL_INVALID_VALUE, "glPointParameterf[v]{EXT,ARB}(param)" ); return; } if (ctx->Point.Threshold == params[0]) return; FLUSH_VERTICES(ctx, _NEW_POINT); ctx->Point.Threshold = params[0]; break; case GL_POINT_SPRITE_R_MODE_NV: /* This is one area where ARB_point_sprite and NV_point_sprite * differ. In ARB_point_sprite the POINT_SPRITE_R_MODE is * always ZERO. NV_point_sprite adds the S and R modes. */ if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_point_sprite) { GLenum value = (GLenum) params[0]; if (value != GL_ZERO && value != GL_S && value != GL_R) { _mesa_error(ctx, GL_INVALID_VALUE, "glPointParameterf[v]{EXT,ARB}(param)"); return; } if (ctx->Point.SpriteRMode == value) return; FLUSH_VERTICES(ctx, _NEW_POINT); ctx->Point.SpriteRMode = value; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glPointParameterf[v]{EXT,ARB}(pname)"); return; } break; case GL_POINT_SPRITE_COORD_ORIGIN: /* GL_POINT_SPRITE_COORD_ORIGIN was added to point sprites when the * extension was merged into OpenGL 2.0. */ if ((ctx->API == API_OPENGL && ctx->Version >= 20) || ctx->API == API_OPENGL_CORE) { GLenum value = (GLenum) params[0]; if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) { _mesa_error(ctx, GL_INVALID_VALUE, "glPointParameterf[v]{EXT,ARB}(param)"); return; } if (ctx->Point.SpriteOrigin == value) return; FLUSH_VERTICES(ctx, _NEW_POINT); ctx->Point.SpriteOrigin = value; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glPointParameterf[v]{EXT,ARB}(pname)"); return; } break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glPointParameterf[v]{EXT,ARB}(pname)" ); return; } if (ctx->Driver.PointParameterfv) (*ctx->Driver.PointParameterfv)(ctx, pname, params); }