/** * Execute a glMaterial call. Note that if GL_COLOR_MATERIAL is enabled, * this may be a (partial) no-op. */ static void GLAPIENTRY vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params) { GLbitfield updateMats; GET_CURRENT_CONTEXT(ctx); /* This function should be a no-op when it tries to update material * attributes which are currently tracking glColor via glColorMaterial. * The updateMats var will be a mask of the MAT_BIT_FRONT/BACK_x bits * indicating which material attributes can actually be updated below. */ if (ctx->Light.ColorMaterialEnabled) { updateMats = ~ctx->Light._ColorMaterialBitmask; } else { /* GL_COLOR_MATERIAL is disabled so don't skip any material updates */ updateMats = ALL_MATERIAL_BITS; } if (ctx->API == API_OPENGL_COMPAT && face == GL_FRONT) { updateMats &= FRONT_MATERIAL_BITS; } else if (ctx->API == API_OPENGL_COMPAT && face == GL_BACK) { updateMats &= BACK_MATERIAL_BITS; } else if (face != GL_FRONT_AND_BACK) { _mesa_error(ctx, GL_INVALID_ENUM, "glMaterial(invalid face)"); return; } switch (pname) { case GL_EMISSION: if (updateMats & MAT_BIT_FRONT_EMISSION) MAT_ATTR(VBO_ATTRIB_MAT_FRONT_EMISSION, 4, params); if (updateMats & MAT_BIT_BACK_EMISSION) MAT_ATTR(VBO_ATTRIB_MAT_BACK_EMISSION, 4, params); break; case GL_AMBIENT: if (updateMats & MAT_BIT_FRONT_AMBIENT) MAT_ATTR(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, params); if (updateMats & MAT_BIT_BACK_AMBIENT) MAT_ATTR(VBO_ATTRIB_MAT_BACK_AMBIENT, 4, params); break; case GL_DIFFUSE: if (updateMats & MAT_BIT_FRONT_DIFFUSE) MAT_ATTR(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, params); if (updateMats & MAT_BIT_BACK_DIFFUSE) MAT_ATTR(VBO_ATTRIB_MAT_BACK_DIFFUSE, 4, params); break; case GL_SPECULAR: if (updateMats & MAT_BIT_FRONT_SPECULAR) MAT_ATTR(VBO_ATTRIB_MAT_FRONT_SPECULAR, 4, params); if (updateMats & MAT_BIT_BACK_SPECULAR) MAT_ATTR(VBO_ATTRIB_MAT_BACK_SPECULAR, 4, params); break; case GL_SHININESS: if (*params < 0 || *params > ctx->Const.MaxShininess) { _mesa_error(ctx, GL_INVALID_VALUE, "glMaterial(invalid shininess: %f out range [0, %f])", *params, ctx->Const.MaxShininess); return; } if (updateMats & MAT_BIT_FRONT_SHININESS) MAT_ATTR(VBO_ATTRIB_MAT_FRONT_SHININESS, 1, params); if (updateMats & MAT_BIT_BACK_SHININESS) MAT_ATTR(VBO_ATTRIB_MAT_BACK_SHININESS, 1, params); break; case GL_COLOR_INDEXES: if (ctx->API != API_OPENGL_COMPAT) { _mesa_error(ctx, GL_INVALID_ENUM, "glMaterialfv(pname)"); return; } if (updateMats & MAT_BIT_FRONT_INDEXES) MAT_ATTR(VBO_ATTRIB_MAT_FRONT_INDEXES, 3, params); if (updateMats & MAT_BIT_BACK_INDEXES) MAT_ATTR(VBO_ATTRIB_MAT_BACK_INDEXES, 3, params); break; case GL_AMBIENT_AND_DIFFUSE: if (updateMats & MAT_BIT_FRONT_AMBIENT) MAT_ATTR(VBO_ATTRIB_MAT_FRONT_AMBIENT, 4, params); if (updateMats & MAT_BIT_FRONT_DIFFUSE) MAT_ATTR(VBO_ATTRIB_MAT_FRONT_DIFFUSE, 4, params); if (updateMats & MAT_BIT_BACK_AMBIENT) MAT_ATTR(VBO_ATTRIB_MAT_BACK_AMBIENT, 4, params); if (updateMats & MAT_BIT_BACK_DIFFUSE) MAT_ATTR(VBO_ATTRIB_MAT_BACK_DIFFUSE, 4, params); break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glMaterialfv(pname)"); return; } }
void GLAPIENTRY _mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params) { struct gl_sampler_object *sampObj; GET_CURRENT_CONTEXT(ctx); sampObj = sampler_parameter_error_check(ctx, sampler, true, "glGetSamplerParameterIuiv"); if (!sampObj) return; switch (pname) { case GL_TEXTURE_WRAP_S: *params = sampObj->WrapS; break; case GL_TEXTURE_WRAP_T: *params = sampObj->WrapT; break; case GL_TEXTURE_WRAP_R: *params = sampObj->WrapR; break; case GL_TEXTURE_MIN_FILTER: *params = sampObj->MinFilter; break; case GL_TEXTURE_MAG_FILTER: *params = sampObj->MagFilter; break; case GL_TEXTURE_MIN_LOD: *params = (GLuint) sampObj->MinLod; break; case GL_TEXTURE_MAX_LOD: *params = (GLuint) sampObj->MaxLod; break; case GL_TEXTURE_LOD_BIAS: *params = (GLuint) sampObj->LodBias; break; case GL_TEXTURE_COMPARE_MODE: *params = sampObj->CompareMode; break; case GL_TEXTURE_COMPARE_FUNC: *params = sampObj->CompareFunc; break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: *params = (GLuint) sampObj->MaxAnisotropy; break; case GL_TEXTURE_BORDER_COLOR: params[0] = sampObj->BorderColor.ui[0]; params[1] = sampObj->BorderColor.ui[1]; params[2] = sampObj->BorderColor.ui[2]; params[3] = sampObj->BorderColor.ui[3]; break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) goto invalid_pname; *params = sampObj->CubeMapSeamless; break; case GL_TEXTURE_SRGB_DECODE_EXT: if (!ctx->Extensions.EXT_texture_sRGB_decode) goto invalid_pname; *params = (GLenum) sampObj->sRGBDecode; break; default: goto invalid_pname; } return; invalid_pname: _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)", _mesa_enum_to_string(pname)); }
void GLAPIENTRY _mesa_CreateSamplers(GLsizei count, GLuint *samplers) { GET_CURRENT_CONTEXT(ctx); create_samplers_err(ctx, count, samplers, "glCreateSamplers"); }
/* Push the state into the sarea and/or texture memory. */ static void i915_emit_state(struct intel_context *intel) { struct i915_context *i915 = i915_context(&intel->ctx); struct i915_hw_state *state = &i915->state; int i, count, aper_count; GLuint dirty; drm_intel_bo *aper_array[3 + I915_TEX_UNITS]; GET_CURRENT_CONTEXT(ctx); BATCH_LOCALS; /* We don't hold the lock at this point, so want to make sure that * there won't be a buffer wrap between the state emits and the primitive * emit header. * * It might be better to talk about explicit places where * scheduling is allowed, rather than assume that it is whenever a * batchbuffer fills up. */ intel_batchbuffer_require_space(intel->batch, get_state_size(state) + INTEL_PRIM_EMIT_SIZE, false); count = 0; again: aper_count = 0; dirty = get_dirty(state); aper_array[aper_count++] = intel->batch->buf; if (dirty & I915_UPLOAD_BUFFERS) { aper_array[aper_count++] = state->draw_region->buffer; if (state->depth_region) aper_array[aper_count++] = state->depth_region->buffer; } if (dirty & I915_UPLOAD_TEX_ALL) { for (i = 0; i < I915_TEX_UNITS; i++) { if (dirty & I915_UPLOAD_TEX(i)) { if (state->tex_buffer[i]) { aper_array[aper_count++] = state->tex_buffer[i]; } } } } if (dri_bufmgr_check_aperture_space(aper_array, aper_count)) { if (count == 0) { count++; intel_batchbuffer_flush(intel->batch); goto again; } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "i915 emit state"); assert(0); } } /* work out list of buffers to emit */ /* Do this here as we may have flushed the batchbuffer above, * causing more state to be dirty! */ dirty = get_dirty(state); state->emitted |= dirty; assert(get_dirty(state) == 0); if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty); if (dirty & I915_UPLOAD_INVARIENT) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_INVARIENT:\n"); i915_emit_invarient_state(intel); } if (dirty & I915_UPLOAD_RASTER_RULES) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_RASTER_RULES:\n"); emit(intel, state->RasterRules, sizeof(state->RasterRules)); } if (dirty & I915_UPLOAD_CTX) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_CTX:\n"); emit(intel, state->Ctx, sizeof(state->Ctx)); } if (dirty & I915_UPLOAD_BUFFERS) { GLuint count; if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); count = 14; if (state->Buffer[I915_DESTREG_DRAWRECT0] != MI_NOOP) count++; if (state->depth_region) count += 3; BEGIN_BATCH(count); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); OUT_RELOC(state->draw_region->buffer, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); if (state->depth_region) { OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); OUT_RELOC(state->depth_region->buffer, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); } OUT_BATCH(state->Buffer[I915_DESTREG_DV0]); OUT_BATCH(state->Buffer[I915_DESTREG_DV1]); OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]); OUT_BATCH(state->Buffer[I915_DESTREG_SR0]); OUT_BATCH(state->Buffer[I915_DESTREG_SR1]); OUT_BATCH(state->Buffer[I915_DESTREG_SR2]); if (state->Buffer[I915_DESTREG_DRAWRECT0] != MI_NOOP) OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT0]); OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT1]); OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT2]); OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT3]); OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT4]); OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT5]); ADVANCE_BATCH(); } if (dirty & I915_UPLOAD_STIPPLE) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n"); emit(intel, state->Stipple, sizeof(state->Stipple)); } if (dirty & I915_UPLOAD_FOG) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_FOG:\n"); emit(intel, state->Fog, sizeof(state->Fog)); } /* Combine all the dirty texture state into a single command to * avoid lockups on I915 hardware. */ if (dirty & I915_UPLOAD_TEX_ALL) { int nr = 0; for (i = 0; i < I915_TEX_UNITS; i++) if (dirty & I915_UPLOAD_TEX(i)) nr++; BEGIN_BATCH(2 + nr * 3); OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); for (i = 0; i < I915_TEX_UNITS; i++) if (dirty & I915_UPLOAD_TEX(i)) { if (state->tex_buffer[i]) { OUT_RELOC(state->tex_buffer[i], I915_GEM_DOMAIN_SAMPLER, 0, state->tex_offset[i]); } else { OUT_BATCH(state->tex_offset[i]); } OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); } ADVANCE_BATCH(); BEGIN_BATCH(2 + nr * 3); OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr)); OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); for (i = 0; i < I915_TEX_UNITS; i++) if (dirty & I915_UPLOAD_TEX(i)) { OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]); OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]); OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]); } ADVANCE_BATCH(); }
void GLAPIENTRY _mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params) { struct gl_sampler_object *sampObj; GLuint res; GET_CURRENT_CONTEXT(ctx); sampObj = sampler_parameter_error_check(ctx, sampler, false, "glSamplerParameterIuiv"); if (!sampObj) return; switch (pname) { case GL_TEXTURE_WRAP_S: res = set_sampler_wrap_s(ctx, sampObj, params[0]); break; case GL_TEXTURE_WRAP_T: res = set_sampler_wrap_t(ctx, sampObj, params[0]); break; case GL_TEXTURE_WRAP_R: res = set_sampler_wrap_r(ctx, sampObj, params[0]); break; case GL_TEXTURE_MIN_FILTER: res = set_sampler_min_filter(ctx, sampObj, params[0]); break; case GL_TEXTURE_MAG_FILTER: res = set_sampler_mag_filter(ctx, sampObj, params[0]); break; case GL_TEXTURE_MIN_LOD: res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]); break; case GL_TEXTURE_MAX_LOD: res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]); break; case GL_TEXTURE_LOD_BIAS: res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]); break; case GL_TEXTURE_COMPARE_MODE: res = set_sampler_compare_mode(ctx, sampObj, params[0]); break; case GL_TEXTURE_COMPARE_FUNC: res = set_sampler_compare_func(ctx, sampObj, params[0]); break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]); break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]); break; case GL_TEXTURE_SRGB_DECODE_EXT: res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]); break; case GL_TEXTURE_BORDER_COLOR: res = set_sampler_border_colorui(ctx, sampObj, params); break; default: res = INVALID_PNAME; } switch (res) { case GL_FALSE: /* no change */ break; case GL_TRUE: /* state change - we do nothing special at this time */ break; case INVALID_PNAME: _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(pname=%s)\n", _mesa_enum_to_string(pname)); break; case INVALID_PARAM: _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(param=%u)\n", params[0]); break; case INVALID_VALUE: _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(param=%u)\n", params[0]); break; default: ; } }
/* * Execute glDrawPixels */ void GLAPIENTRY _mesa_DrawPixels( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels ) { GLenum err; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glDrawPixels(%d, %d, %s, %s, %p) // to %s at %d, %d\n", width, height, _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type), pixels, _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer[0]), IROUND(ctx->Current.RasterPos[0]), IROUND(ctx->Current.RasterPos[1])); if (width < 0 || height < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glDrawPixels(width or height < 0)" ); return; } /* We're not using the current vertex program, and the driver may install * its own. Note: this may dirty some state. */ _mesa_set_vp_override(ctx, GL_TRUE); /* Note: this call does state validation */ if (!_mesa_valid_to_render(ctx, "glDrawPixels")) { goto end; /* the error code was recorded */ } /* GL 3.0 introduced a new restriction on glDrawPixels() over what was in * GL_EXT_texture_integer. From section 3.7.4 ("Rasterization of Pixel * Rectangles) on page 151 of the GL 3.0 specification: * * "If format contains integer components, as shown in table 3.6, an * INVALID OPERATION error is generated." * * Since DrawPixels rendering would be merely undefined if not an error (due * to a lack of defined mapping from integer data to gl_Color fragment shader * input), NVIDIA's implementation also just returns this error despite * exposing GL_EXT_texture_integer, just return an error regardless. */ if (_mesa_is_enum_format_integer(format)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(integer format)"); goto end; } err = _mesa_error_check_format_and_type(ctx, format, type); if (err != GL_NO_ERROR) { _mesa_error(ctx, err, "glDrawPixels(invalid format %s and/or type %s)", _mesa_lookup_enum_by_nr(format), _mesa_lookup_enum_by_nr(type)); goto end; } /* do special format-related checks */ switch (format) { case GL_STENCIL_INDEX: case GL_DEPTH_COMPONENT: case GL_DEPTH_STENCIL_EXT: /* these buffers must exist */ if (!_mesa_dest_buffer_exists(ctx, format)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(missing deest buffer)"); goto end; } break; case GL_COLOR_INDEX: if (ctx->PixelMaps.ItoR.Size == 0 || ctx->PixelMaps.ItoG.Size == 0 || ctx->PixelMaps.ItoB.Size == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(drawing color index pixels into RGB buffer)"); goto end; } break; default: /* for color formats it's not an error if the destination color * buffer doesn't exist. */ break; } if (ctx->RasterDiscard) { goto end; } if (!ctx->Current.RasterPosValid) { goto end; /* no-op, not an error */ } if (ctx->RenderMode == GL_RENDER) { if (width > 0 && height > 0) { /* Round, to satisfy conformance tests (matches SGI's OpenGL) */ GLint x = IROUND(ctx->Current.RasterPos[0]); GLint y = IROUND(ctx->Current.RasterPos[1]); if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { /* unpack from PBO */ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, format, type, INT_MAX, pixels)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(invalid PBO access)"); goto end; } if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) { /* buffer is mapped - that's an error */ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels(PBO is mapped)"); goto end; } } ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type, &ctx->Unpack, pixels); } } else if (ctx->RenderMode == GL_FEEDBACK) { /* Feedback the current raster pos info */ FLUSH_CURRENT( ctx, 0 ); _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN ); _mesa_feedback_vertex( ctx, ctx->Current.RasterPos, ctx->Current.RasterColor, ctx->Current.RasterTexCoords[0] ); } else { ASSERT(ctx->RenderMode == GL_SELECT); /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */ } end: _mesa_set_vp_override(ctx, GL_FALSE); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { _mesa_flush(ctx); } }
void GLAPIENTRY _mesa_ViewportIndexedfv_no_error(GLuint index, const GLfloat *v) { GET_CURRENT_CONTEXT(ctx); _mesa_set_viewport(ctx, index, v[0], v[1], v[2], v[3]); }
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_COMPAT && 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); }
GLFBDevContextPtr glFBDevGetCurrentContext( void ) { GET_CURRENT_CONTEXT(ctx); return (GLFBDevContextPtr) ctx; }
/* Push the state into the sarea and/or texture memory. */ static void i915_emit_state(struct intel_context *intel) { struct i915_context *i915 = i915_context(&intel->ctx); struct i915_hw_state *state = i915->current; int i; int ret, count; GLuint dirty; GET_CURRENT_CONTEXT(ctx); BATCH_LOCALS; /* We don't hold the lock at this point, so want to make sure that * there won't be a buffer wrap between the state emits and the primitive * emit header. * * It might be better to talk about explicit places where * scheduling is allowed, rather than assume that it is whenever a * batchbuffer fills up. * * Set the space as LOOP_CLIPRECTS now, since that's what our primitives * will be emitted under. */ intel_batchbuffer_require_space(intel->batch, get_state_size(state) + 8, LOOP_CLIPRECTS); count = 0; again: dirty = get_dirty(state); ret = 0; if (dirty & I915_UPLOAD_BUFFERS) { ret |= dri_bufmgr_check_aperture_space(state->draw_region->buffer); if (state->depth_region) ret |= dri_bufmgr_check_aperture_space(state->depth_region->buffer); } if (dirty & I915_UPLOAD_TEX_ALL) { for (i = 0; i < I915_TEX_UNITS; i++) if (dirty & I915_UPLOAD_TEX(i)) { if (state->tex_buffer[i]) { ret |= dri_bufmgr_check_aperture_space(state->tex_buffer[i]); } } } if (ret) { if (count == 0) { count++; intel_batchbuffer_flush(intel->batch); goto again; } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "i915 emit state"); assert(0); } } /* work out list of buffers to emit */ /* Do this here as we may have flushed the batchbuffer above, * causing more state to be dirty! */ dirty = get_dirty(state); state->emitted |= dirty; assert(get_dirty(state) == 0); if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty); if (dirty & I915_UPLOAD_INVARIENT) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_INVARIENT:\n"); i915_emit_invarient_state(intel); } if (dirty & I915_UPLOAD_CTX) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_CTX:\n"); emit(intel, state->Ctx, sizeof(state->Ctx)); } if (dirty & I915_UPLOAD_BUFFERS) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n"); BEGIN_BATCH(I915_DEST_SETUP_SIZE + 2, IGNORE_CLIPRECTS); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); OUT_RELOC(state->draw_region->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, state->draw_region->draw_offset); if (state->depth_region) { OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); OUT_RELOC(state->depth_region->buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE, state->depth_region->draw_offset); } OUT_BATCH(state->Buffer[I915_DESTREG_DV0]); OUT_BATCH(state->Buffer[I915_DESTREG_DV1]); OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]); OUT_BATCH(state->Buffer[I915_DESTREG_SR0]); OUT_BATCH(state->Buffer[I915_DESTREG_SR1]); OUT_BATCH(state->Buffer[I915_DESTREG_SR2]); ADVANCE_BATCH(); } if (dirty & I915_UPLOAD_STIPPLE) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n"); emit(intel, state->Stipple, sizeof(state->Stipple)); } if (dirty & I915_UPLOAD_FOG) { if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_FOG:\n"); emit(intel, state->Fog, sizeof(state->Fog)); } /* Combine all the dirty texture state into a single command to * avoid lockups on I915 hardware. */ if (dirty & I915_UPLOAD_TEX_ALL) { int nr = 0; for (i = 0; i < I915_TEX_UNITS; i++) if (dirty & I915_UPLOAD_TEX(i)) nr++; BEGIN_BATCH(2 + nr * 3, IGNORE_CLIPRECTS); OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); for (i = 0; i < I915_TEX_UNITS; i++) if (dirty & I915_UPLOAD_TEX(i)) { if (state->tex_buffer[i]) { OUT_RELOC(state->tex_buffer[i], DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, state->tex_offset[i]); } else if (state == &i915->meta) { assert(i == 0); OUT_BATCH(0); } else { OUT_BATCH(state->tex_offset[i]); } OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); } ADVANCE_BATCH(); BEGIN_BATCH(2 + nr * 3, IGNORE_CLIPRECTS); OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3 * nr)); OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT); for (i = 0; i < I915_TEX_UNITS; i++) if (dirty & I915_UPLOAD_TEX(i)) { OUT_BATCH(state->Tex[i][I915_TEXREG_SS2]); OUT_BATCH(state->Tex[i][I915_TEXREG_SS3]); OUT_BATCH(state->Tex[i][I915_TEXREG_SS4]); } ADVANCE_BATCH(); }
/** * \brief Optimized glReadPixels(). * * To be used with particular pixel formats GL_UNSIGNED_BYTE and GL_RGBA, when pixel * scaling, biasing and mapping are disabled. * * \param x x start position of the reading rectangle. * \param y y start position of the reading rectangle. * \param width width of the reading rectangle. * \param height height of the reading rectangle. * \param format pixel format. Must be GL_RGBA. * \param type pixel type. Must be GL_UNSIGNED_BYTE. * \param pixels pixel data. * * After asserting the above conditions, compensates for clipping and calls * ReadRGBASpan() to read each row. */ void radeonReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ) { GET_CURRENT_CONTEXT(ctx); GLint srcX = x; GLint srcY = y; GLint readWidth = width; /* actual width read */ GLint readHeight = height; /* actual height read */ const struct gl_pixelstore_attrib *packing = &ctx->Pack; GLint skipRows = packing->SkipRows; GLint skipPixels = packing->SkipPixels; GLint rowLength; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); { GLint tmp, tmps; tmp = x; x = y; y = tmp; tmps = width; width = height; height = tmps; } if (width < 0 || height < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(width=%d height=%d)", width, height ); return; } if (!pixels) { _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" ); return; } if (ctx->NewState) _mesa_update_state(ctx); /* can't do scale, bias, mapping, etc */ assert(!ctx->_ImageTransferState); /* can't do fancy pixel packing */ assert (packing->Alignment == 1 && !packing->SwapBytes && !packing->LsbFirst); if (packing->RowLength > 0) rowLength = packing->RowLength; else rowLength = width; /* horizontal clipping */ if (srcX < 0) { skipPixels -= srcX; readWidth += srcX; srcX = 0; } if (srcX + readWidth > (GLint) ctx->ReadBuffer->Width) readWidth -= (srcX + readWidth - (GLint) ctx->ReadBuffer->Width); if (readWidth <= 0) return; /* vertical clipping */ if (srcY < 0) { skipRows -= srcY; readHeight += srcY; srcY = 0; } if (srcY + readHeight > (GLint) ctx->ReadBuffer->Height) readHeight -= (srcY + readHeight - (GLint) ctx->ReadBuffer->Height); if (readHeight <= 0) return; /* * Ready to read! * The window region at (destX, destY) of size (readWidth, readHeight) * will be read back. * We'll write pixel data to buffer pointed to by "pixels" but we'll * skip "skipRows" rows and skip "skipPixels" pixels/row. */ if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { GLchan *dest = (GLchan *) pixels + (skipRows * rowLength + skipPixels) * 4; GLint row; for (row=0; row<readHeight; row++) { ReadRGBASpan(ctx, readWidth, srcX, srcY, (GLchan (*)[4]) dest); dest += rowLength * 4; srcY++; } } else { /* can't do this format/type combination */ assert(0); } }
/** * Set the current matrix stack. * * \param mode matrix stack. * * \sa glMatrixMode(). * * Flushes the vertices, validates the parameter and updates * __GLcontextRec::CurrentStack and gl_transform_attrib::MatrixMode with the * specified matrix stack. */ void GLAPIENTRY _mesa_MatrixMode( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (ctx->Transform.MatrixMode == mode && mode != GL_TEXTURE) return; FLUSH_VERTICES(ctx, _NEW_TRANSFORM); switch (mode) { case GL_MODELVIEW: ctx->CurrentStack = &ctx->ModelviewMatrixStack; break; case GL_PROJECTION: ctx->CurrentStack = &ctx->ProjectionMatrixStack; break; case GL_TEXTURE: if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMatrixMode(texcoord unit)"); return; } ctx->CurrentStack = &ctx->TextureMatrixStack[ctx->Texture.CurrentUnit]; break; case GL_COLOR: ctx->CurrentStack = &ctx->ColorMatrixStack; break; case GL_MATRIX0_NV: case GL_MATRIX1_NV: case GL_MATRIX2_NV: case GL_MATRIX3_NV: case GL_MATRIX4_NV: case GL_MATRIX5_NV: case GL_MATRIX6_NV: case GL_MATRIX7_NV: if (ctx->Extensions.NV_vertex_program) { ctx->CurrentStack = &ctx->ProgramMatrixStack[mode - GL_MATRIX0_NV]; } else { _mesa_error( ctx, GL_INVALID_ENUM, "glMatrixMode(mode)" ); return; } break; case GL_MATRIX0_ARB: case GL_MATRIX1_ARB: case GL_MATRIX2_ARB: case GL_MATRIX3_ARB: case GL_MATRIX4_ARB: case GL_MATRIX5_ARB: case GL_MATRIX6_ARB: case GL_MATRIX7_ARB: if (ctx->Extensions.ARB_vertex_program || ctx->Extensions.ARB_fragment_program) { const GLuint m = mode - GL_MATRIX0_ARB; if (m > ctx->Const.MaxProgramMatrices) { _mesa_error(ctx, GL_INVALID_ENUM, "glMatrixMode(GL_MATRIX%d_ARB)", m); return; } ctx->CurrentStack = &ctx->ProgramMatrixStack[m]; } else { _mesa_error( ctx, GL_INVALID_ENUM, "glMatrixMode(mode)" ); return; } break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glMatrixMode(mode)" ); return; } ctx->Transform.MatrixMode = mode; }
extern "C" void GLAPIENTRY _mesa_GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; GLsizei i; shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); if (!shProg) return; if (uniformCount < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(uniformCount < 0)"); return; } for (i = 0; i < uniformCount; i++) { GLuint index = uniformIndices[i]; if (index >= shProg->NumUserUniformStorage) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)"); return; } } for (i = 0; i < uniformCount; i++) { GLuint index = uniformIndices[i]; const struct gl_uniform_storage *uni = &shProg->UniformStorage[index]; switch (pname) { case GL_UNIFORM_TYPE: params[i] = uni->type->gl_type; break; case GL_UNIFORM_SIZE: /* array_elements is zero for non-arrays, but the API requires that 1 be * returned. */ params[i] = MAX2(1, uni->array_elements); break; case GL_UNIFORM_NAME_LENGTH: params[i] = strlen(uni->name) + 1; /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0 * spec says: * * "If the active uniform is an array, the uniform name returned * in name will always be the name of the uniform array appended * with "[0]"." */ if (uni->array_elements != 0) params[i] += 3; break; case GL_UNIFORM_BLOCK_INDEX: params[i] = uni->block_index; break; case GL_UNIFORM_OFFSET: params[i] = uni->offset; break; case GL_UNIFORM_ARRAY_STRIDE: params[i] = uni->array_stride; break; case GL_UNIFORM_MATRIX_STRIDE: params[i] = uni->matrix_stride; break; case GL_UNIFORM_IS_ROW_MAJOR: params[i] = uni->row_major; break; case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX: if (!ctx->Extensions.ARB_shader_atomic_counters) goto invalid_enum; params[i] = uni->atomic_buffer_index; break; default: goto invalid_enum; } } return; invalid_enum: _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)"); }
/** * Blit rectangular region, optionally from one framebuffer to another. * * Note, if the src buffer is multisampled and the dest is not, this is * when the samples must be resolved to a single color. */ void GLAPIENTRY _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { const GLbitfield legalMaskBits = (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); const struct gl_framebuffer *readFb, *drawFb; GET_CURRENT_CONTEXT(ctx); FLUSH_VERTICES(ctx, 0); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, 0x%x, %s)\n", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, _mesa_lookup_enum_by_nr(filter)); if (ctx->NewState) { _mesa_update_state(ctx); } readFb = ctx->ReadBuffer; drawFb = ctx->DrawBuffer; if (!readFb || !drawFb) { /* This will normally never happen but someday we may want to * support MakeCurrent() with no drawables. */ return; } /* check for complete framebuffers */ if (drawFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT || readFb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "glBlitFramebufferEXT(incomplete draw/read buffers)"); return; } if (!is_valid_blit_filter(ctx, filter)) { _mesa_error(ctx, GL_INVALID_ENUM, "glBlitFramebufferEXT(%s)", _mesa_lookup_enum_by_nr(filter)); return; } if ((filter == GL_SCALED_RESOLVE_FASTEST_EXT || filter == GL_SCALED_RESOLVE_NICEST_EXT) && (readFb->Visual.samples == 0 || drawFb->Visual.samples > 0)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(%s)", _mesa_lookup_enum_by_nr(filter)); return; } if (mask & ~legalMaskBits) { _mesa_error( ctx, GL_INVALID_VALUE, "glBlitFramebufferEXT(mask)"); return; } /* depth/stencil must be blitted with nearest filtering */ if ((mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) && filter != GL_NEAREST) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(depth/stencil requires GL_NEAREST filter)"); return; } /* get color read/draw renderbuffers */ if (mask & GL_COLOR_BUFFER_BIT) { const GLuint numColorDrawBuffers = ctx->DrawBuffer->_NumColorDrawBuffers; const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; const struct gl_renderbuffer *colorDrawRb = NULL; GLuint i; /* From the EXT_framebuffer_object spec: * * "If a buffer is specified in <mask> and does not exist in both * the read and draw framebuffers, the corresponding bit is silently * ignored." */ if (!colorReadRb || numColorDrawBuffers == 0) { mask &= ~GL_COLOR_BUFFER_BIT; } else { for (i = 0; i < numColorDrawBuffers; i++) { colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i]; if (!colorDrawRb) continue; /* Page 193 (page 205 of the PDF) in section 4.3.2 of the OpenGL * ES 3.0.1 spec says: * * "If the source and destination buffers are identical, an * INVALID_OPERATION error is generated. Different mipmap * levels of a texture, different layers of a three- * dimensional texture or two-dimensional array texture, and * different faces of a cube map texture do not constitute * identical buffers." */ if (_mesa_is_gles3(ctx) && (colorDrawRb == colorReadRb)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer(source and destination color " "buffer cannot be the same)"); return; } if (!compatible_color_datatypes(colorReadRb->Format, colorDrawRb->Format)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(color buffer datatypes mismatch)"); return; } /* extra checks for multisample copies... */ if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) { /* color formats must match */ if (!compatible_resolve_formats(colorReadRb, colorDrawRb)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(bad src/dst multisample pixel formats)"); return; } } } if (filter != GL_NEAREST) { /* From EXT_framebuffer_multisample_blit_scaled specification: * "Calling BlitFramebuffer will result in an INVALID_OPERATION error * if filter is not NEAREST and read buffer contains integer data." */ GLenum type = _mesa_get_format_datatype(colorReadRb->Format); if (type == GL_INT || type == GL_UNSIGNED_INT) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(integer color type)"); return; } } } } if (mask & GL_STENCIL_BUFFER_BIT) { struct gl_renderbuffer *readRb = readFb->Attachment[BUFFER_STENCIL].Renderbuffer; struct gl_renderbuffer *drawRb = drawFb->Attachment[BUFFER_STENCIL].Renderbuffer; /* From the EXT_framebuffer_object spec: * * "If a buffer is specified in <mask> and does not exist in both * the read and draw framebuffers, the corresponding bit is silently * ignored." */ if ((readRb == NULL) || (drawRb == NULL)) { mask &= ~GL_STENCIL_BUFFER_BIT; } else { int read_z_bits, draw_z_bits; if (_mesa_is_gles3(ctx) && (drawRb == readRb)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer(source and destination stencil " "buffer cannot be the same)"); return; } if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) != _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) { /* There is no need to check the stencil datatype here, because * there is only one: GL_UNSIGNED_INT. */ _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer(stencil attachment format mismatch)"); return; } read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS); draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS); /* If both buffers also have depth data, the depth formats must match * as well. If one doesn't have depth, it's not blitted, so we should * ignore the depth format check. */ if (read_z_bits > 0 && draw_z_bits > 0 && (read_z_bits != draw_z_bits || _mesa_get_format_datatype(readRb->Format) != _mesa_get_format_datatype(drawRb->Format))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer" "(stencil attachment depth format mismatch)"); return; } } } if (mask & GL_DEPTH_BUFFER_BIT) { struct gl_renderbuffer *readRb = readFb->Attachment[BUFFER_DEPTH].Renderbuffer; struct gl_renderbuffer *drawRb = drawFb->Attachment[BUFFER_DEPTH].Renderbuffer; /* From the EXT_framebuffer_object spec: * * "If a buffer is specified in <mask> and does not exist in both * the read and draw framebuffers, the corresponding bit is silently * ignored." */ if ((readRb == NULL) || (drawRb == NULL)) { mask &= ~GL_DEPTH_BUFFER_BIT; } else { int read_s_bit, draw_s_bit; if (_mesa_is_gles3(ctx) && (drawRb == readRb)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer(source and destination depth " "buffer cannot be the same)"); return; } if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) != _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) || (_mesa_get_format_datatype(readRb->Format) != _mesa_get_format_datatype(drawRb->Format))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer(depth attachment format mismatch)"); return; } read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS); draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS); /* If both buffers also have stencil data, the stencil formats must * match as well. If one doesn't have stencil, it's not blitted, so * we should ignore the stencil format check. */ if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer" "(depth attachment stencil bits mismatch)"); return; } } } if (_mesa_is_gles3(ctx)) { /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES * 3.0.1 spec says: * * "If SAMPLE_BUFFERS for the draw framebuffer is greater than zero, * an INVALID_OPERATION error is generated." */ if (drawFb->Visual.samples > 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer(destination samples must be 0)"); return; } /* Page 194 (page 206 of the PDF) in section 4.3.2 of the OpenGL ES * 3.0.1 spec says: * * "If SAMPLE_BUFFERS for the read framebuffer is greater than zero, * no copy is performed and an INVALID_OPERATION error is generated * if the formats of the read and draw framebuffers are not * identical or if the source and destination rectangles are not * defined with the same (X0, Y0) and (X1, Y1) bounds." * * The format check was made above because desktop OpenGL has the same * requirement. */ if (readFb->Visual.samples > 0 && (srcX0 != dstX0 || srcY0 != dstY0 || srcX1 != dstX1 || srcY1 != dstY1)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer(bad src/dst multisample region)"); return; } } else { if (readFb->Visual.samples > 0 && drawFb->Visual.samples > 0 && readFb->Visual.samples != drawFb->Visual.samples) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(mismatched samples)"); return; } /* extra checks for multisample copies... */ if ((readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) && (filter == GL_NEAREST || filter == GL_LINEAR)) { /* src and dest region sizes must be the same */ if (abs(srcX1 - srcX0) != abs(dstX1 - dstX0) || abs(srcY1 - srcY0) != abs(dstY1 - dstY0)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebufferEXT(bad src/dst multisample region sizes)"); return; } } } /* Debug code */ if (DEBUG_BLIT) { const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer; const struct gl_renderbuffer *colorDrawRb = NULL; GLuint i = 0; printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d," " 0x%x, 0x%x)\n", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); if (colorReadRb) { const struct gl_renderbuffer_attachment *att; att = find_attachment(readFb, colorReadRb); printf(" Src FBO %u RB %u (%dx%d) ", readFb->Name, colorReadRb->Name, colorReadRb->Width, colorReadRb->Height); if (att && att->Texture) { printf("Tex %u tgt 0x%x level %u face %u", att->Texture->Name, att->Texture->Target, att->TextureLevel, att->CubeMapFace); } printf("\n"); /* Print all active color render buffers */ for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i]; if (!colorDrawRb) continue; att = find_attachment(drawFb, colorDrawRb); printf(" Dst FBO %u RB %u (%dx%d) ", drawFb->Name, colorDrawRb->Name, colorDrawRb->Width, colorDrawRb->Height); if (att && att->Texture) { printf("Tex %u tgt 0x%x level %u face %u", att->Texture->Name, att->Texture->Target, att->TextureLevel, att->CubeMapFace); } printf("\n"); } } } if (!mask || (srcX1 - srcX0) == 0 || (srcY1 - srcY0) == 0 || (dstX1 - dstX0) == 0 || (dstY1 - dstY0) == 0) { return; } ASSERT(ctx->Driver.BlitFramebuffer); ctx->Driver.BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); }
void GLAPIENTRY _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, GLenum type ) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glCopyPixels(%d, %d, %d, %d, %s) // from %s to %s at %d, %d\n", srcx, srcy, width, height, _mesa_lookup_enum_by_nr(type), _mesa_lookup_enum_by_nr(ctx->ReadBuffer->ColorReadBuffer), _mesa_lookup_enum_by_nr(ctx->DrawBuffer->ColorDrawBuffer[0]), IROUND(ctx->Current.RasterPos[0]), IROUND(ctx->Current.RasterPos[1])); if (width < 0 || height < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)"); return; } /* Note: more detailed 'type' checking is done by the * _mesa_source/dest_buffer_exists() calls below. That's where we * check if the stencil buffer exists, etc. */ if (type != GL_COLOR && type != GL_DEPTH && type != GL_STENCIL && type != GL_DEPTH_STENCIL) { _mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels(type=%s)", _mesa_lookup_enum_by_nr(type)); return; } /* We're not using the current vertex program, and the driver may install * it's own. Note: this may dirty some state. */ _mesa_set_vp_override(ctx, GL_TRUE); /* Note: this call does state validation */ if (!_mesa_valid_to_render(ctx, "glCopyPixels")) { goto end; /* the error code was recorded */ } /* Check read buffer's status (draw buffer was already checked) */ if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "glCopyPixels(incomplete framebuffer)" ); goto end; } if (_mesa_is_user_fbo(ctx->ReadBuffer) && ctx->ReadBuffer->Visual.samples > 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyPixels(multisample FBO)"); goto end; } if (!_mesa_source_buffer_exists(ctx, type) || !_mesa_dest_buffer_exists(ctx, type)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyPixels(missing source or dest buffer)"); goto end; } if (ctx->RasterDiscard) { goto end; } if (!ctx->Current.RasterPosValid || width == 0 || height == 0) { goto end; /* no-op, not an error */ } if (ctx->RenderMode == GL_RENDER) { /* Round to satisfy conformance tests (matches SGI's OpenGL) */ if (width > 0 && height > 0) { GLint destx = IROUND(ctx->Current.RasterPos[0]); GLint desty = IROUND(ctx->Current.RasterPos[1]); ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty, type ); } } else if (ctx->RenderMode == GL_FEEDBACK) { FLUSH_CURRENT( ctx, 0 ); _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN ); _mesa_feedback_vertex( ctx, ctx->Current.RasterPos, ctx->Current.RasterColor, ctx->Current.RasterTexCoords[0] ); } else { ASSERT(ctx->RenderMode == GL_SELECT); /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */ } end: _mesa_set_vp_override(ctx, GL_FALSE); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { _mesa_flush(ctx); } }
/** * 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; const char *callerstr; if (_mesa_is_desktop_gl(ctx)) callerstr = "glGetPointerv"; else callerstr = "glGetPointervKHR"; if (!params) return; if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "%s %s\n", callerstr, _mesa_enum_to_string(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.VAO->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.VAO->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.VAO->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.VAO->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.VAO->VertexAttrib[VERT_ATTRIB_FOG].Ptr; break; case GL_INDEX_ARRAY_POINTER: if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; *params = (GLvoid *) ctx->Array.VAO->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.VAO->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.VAO->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.VAO->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Ptr; break; case GL_DEBUG_CALLBACK_FUNCTION_ARB: case GL_DEBUG_CALLBACK_USER_PARAM_ARB: *params = _mesa_get_debug_state_ptr(ctx, pname); break; default: goto invalid_pname; } return; invalid_pname: _mesa_error( ctx, GL_INVALID_ENUM, "%s", callerstr); return; }
void GLAPIENTRY _mesa_Bitmap( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap ) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (width < 0 || height < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" ); return; } if (!ctx->Current.RasterPosValid) { return; /* do nothing */ } /* Note: this call does state validation */ if (!_mesa_valid_to_render(ctx, "glBitmap")) { /* the error code was recorded */ return; } if (ctx->RasterDiscard) return; if (ctx->RenderMode == GL_RENDER) { /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */ if (width > 0 && height > 0) { const GLfloat epsilon = 0.0001F; GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig); GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig); if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) { /* unpack from PBO */ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, GL_COLOR_INDEX, GL_BITMAP, INT_MAX, (const GLvoid *) bitmap)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(invalid PBO access)"); return; } if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) { /* buffer is mapped - that's an error */ _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)"); return; } } ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap ); } } else if (ctx->RenderMode == GL_FEEDBACK) { FLUSH_CURRENT(ctx, 0); _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN ); _mesa_feedback_vertex( ctx, ctx->Current.RasterPos, ctx->Current.RasterColor, ctx->Current.RasterTexCoords[0] ); } else { ASSERT(ctx->RenderMode == GL_SELECT); /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */ } /* update raster position */ ctx->Current.RasterPos[0] += xmove; ctx->Current.RasterPos[1] += ymove; if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { _mesa_flush(ctx); } }
extern "C" void GLAPIENTRY _mesa_GetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; GLsizei i; shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); if (!shProg) return; if (uniformCount < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformIndices(uniformCount < 0)"); return; } for (i = 0; i < uniformCount; i++) { GLuint index = uniformIndices[i]; const struct gl_uniform_storage *uni = &shProg->UniformStorage[index]; if (index >= shProg->NumUserUniformStorage) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)"); return; } switch (pname) { case GL_UNIFORM_TYPE: params[i] = uni->type->gl_type; break; case GL_UNIFORM_SIZE: /* array_elements is zero for non-arrays, but the API requires that 1 be * returned. */ params[i] = MAX2(1, uni->array_elements); break; case GL_UNIFORM_NAME_LENGTH: params[i] = strlen(uni->name) + 1; break; case GL_UNIFORM_BLOCK_INDEX: params[i] = uni->block_index; break; case GL_UNIFORM_OFFSET: params[i] = uni->offset; break; case GL_UNIFORM_ARRAY_STRIDE: params[i] = uni->array_stride; break; case GL_UNIFORM_MATRIX_STRIDE: params[i] = uni->matrix_stride; break; case GL_UNIFORM_IS_ROW_MAJOR: params[i] = uni->row_major; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)"); return; } } }
/** * Set the viewport. * \sa Called via glViewport() or display list execution. * * Flushes the vertices and calls _mesa_set_viewport() with the given * parameters. */ void GLAPIENTRY _mesa_Viewport_no_error(GLint x, GLint y, GLsizei width, GLsizei height) { GET_CURRENT_CONTEXT(ctx); viewport(ctx, x, y, width, height); }
/** * Bind a new array. * * \todo * The binding could be done more efficiently by comparing the non-NULL * pointers in the old and new objects. The only arrays that are "dirty" are * the ones that are non-NULL in either object. */ void GLAPIENTRY _mesa_BindVertexArrayAPPLE( GLuint id ) { GET_CURRENT_CONTEXT(ctx); bind_vertex_array(ctx, id, GL_FALSE); }
void GLAPIENTRY _mesa_ClipControl_no_error(GLenum origin, GLenum depth) { GET_CURRENT_CONTEXT(ctx); clip_control(ctx, origin, depth); }
/** * APPLE version of glGenVertexArraysAPPLE() * Arrays may live in VBOs or ordinary memory. */ void GLAPIENTRY _mesa_GenVertexArraysAPPLE(GLsizei n, GLuint *arrays) { GET_CURRENT_CONTEXT(ctx); gen_vertex_arrays(ctx, n, arrays, GL_FALSE); }
/** * Helper used by _mesa_TexStorage1/2/3D(). */ static void texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { struct gl_texture_object *texObj; GLboolean sizeOK, dimensionsOK; mesa_format texFormat; GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n", dims, _mesa_lookup_enum_by_nr(target), levels, _mesa_lookup_enum_by_nr(internalformat), width, height, depth); if (tex_storage_error_check(ctx, dims, target, levels, internalformat, width, height, depth)) { return; /* error was recorded */ } texObj = _mesa_get_current_tex_object(ctx, target); assert(texObj); texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, internalformat, GL_NONE, GL_NONE); assert(texFormat != MESA_FORMAT_NONE); /* check that width, height, depth are legal for the mipmap level */ dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, width, height, depth, 0); sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat, width, height, depth, 0); if (_mesa_is_proxy_texture(texObj->Target)) { if (dimensionsOK && sizeOK) { initialize_texture_fields(ctx, texObj, levels, width, height, depth, internalformat, texFormat); } else { /* clear all image fields for [levels] */ clear_texture_fields(ctx, texObj); } } else { if (!dimensionsOK) { _mesa_error(ctx, GL_INVALID_VALUE, "glTexStorage%uD(invalid width, height or depth)", dims); return; } if (!sizeOK) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage%uD(texture too large)", dims); } assert(levels > 0); assert(width > 0); assert(height > 0); assert(depth > 0); if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth, internalformat, texFormat)) { return; } /* Do actual texture memory allocation */ if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels, width, height, depth)) { /* Reset the texture images' info to zeros. * Strictly speaking, we probably don't have to do this since * generating GL_OUT_OF_MEMORY can leave things in an undefined * state but this puts things in a consistent state. */ clear_texture_fields(ctx, texObj); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage%uD", dims); return; } _mesa_set_texture_view_state(ctx, texObj, target, levels); } }
/** * Load/parse/compile a program. * \note Called from the GL API dispatcher. */ void GLAPIENTRY _mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program) { struct gl_program *prog; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (!ctx->Extensions.NV_vertex_program && !ctx->Extensions.NV_fragment_program) { _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV()"); return; } if (id == 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)"); return; } if (len < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(len)"); return; } FLUSH_VERTICES(ctx, _NEW_PROGRAM); prog = _mesa_lookup_program(ctx, id); if (prog && prog->Target != 0 && prog->Target != target) { _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target)"); return; } if ((target == GL_VERTEX_PROGRAM_NV || target == GL_VERTEX_STATE_PROGRAM_NV) && ctx->Extensions.NV_vertex_program) { struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog; if (!vprog || prog == &_mesa_DummyProgram) { vprog = (struct gl_vertex_program *) ctx->Driver.NewProgram(ctx, target, id); if (!vprog) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); return; } _mesa_HashInsert(ctx->Shared->Programs, id, vprog); } if (ctx->Extensions.ARB_vertex_program && (strncmp((char *) program, "!!ARB", 5) == 0)) { _mesa_parse_arb_vertex_program(ctx, target, program, len, vprog); } else { _mesa_parse_nv_vertex_program(ctx, target, program, len, vprog); } } else if (target == GL_FRAGMENT_PROGRAM_NV && ctx->Extensions.NV_fragment_program) { struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; if (!fprog || prog == &_mesa_DummyProgram) { fprog = (struct gl_fragment_program *) ctx->Driver.NewProgram(ctx, target, id); if (!fprog) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); return; } _mesa_HashInsert(ctx->Shared->Programs, id, fprog); } _mesa_parse_nv_fragment_program(ctx, target, program, len, fprog); } else if (target == GL_FRAGMENT_PROGRAM_ARB && ctx->Extensions.ARB_fragment_program) { struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; if (!fprog || prog == &_mesa_DummyProgram) { fprog = (struct gl_fragment_program *) ctx->Driver.NewProgram(ctx, target, id); if (!fprog) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); return; } _mesa_HashInsert(ctx->Shared->Programs, id, fprog); } _mesa_parse_arb_fragment_program(ctx, target, program, len, fprog); } else { _mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)"); } }
void GLAPIENTRY _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) { struct gl_sampler_object *sampObj; GET_CURRENT_CONTEXT(ctx); sampObj = sampler_parameter_error_check(ctx, sampler, true, "glGetSamplerParameteriv"); if (!sampObj) return; switch (pname) { case GL_TEXTURE_WRAP_S: *params = sampObj->WrapS; break; case GL_TEXTURE_WRAP_T: *params = sampObj->WrapT; break; case GL_TEXTURE_WRAP_R: *params = sampObj->WrapR; break; case GL_TEXTURE_MIN_FILTER: *params = sampObj->MinFilter; break; case GL_TEXTURE_MAG_FILTER: *params = sampObj->MagFilter; break; case GL_TEXTURE_MIN_LOD: /* GL spec 'Data Conversions' section specifies that floating-point * value in integer Get function is rounded to nearest integer */ *params = IROUND(sampObj->MinLod); break; case GL_TEXTURE_MAX_LOD: /* GL spec 'Data Conversions' section specifies that floating-point * value in integer Get function is rounded to nearest integer */ *params = IROUND(sampObj->MaxLod); break; case GL_TEXTURE_LOD_BIAS: /* GL spec 'Data Conversions' section specifies that floating-point * value in integer Get function is rounded to nearest integer */ *params = IROUND(sampObj->LodBias); break; case GL_TEXTURE_COMPARE_MODE: *params = sampObj->CompareMode; break; case GL_TEXTURE_COMPARE_FUNC: *params = sampObj->CompareFunc; break; case GL_TEXTURE_MAX_ANISOTROPY_EXT: /* GL spec 'Data Conversions' section specifies that floating-point * value in integer Get function is rounded to nearest integer */ *params = IROUND(sampObj->MaxAnisotropy); break; case GL_TEXTURE_BORDER_COLOR: params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]); params[1] = FLOAT_TO_INT(sampObj->BorderColor.f[1]); params[2] = FLOAT_TO_INT(sampObj->BorderColor.f[2]); params[3] = FLOAT_TO_INT(sampObj->BorderColor.f[3]); break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) goto invalid_pname; *params = sampObj->CubeMapSeamless; break; case GL_TEXTURE_SRGB_DECODE_EXT: if (!ctx->Extensions.EXT_texture_sRGB_decode) goto invalid_pname; *params = (GLenum) sampObj->sRGBDecode; break; default: goto invalid_pname; } return; invalid_pname: _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameteriv(pname=%s)", _mesa_enum_to_string(pname)); }
void GLAPIENTRY _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) { GET_CURRENT_CONTEXT(ctx); _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)"); }
void GLAPIENTRY _mesa_GenSamplers_no_error(GLsizei count, GLuint *samplers) { GET_CURRENT_CONTEXT(ctx); create_samplers(ctx, count, samplers, "glGenSamplers"); }
/** * All glWindowPosMESA and glWindowPosARB commands call this function to * update the current raster position. */ static void window_pos3f(GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); GLfloat z2; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); FLUSH_CURRENT(ctx, 0); z2 = CLAMP(z, 0.0F, 1.0F) * (ctx->Viewport.Far - ctx->Viewport.Near) + ctx->Viewport.Near; /* set raster position */ ctx->Current.RasterPos[0] = x; ctx->Current.RasterPos[1] = y; ctx->Current.RasterPos[2] = z2; ctx->Current.RasterPos[3] = 1.0F; ctx->Current.RasterPosValid = GL_TRUE; if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0]; else ctx->Current.RasterDistance = 0.0; /* raster color = current color or index */ if (ctx->Visual.rgbMode) { ctx->Current.RasterColor[0] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0], 0.0F, 1.0F); ctx->Current.RasterColor[1] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1], 0.0F, 1.0F); ctx->Current.RasterColor[2] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2], 0.0F, 1.0F); ctx->Current.RasterColor[3] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[0] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[1] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[2] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2], 0.0F, 1.0F); ctx->Current.RasterSecondaryColor[3] = CLAMP(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3], 0.0F, 1.0F); } else { ctx->Current.RasterIndex = ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0]; } /* raster texcoord = current texcoord */ { GLuint texSet; for (texSet = 0; texSet < ctx->Const.MaxTextureCoordUnits; texSet++) { COPY_4FV( ctx->Current.RasterTexCoords[texSet], ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texSet] ); } } if (ctx->RenderMode==GL_SELECT) { _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); } }
void GLAPIENTRY _mesa_DeleteSamplers_no_error(GLsizei count, const GLuint *samplers) { GET_CURRENT_CONTEXT(ctx); delete_samplers(ctx, count, samplers); }
void GLAPIENTRY _mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) { struct gl_texture_object *t; struct gl_texture_image *image; GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glInvalidateTexSubImage %d\n", texture); t = invalidate_tex_image_error_check(ctx, texture, level, "glInvalidateTexSubImage"); /* The GL_ARB_invalidate_subdata spec says: * * "...the specified subregion must be between -<b> and <dim>+<b> where * <dim> is the size of the dimension of the texture image, and <b> is * the size of the border of that texture image, otherwise * INVALID_VALUE is generated (border is not applied to dimensions that * don't exist in a given texture target)." */ image = t->Image[0][level]; if (image) { int xBorder; int yBorder; int zBorder; int imageWidth; int imageHeight; int imageDepth; /* The GL_ARB_invalidate_subdata spec says: * * "For texture targets that don't have certain dimensions, this * command treats those dimensions as having a size of 1. For * example, to invalidate a portion of a two-dimensional texture, * the application would use <zoffset> equal to zero and <depth> * equal to one." */ switch (t->Target) { case GL_TEXTURE_BUFFER: xBorder = 0; yBorder = 0; zBorder = 0; imageWidth = 1; imageHeight = 1; imageDepth = 1; break; case GL_TEXTURE_1D: xBorder = image->Border; yBorder = 0; zBorder = 0; imageWidth = image->Width; imageHeight = 1; imageDepth = 1; break; case GL_TEXTURE_1D_ARRAY: xBorder = image->Border; yBorder = 0; zBorder = 0; imageWidth = image->Width; imageHeight = image->Height; imageDepth = 1; break; case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_RECTANGLE: case GL_TEXTURE_2D_MULTISAMPLE: xBorder = image->Border; yBorder = image->Border; zBorder = 0; imageWidth = image->Width; imageHeight = image->Height; imageDepth = 1; break; case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: xBorder = image->Border; yBorder = image->Border; zBorder = 0; imageWidth = image->Width; imageHeight = image->Height; imageDepth = image->Depth; break; case GL_TEXTURE_3D: xBorder = image->Border; yBorder = image->Border; zBorder = image->Border; imageWidth = image->Width; imageHeight = image->Height; imageDepth = image->Depth; break; default: assert(!"Should not get here."); xBorder = 0; yBorder = 0; zBorder = 0; imageWidth = 0; imageHeight = 0; imageDepth = 0; break; } if (xoffset < -xBorder) { _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(xoffset)"); return; } if (xoffset + width > imageWidth + xBorder) { _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(xoffset+width)"); return; } if (yoffset < -yBorder) { _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(yoffset)"); return; } if (yoffset + height > imageHeight + yBorder) { _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(yoffset+height)"); return; } if (zoffset < -zBorder) { _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(zoffset)"); return; } if (zoffset + depth > imageDepth + zBorder) { _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(zoffset+depth)"); return; } } /* We don't actually do anything for this yet. Just return after * validating the parameters and generating the required errors. */ return; }