Esempio n. 1
0
/**
 * 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;
   }
}
Esempio n. 2
0
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));
}
Esempio n. 3
0
void GLAPIENTRY
_mesa_CreateSamplers(GLsizei count, GLuint *samplers)
{
   GET_CURRENT_CONTEXT(ctx);
   create_samplers_err(ctx, count, samplers, "glCreateSamplers");
}
Esempio n. 4
0
/* 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();
   }
Esempio n. 5
0
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:
      ;
   }
}
Esempio n. 6
0
/*
 * 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);
   }
}
Esempio n. 7
0
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]);
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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);
   }
}
Esempio n. 12
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;
}
Esempio n. 13
0
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)");
}
Esempio n. 14
0
File: blit.c Progetto: DirectFB/mesa
/**
 * 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);
}
Esempio n. 15
0
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);
   }
}
Esempio n. 16
0
/**
 * 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;
}
Esempio n. 17
0
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);
   }
}
Esempio n. 18
0
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;
      }
   }
}
Esempio n. 19
0
/**
 * 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);
}
Esempio n. 20
0
/**
 * 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);
}
Esempio n. 21
0
void GLAPIENTRY
_mesa_ClipControl_no_error(GLenum origin, GLenum depth)
{
   GET_CURRENT_CONTEXT(ctx);
   clip_control(ctx, origin, depth);
}
Esempio n. 22
0
/**
 * 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);
}
Esempio n. 23
0
/**
 * 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);

   }
}
Esempio n. 24
0
/**
 * 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)");
   }
}
Esempio n. 25
0
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));
}
Esempio n. 26
0
void GLAPIENTRY
_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
{
   GET_CURRENT_CONTEXT(ctx);
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)");
}
Esempio n. 27
0
void GLAPIENTRY
_mesa_GenSamplers_no_error(GLsizei count, GLuint *samplers)
{
   GET_CURRENT_CONTEXT(ctx);
   create_samplers(ctx, count, samplers, "glGenSamplers");
}
Esempio n. 28
0
/**
 * 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] );
   }
}
Esempio n. 29
0
void GLAPIENTRY
_mesa_DeleteSamplers_no_error(GLsizei count, const GLuint *samplers)
{
   GET_CURRENT_CONTEXT(ctx);
   delete_samplers(ctx, count, samplers);
}
Esempio n. 30
0
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;
}