Beispiel #1
0
/**
 * Returns the current GL error code, or GL_NO_ERROR.
 * \return current error code
 *
 * Returns __struct gl_contextRec::ErrorValue.
 */
GLenum GLAPIENTRY
_mesa_GetError( void )
{
   GET_CURRENT_CONTEXT(ctx);
   GLenum e = ctx->ErrorValue;
   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glGetError <-- %s\n", _mesa_lookup_enum_by_nr(e));

   ctx->ErrorValue = (GLenum) GL_NO_ERROR;
   ctx->ErrorDebugCount = 0;
   return e;
}
Beispiel #2
0
static void GLAPIENTRY
vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name,
                                        GLsizei primcount)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_transform_feedback_object *obj =
      _mesa_lookup_transform_feedback_object(ctx, name);

   if (MESA_VERBOSE & VERBOSE_DRAW)
      _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n",
                  _mesa_lookup_enum_by_nr(mode), name);

   vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount);
}
Beispiel #3
0
static void gen6_set_prim(struct brw_context *brw,
                          const struct _mesa_prim *prim)
{
   uint32_t hw_prim;

   DBG("PRIM: %s\n", _mesa_lookup_enum_by_nr(prim->mode));

   hw_prim = prim_to_hw_prim[prim->mode];

   if (hw_prim != brw->primitive) {
      brw->primitive = hw_prim;
      brw->state.dirty.brw |= BRW_NEW_PRIMITIVE;
   }
}
Beispiel #4
0
/**
 * Given vertex array type/size/format/normalized info, return
 * the appopriate hardware surface type.
 * Format will be GL_RGBA or possibly GL_BGRA for GLubyte[4] color arrays.
 */
static GLuint get_surface_type( GLenum type, GLuint size,
                                GLenum format, GLboolean normalized )
{
   if (unlikely(INTEL_DEBUG & DEBUG_VERTS))
      printf("type %s size %d normalized %d\n", 
		   _mesa_lookup_enum_by_nr(type), size, normalized);

   if (normalized) {
      switch (type) {
      case GL_DOUBLE: return double_types[size];
      case GL_FLOAT: return float_types[size];
      case GL_HALF_FLOAT: return half_float_types[size];
      case GL_INT: return int_types_norm[size];
      case GL_SHORT: return short_types_norm[size];
      case GL_BYTE: return byte_types_norm[size];
      case GL_UNSIGNED_INT: return uint_types_norm[size];
      case GL_UNSIGNED_SHORT: return ushort_types_norm[size];
      case GL_UNSIGNED_BYTE:
         if (format == GL_BGRA) {
            /* See GL_EXT_vertex_array_bgra */
            assert(size == 4);
            return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
         }
         else {
            return ubyte_types_norm[size];
         }
      default: assert(0); return 0;
      }      
   }
   else {
      assert(format == GL_RGBA); /* sanity check */
      switch (type) {
      case GL_DOUBLE: return double_types[size];
      case GL_FLOAT: return float_types[size];
      case GL_HALF_FLOAT: return half_float_types[size];
      case GL_INT: return int_types_scale[size];
      case GL_SHORT: return short_types_scale[size];
      case GL_BYTE: return byte_types_scale[size];
      case GL_UNSIGNED_INT: return uint_types_scale[size];
      case GL_UNSIGNED_SHORT: return ushort_types_scale[size];
      case GL_UNSIGNED_BYTE: return ubyte_types_scale[size];
      /* This produces GL_FIXED inputs as values between INT32_MIN and
       * INT32_MAX, which will be scaled down by 1/65536 by the VS.
       */
      case GL_FIXED: return int_types_scale[size];
      default: assert(0); return 0;
      }
   }
}
Beispiel #5
0
static void r300TexParameter(GLcontext * ctx, GLenum target,
			     struct gl_texture_object *texObj,
			     GLenum pname, const GLfloat * params)
{
	r300TexObjPtr t = (r300TexObjPtr) texObj->DriverData;

	if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
		fprintf(stderr, "%s( %s )\n", __FUNCTION__,
			_mesa_lookup_enum_by_nr(pname));
	}

	switch (pname) {
	case GL_TEXTURE_MIN_FILTER:
	case GL_TEXTURE_MAG_FILTER:
	case GL_TEXTURE_MAX_ANISOTROPY_EXT:
		r300SetTexMaxAnisotropy(t, texObj->MaxAnisotropy);
		r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter);
		break;

	case GL_TEXTURE_WRAP_S:
	case GL_TEXTURE_WRAP_T:
	case GL_TEXTURE_WRAP_R:
		r300SetTexWrap(t, texObj->WrapS, texObj->WrapT, texObj->WrapR);
		break;

	case GL_TEXTURE_BORDER_COLOR:
		r300SetTexBorderColor(t, texObj->_BorderChan);
		break;

	case GL_TEXTURE_BASE_LEVEL:
	case GL_TEXTURE_MAX_LEVEL:
	case GL_TEXTURE_MIN_LOD:
	case GL_TEXTURE_MAX_LOD:
		/* This isn't the most efficient solution but there doesn't appear to
		 * be a nice alternative.  Since there's no LOD clamping,
		 * we just have to rely on loading the right subset of mipmap levels
		 * to simulate a clamped LOD.
		 */
		driSwapOutTextureObject((driTextureObject *) t);
		break;

	default:
		return;
	}

	/* Mark this texobj as dirty (one bit per tex unit)
	 */
	t->dirty_state = TEX_ALL;
}
static void GLAPIENTRY
_mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params)
{
   struct gl_query_object *q = NULL;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glGetQueryObjectuiv(%u, %s)\n", id,
                  _mesa_lookup_enum_by_nr(pname));

   if (id)
      q = _mesa_lookup_query_object(ctx, id);

   if (!q || q->Active) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glGetQueryObjectuivARB(id=%d is invalid or active)", id);
      return;
   }

   switch (pname) {
      case GL_QUERY_RESULT_ARB:
         if (!q->Ready)
            ctx->Driver.WaitQuery(ctx, q);
         /* if result is too large for returned type, clamp to max value */
         if (q->Target == GL_ANY_SAMPLES_PASSED) {
            if (q->Result)
               *params = GL_TRUE;
            else
               *params = GL_FALSE;
         } else {
            if (q->Result > 0xffffffff) {
               *params = 0xffffffff;
            }
            else {
               *params = (GLuint)q->Result;
            }
         }
         break;
      case GL_QUERY_RESULT_AVAILABLE_ARB:
	 if (!q->Ready)
	    ctx->Driver.CheckQuery( ctx, q );
         *params = q->Ready;
         break;
      default:
         _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)");
         return;
   }
}
Beispiel #7
0
/**
 * Verify that the element type is valid.
 *
 * Generates \c GL_INVALID_ENUM and returns \c false if it is not.
 */
static bool
valid_elements_type(struct gl_context *ctx, GLenum type, const char *name)
{
   switch (type) {
   case GL_UNSIGNED_BYTE:
   case GL_UNSIGNED_SHORT:
   case GL_UNSIGNED_INT:
      return true;

   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", name,
                  _mesa_lookup_enum_by_nr(type));
      return false;
   }
}
Beispiel #8
0
/* GL_ARB_multitexture */
void GLAPIENTRY
_mesa_ActiveTextureARB(GLenum texture)
{
   const GLuint texUnit = texture - GL_TEXTURE0;
   GLuint k;
   GET_CURRENT_CONTEXT(ctx);

   /* See OpenGL spec for glActiveTexture: */
   k = MAX2(ctx->Const.MaxCombinedTextureImageUnits,
            ctx->Const.MaxTextureCoordUnits);

   ASSERT(k <= Elements(ctx->Texture.Unit));
   
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
      _mesa_debug(ctx, "glActiveTexture %s\n",
                  _mesa_lookup_enum_by_nr(texture));

   if (texUnit >= k) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
                  _mesa_lookup_enum_by_nr(texture));
      return;
   }

   if (ctx->Texture.CurrentUnit == texUnit)
      return;

   FLUSH_VERTICES(ctx, _NEW_TEXTURE);

   ctx->Texture.CurrentUnit = texUnit;
   if (ctx->Transform.MatrixMode == GL_TEXTURE) {
      /* update current stack pointer */
      ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
   }
}
Beispiel #9
0
 /* System to flush dma and emit state changes based on the rasterized
  * primitive.
  */
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim )
{
   intelContextPtr intel = INTEL_CONTEXT(ctx);

   if (0)
      fprintf(stderr, "%s %s %x\n", __FUNCTION__, 
	      _mesa_lookup_enum_by_nr(rprim), hwprim);

   intel->vtbl.reduced_primitive_state( intel, rprim );
    
   /* Start a new primitive.  Arrange to have it flushed later on.
    */
   if (hwprim != intel->prim.primitive) 
      intelStartInlinePrimitive( intel, hwprim );
}
Beispiel #10
0
/**
 * Do error checking and update state for glVertex/Color/TexCoord/...Pointer
 * functions.
 *
 * \param func  name of calling function used for error reporting
 * \param attrib  the attribute array index to update
 * \param legalTypes  bitmask of *_BIT above indicating legal datatypes
 * \param sizeMin  min allowable size value
 * \param sizeMax  max allowable size value
 * \param size  components per element (1, 2, 3 or 4)
 * \param type  datatype of each component (GL_FLOAT, GL_INT, etc)
 * \param stride  stride between elements, in elements
 * \param normalized  are integer types converted to floats in [-1, 1]?
 * \param integer  integer-valued values (will not be normalized to [-1,1])
 * \param ptr  the address (or offset inside VBO) of the array data
 */
static void
update_array(struct gl_context *ctx,
             const char *func,
             GLuint attrib, GLbitfield legalTypesMask,
             GLint sizeMin, GLint sizeMax,
             GLint size, GLenum type, GLsizei stride,
             GLboolean normalized, GLboolean integer,
             const GLvoid *ptr)
{
   struct gl_client_array *array;
   GLbitfield typeBit;
   GLsizei elementSize;

   typeBit = type_to_bit(ctx, type);
   if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
                  func, _mesa_lookup_enum_by_nr(type));
      return;
   }

   /* Do size parameter checking. */
   if (size < sizeMin || size > sizeMax || size > 4) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
      return;
   }

   ASSERT(size <= 4);

   if (stride < 0) {
      _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
      return;
   }

   elementSize = _mesa_sizeof_type(type) * size;

   array = &ctx->Array.VertexAttrib[attrib];
   array->Size = size;
   array->Type = type;
   array->Stride = stride;
   array->StrideB = stride ? stride : elementSize;
   array->Normalized = normalized;
   array->Integer = integer;
   array->Ptr = (const GLubyte *) ptr;
   array->_ElementSize = elementSize;

   ctx->NewState |= _NEW_ARRAY;
   ctx->Array.NewState |= VERT_BIT(attrib);
}
Beispiel #11
0
static void
radeon_bind_framebuffer(struct gl_context * ctx, GLenum target,
                       struct gl_framebuffer *fb, struct gl_framebuffer *fbread)
{
  radeon_print(RADEON_TEXTURE, RADEON_TRACE,
		"%s(%p, fb %p, target %s) \n",
		__func__, ctx, fb,
		_mesa_lookup_enum_by_nr(target));

   if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) {
      radeon_draw_buffer(ctx, fb);
   }
   else {
      /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */
   }
}
Beispiel #12
0
static void r300TexEnv(GLcontext * ctx, GLenum target,
		       GLenum pname, const GLfloat * param)
{
	if (RADEON_DEBUG & DEBUG_STATE) {
		fprintf(stderr, "%s( %s )\n",
			__FUNCTION__, _mesa_lookup_enum_by_nr(pname));
	}

	/* This is incorrect: Need to maintain this data for each of
	 * GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch
	 * between them according to _ReallyEnabled.
	 */
	switch (pname) {
	case GL_TEXTURE_LOD_BIAS_EXT:{
#if 0 /* Needs to be relocated in order to make sure we got the right tmu */
			GLfloat bias, min;
			GLuint b;

			/* The R300's LOD bias is a signed 2's complement value with a
			 * range of -16.0 <= bias < 16.0.
			 *
			 * NOTE: Add a small bias to the bias for conform mipsel.c test.
			 */
			bias = *param + .01;
			min =
			    driQueryOptionb(&rmesa->radeon.optionCache,
					    "no_neg_lod_bias") ? 0.0 : -16.0;
			bias = CLAMP(bias, min, 16.0);

			/* 0.0 - 16.0 == 0x0 - 0x1000 */
			/* 0.0 - -16.0 == 0x1001 - 0x1fff */
			b = 0x1000 / 16.0 * bias;
			b &= R300_LOD_BIAS_MASK;

			if(b != (rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+unit] & R300_LOD_BIAS_MASK)){
				R300_STATECHANGE(rmesa, tex.unknown1);
				rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+unit] &= ~R300_LOD_BIAS_MASK;
				rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+unit] |= b;
			}
#endif
			break;
		}

	default:
		return;
	}
}
Beispiel #13
0
void GLAPIENTRY
_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
                      const GLvoid *ptr)
{
    GLint elementSize;
    GET_CURRENT_CONTEXT(ctx);
    const GLuint unit = ctx->Array.ActiveTexture;
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

    if (size < 1 || size > 4) {
        _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
        return;
    }
    if (stride < 0) {
        _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
        return;
    }

    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
        _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n",
                    unit, size, _mesa_lookup_enum_by_nr( type ), stride);

    /* always need to check that <type> is legal */
    switch (type) {
    case GL_SHORT:
        elementSize = size * sizeof(GLshort);
        break;
    case GL_INT:
        elementSize = size * sizeof(GLint);
        break;
    case GL_FLOAT:
        elementSize = size * sizeof(GLfloat);
        break;
    case GL_DOUBLE:
        elementSize = size * sizeof(GLdouble);
        break;
    default:
        _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
        return;
    }

    update_array(ctx, &ctx->Array.TexCoord[unit], _NEW_ARRAY_TEXCOORD(unit),
                 elementSize, size, type, stride, GL_FALSE, ptr);

    if (ctx->Driver.TexCoordPointer)
        ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
}
Beispiel #14
0
/**
 * New in GL 3.2
 * This is pretty much a duplicate of GetBufferParameteriv() but the
 * GL_BUFFER_SIZE_ARB attribute will be 64-bits on a 64-bit system.
 */
void GLAPIENTRY
_mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_buffer_object *bufObj;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   bufObj = get_buffer(ctx, "glGetBufferParameteri64v", target);
   if (!bufObj)
      return;

   switch (pname) {
   case GL_BUFFER_SIZE_ARB:
      *params = bufObj->Size;
      return;
   case GL_BUFFER_USAGE_ARB:
      *params = bufObj->Usage;
      return;
   case GL_BUFFER_ACCESS_ARB:
      *params = simplified_access_mode(bufObj->AccessFlags);
      return;
   case GL_BUFFER_ACCESS_FLAGS:
      if (!ctx->Extensions.ARB_map_buffer_range)
         goto invalid_pname;
      *params = bufObj->AccessFlags;
      return;
   case GL_BUFFER_MAPPED_ARB:
      *params = _mesa_bufferobj_mapped(bufObj);
      return;
   case GL_BUFFER_MAP_OFFSET:
      if (!ctx->Extensions.ARB_map_buffer_range)
         goto invalid_pname;
      *params = bufObj->Offset;
      return;
   case GL_BUFFER_MAP_LENGTH:
      if (!ctx->Extensions.ARB_map_buffer_range)
         goto invalid_pname;
      *params = bufObj->Length;
      return;
   default:
      ; /* fall-through */
   }

invalid_pname:
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameteri64v(pname=%s)",
               _mesa_lookup_enum_by_nr(pname));
}
Beispiel #15
0
void brw_draw_prims( struct gl_context *ctx,
		     const struct _mesa_prim *prim,
		     GLuint nr_prims,
		     const struct _mesa_index_buffer *ib,
		     GLboolean index_bounds_valid,
		     GLuint min_index,
		     GLuint max_index,
		     struct gl_transform_feedback_object *tfb_vertcount )
{
   struct intel_context *intel = intel_context(ctx);
   const struct gl_client_array **arrays = ctx->Array._DrawArrays;

   if (!_mesa_check_conditional_render(ctx))
      return;

   /* Handle primitive restart if needed */
   if (brw_handle_primitive_restart(ctx, prim, nr_prims, ib)) {
      /* The draw was handled, so we can exit now */
      return;
   }

   /* If we're going to have to upload any of the user's vertex arrays, then
    * get the minimum and maximum of their index buffer so we know what range
    * to upload.
    */
   if (!vbo_all_varyings_in_vbos(arrays) && !index_bounds_valid)
      vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims);

   /* Do GL_SELECT and GL_FEEDBACK rendering using swrast, even though it
    * won't support all the extensions we support.
    */
   if (ctx->RenderMode != GL_RENDER) {
      perf_debug("%s render mode not supported in hardware\n",
                 _mesa_lookup_enum_by_nr(ctx->RenderMode));
      _swsetup_Wakeup(ctx);
      _tnl_wakeup(ctx);
      _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
      return;
   }

   /* Try drawing with the hardware, but don't do anything else if we can't
    * manage it.  swrast doesn't support our featureset, so we can't fall back
    * to it.
    */
   brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
}
Beispiel #16
0
void GLAPIENTRY
_mesa_BeginConditionalRender(GLuint queryId, GLenum mode)
{
   struct gl_query_object *q;
   GET_CURRENT_CONTEXT(ctx);

   if (!ctx->Extensions.NV_conditional_render || ctx->Query.CondRenderQuery ||
       queryId == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
      return;
   }

   ASSERT(ctx->Query.CondRenderMode == GL_NONE);

   switch (mode) {
   case GL_QUERY_WAIT:
   case GL_QUERY_NO_WAIT:
   case GL_QUERY_BY_REGION_WAIT:
   case GL_QUERY_BY_REGION_NO_WAIT:
      /* OK */
      break;
   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "glBeginConditionalRender(mode=%s)",
                  _mesa_lookup_enum_by_nr(mode));
      return;
   }

   q = _mesa_lookup_query_object(ctx, queryId);
   if (!q) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glBeginConditionalRender(bad queryId=%u)", queryId);
      return;
   }
   ASSERT(q->Id == queryId);

   if (q->Target != GL_SAMPLES_PASSED || q->Active) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
      return;
   }

   ctx->Query.CondRenderQuery = q;
   ctx->Query.CondRenderMode = mode;

   if (ctx->Driver.BeginConditionalRender)
      ctx->Driver.BeginConditionalRender(ctx, q, mode);
}
Beispiel #17
0
/**
 * Called by glDrawBuffer().
 * Specify which renderbuffer(s) to draw into for the first color output.
 * <buffer> can name zero, one, two or four renderbuffers!
 * \sa _mesa_DrawBuffers
 *
 * \param buffer  buffer token such as GL_LEFT or GL_FRONT_AND_BACK, etc.
 *
 * Note that the behaviour of this function depends on whether the
 * current ctx->DrawBuffer is a window-system framebuffer or a user-created
 * framebuffer object.
 *   In the former case, we update the per-context ctx->Color.DrawBuffer
 *   state var _and_ the FB's ColorDrawBuffer state.
 *   In the later case, we update the FB's ColorDrawBuffer state only.
 *
 * Furthermore, upon a MakeCurrent() or BindFramebuffer() call, if the
 * new FB is a window system FB, we need to re-update the FB's
 * ColorDrawBuffer state to match the context.  This is handled in
 * _mesa_update_framebuffer().
 *
 * See the GL_EXT_framebuffer_object spec for more info.
 */
void GLAPIENTRY
_mesa_DrawBuffer(GLenum buffer)
{
   GLbitfield destMask;
   GET_CURRENT_CONTEXT(ctx);

   FLUSH_VERTICES(ctx, 0);

   if (MESA_VERBOSE & VERBOSE_API) {
      _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer));
   }

   if (buffer == GL_NONE) {
      destMask = 0x0;
   }
   else {
      const GLbitfield supportedMask
         = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
      destMask = draw_buffer_enum_to_bitmask(ctx, buffer);
      if (destMask == BAD_MASK) {
         /* totally bogus buffer */
         _mesa_error(ctx, GL_INVALID_ENUM,
                     "glDrawBuffer(buffer=0x%x)", buffer);
         return;
      }
      destMask &= supportedMask;
      if (destMask == 0x0) {
         /* none of the named color buffers exist! */
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glDrawBuffer(buffer=0x%x)", buffer);
         return;
      }
   }

   /* if we get here, there's no error so set new state */
   _mesa_drawbuffers(ctx, 1, &buffer, &destMask);

   /*
    * Call device driver function.
    */
   if (ctx->Driver.DrawBuffers)
      ctx->Driver.DrawBuffers(ctx, 1, &buffer);
   else if (ctx->Driver.DrawBuffer)
      ctx->Driver.DrawBuffer(ctx, buffer);
}
Beispiel #18
0
GLuint GLAPIENTRY
_mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface,
                              const GLchar *name)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_program_resource *res;
   struct gl_shader_program *shProg =
      _mesa_lookup_shader_program_err(ctx, program,
                                      "glGetProgramResourceIndex");
   if (!shProg || !name)
      return GL_INVALID_INDEX;

   /*
    * For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX
    * should be returned when querying the index assigned to the special names
    * "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2",
    * "gl_SkipComponents3", and "gl_SkipComponents4".
    */
   if (programInterface == GL_TRANSFORM_FEEDBACK_VARYING &&
       is_xfb_marker(name))
      return GL_INVALID_INDEX;

   switch (programInterface) {
   case GL_PROGRAM_INPUT:
   case GL_PROGRAM_OUTPUT:
   case GL_UNIFORM:
   case GL_UNIFORM_BLOCK:
   case GL_TRANSFORM_FEEDBACK_VARYING:
      /* Validate name syntax for arrays. */
      if (!valid_program_resource_index_name(name))
         return GL_INVALID_INDEX;

      res = _mesa_program_resource_find_name(shProg, programInterface, name);
      if (!res)
         return GL_INVALID_INDEX;

      return _mesa_program_resource_index(shProg, res);
   case GL_ATOMIC_COUNTER_BUFFER:
   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)",
                  _mesa_lookup_enum_by_nr(programInterface));
   }

   return GL_INVALID_INDEX;
}
Beispiel #19
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);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (!params)
      return;

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glGetPointerv %s\n", _mesa_lookup_enum_by_nr(pname));

   switch (pname) {
      case GL_VERTEX_ARRAY_POINTER:
         *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_POS].Ptr;
         break;
      case GL_NORMAL_ARRAY_POINTER:
         *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_NORMAL].Ptr;
         break;
      case GL_COLOR_ARRAY_POINTER:
         *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR].Ptr;
         break;
      case GL_FOG_COORDINATE_ARRAY_POINTER_EXT:
         *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_FOG].Ptr;
         break;
      case GL_INDEX_ARRAY_POINTER:
         *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Ptr;
         break;
      case GL_TEXTURE_COORD_ARRAY_POINTER:
         *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_TEX].Ptr;
         break;
      case GL_EDGE_FLAG_ARRAY_POINTER:
         *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_EDGEFLAG].Ptr;
         break;
      case GL_FEEDBACK_BUFFER_POINTER:
         *params = ctx->Feedback.Buffer;
         break;
      case GL_SELECTION_BUFFER_POINTER:
         *params = ctx->Select.Buffer;
         break;
      default:
         _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" );
         return;
   }
}
Beispiel #20
0
/**
 * This function is called by software rendering commands (all point,
 * line triangle drawing, glClear, glDrawPixels, glCopyPixels, and
 * glBitmap, glBlitFramebuffer) to determine if subsequent drawing
 * commands should be
 * executed or discarded depending on the current conditional
 * rendering state.  Ideally, this check would be implemented by the
 * GPU when doing hardware rendering.  XXX should this function be
 * called via a new driver hook?
 *
 * \return GL_TRUE if we should render, GL_FALSE if we should discard
 */
GLboolean
_mesa_check_conditional_render(struct gl_context *ctx)
{
   struct gl_query_object *q = ctx->Query.CondRenderQuery;

   if (!q) {
      /* no query in progress - draw normally */
      return GL_TRUE;
   }

   switch (ctx->Query.CondRenderMode) {
   case GL_QUERY_BY_REGION_WAIT:
      /* fall-through */
   case GL_QUERY_WAIT:
      if (!q->Ready) {
         ctx->Driver.WaitQuery(ctx, q);
      }
      return q->Result > 0;
   case GL_QUERY_BY_REGION_WAIT_INVERTED:
      /* fall-through */
   case GL_QUERY_WAIT_INVERTED:
      if (!q->Ready) {
         ctx->Driver.WaitQuery(ctx, q);
      }
      return q->Result == 0;
   case GL_QUERY_BY_REGION_NO_WAIT:
      /* fall-through */
   case GL_QUERY_NO_WAIT:
      if (!q->Ready)
         ctx->Driver.CheckQuery(ctx, q);
      return q->Ready ? (q->Result > 0) : GL_TRUE;
   case GL_QUERY_BY_REGION_NO_WAIT_INVERTED:
      /* fall-through */
   case GL_QUERY_NO_WAIT_INVERTED:
      if (!q->Ready)
         ctx->Driver.CheckQuery(ctx, q);
      return q->Ready ? (q->Result == 0) : GL_TRUE;
   default:
      _mesa_problem(ctx, "Bad cond render mode %s in "
                    " _mesa_check_conditional_render()",
                    _mesa_lookup_enum_by_nr(ctx->Query.CondRenderMode));
      return GL_TRUE;
   }
}
Beispiel #21
0
void GLAPIENTRY
_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
{
    GLsizei elementSize;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

    if (stride < 0) {
        _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
        return;
    }

    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
        _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n",
                    _mesa_lookup_enum_by_nr( type ), stride);

    switch (type) {
    case GL_BYTE:
        elementSize = 3 * sizeof(GLbyte);
        break;
    case GL_SHORT:
        elementSize = 3 * sizeof(GLshort);
        break;
    case GL_INT:
        elementSize = 3 * sizeof(GLint);
        break;
    case GL_FLOAT:
        elementSize = 3 * sizeof(GLfloat);
        break;
    case GL_DOUBLE:
        elementSize = 3 * sizeof(GLdouble);
        break;
    default:
        _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
        return;
    }

    update_array(ctx, &ctx->Array.Normal, _NEW_ARRAY_NORMAL,
                 elementSize, 3, type, stride, GL_FALSE, ptr);

    if (ctx->Driver.NormalPointer)
        ctx->Driver.NormalPointer( ctx, type, stride, ptr );
}
Beispiel #22
0
 /* System to flush dma and emit state changes based on the rasterized
  * primitive.
  */
static void
intelRasterPrimitive(GLcontext * ctx, GLenum rprim, GLuint hwprim)
{
   struct intel_context *intel = intel_context(ctx);

   if (0)
      fprintf(stderr, "%s %s %x\n", __FUNCTION__,
              _mesa_lookup_enum_by_nr(rprim), hwprim);

   intel->vtbl.reduced_primitive_state(intel, rprim);

   /* Start a new primitive.  Arrange to have it flushed later on.
    */
   if (hwprim != intel->prim.primitive) {
      INTEL_FIREVERTICES(intel);

      intelStartInlinePrimitive(intel, hwprim, INTEL_BATCH_CLIPRECTS);
   }
}
/**
 * Given vertex array type/size/format/normalized info, return
 * the appopriate hardware surface type.
 * Format will be GL_RGBA or possibly GL_BGRA for GLubyte[4] color arrays.
 */
static GLuint get_surface_type( GLenum type, GLuint size,
                                GLenum format, GLboolean normalized )
{
   if (INTEL_DEBUG & DEBUG_VERTS)
      _mesa_printf("type %s size %d normalized %d\n", 
		   _mesa_lookup_enum_by_nr(type), size, normalized);

   if (normalized) {
      switch (type) {
      case GL_DOUBLE: return double_types[size];
      case GL_FLOAT: return float_types[size];
      case GL_INT: return int_types_norm[size];
      case GL_SHORT: return short_types_norm[size];
      case GL_BYTE: return byte_types_norm[size];
      case GL_UNSIGNED_INT: return uint_types_norm[size];
      case GL_UNSIGNED_SHORT: return ushort_types_norm[size];
      case GL_UNSIGNED_BYTE:
         if (format == GL_BGRA) {
            /* See GL_EXT_vertex_array_bgra */
            assert(size == 4);
            return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
         }
         else {
            return ubyte_types_norm[size];
         }
      default: assert(0); return 0;
      }      
   }
   else {
      assert(format == GL_RGBA); /* sanity check */
      switch (type) {
      case GL_DOUBLE: return double_types[size];
      case GL_FLOAT: return float_types[size];
      case GL_INT: return int_types_scale[size];
      case GL_SHORT: return short_types_scale[size];
      case GL_BYTE: return byte_types_scale[size];
      case GL_UNSIGNED_INT: return uint_types_scale[size];
      case GL_UNSIGNED_SHORT: return ushort_types_scale[size];
      case GL_UNSIGNED_BYTE: return ubyte_types_scale[size];
      default: assert(0); return 0;
      }      
   }
}
Beispiel #24
0
/**
 * Called from glDrawArrays when in immediate mode (not display list mode).
 */
static void GLAPIENTRY
vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_DRAW)
      _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n",
                  _mesa_lookup_enum_by_nr(mode), start, count);

   if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
      return;

   if (0)
      check_draw_arrays_data(ctx, start, count);

   vbo_draw_arrays(ctx, mode, start, count, 1, 0);

   if (0)
      print_draw_arrays(ctx, mode, start, count);
}
Beispiel #25
0
/* This is really an extension function! */
void GLAPIENTRY
_mesa_BlendEquation( GLenum mode )
{
    GLuint buf, numBuffers;
    GLboolean changed;
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);

    if (MESA_VERBOSE & VERBOSE_API)
        _mesa_debug(ctx, "glBlendEquation(%s)\n",
                    _mesa_lookup_enum_by_nr(mode));

    if (!legal_blend_equation(ctx, mode)) {
        _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation");
        return;
    }

    numBuffers = ctx->Extensions.ARB_draw_buffers_blend
                 ? ctx->Const.MaxDrawBuffers : 1;

    changed = GL_FALSE;
    for (buf = 0; buf < numBuffers; buf++) {
        if (ctx->Color.Blend[buf].EquationRGB != mode ||
                ctx->Color.Blend[buf].EquationA != mode) {
            changed = GL_TRUE;
            break;
        }
    }
    if (!changed)
        return;

    FLUSH_VERTICES(ctx, _NEW_COLOR);
    for (buf = 0; buf < numBuffers; buf++) {
        ctx->Color.Blend[buf].EquationRGB = mode;
        ctx->Color.Blend[buf].EquationA = mode;
    }
    ctx->Color._BlendEquationPerBuffer = GL_FALSE;

    if (ctx->Driver.BlendEquationSeparate)
        (*ctx->Driver.BlendEquationSeparate)( ctx, mode, mode );
}
Beispiel #26
0
static void brw_emit_prim(struct brw_context *brw,
			  const struct _mesa_prim *prim,
			  uint32_t hw_prim)
{
   struct brw_3d_primitive prim_packet;
   struct intel_context *intel = &brw->intel;

   if (INTEL_DEBUG & DEBUG_PRIMS)
      printf("PRIM: %s %d %d\n", _mesa_lookup_enum_by_nr(prim->mode), 
		   prim->start, prim->count);

   prim_packet.header.opcode = CMD_3D_PRIM;
   prim_packet.header.length = sizeof(prim_packet)/4 - 2;
   prim_packet.header.pad = 0;
   prim_packet.header.topology = hw_prim;
   prim_packet.header.indexed = prim->indexed;

   prim_packet.verts_per_instance = trim(prim->mode, prim->count);
   prim_packet.start_vert_location = prim->start;
   if (prim->indexed)
      prim_packet.start_vert_location += brw->ib.start_vertex_offset;
   prim_packet.instance_count = 1;
   prim_packet.start_instance_location = 0;
   prim_packet.base_vert_location = prim->basevertex;

   /* If we're set to always flush, do it before and after the primitive emit.
    * We want to catch both missed flushes that hurt instruction/state cache
    * and missed flushes of the render cache as it heads to other parts of
    * the besides the draw code.
    */
   if (intel->always_flush_cache) {
      intel_batchbuffer_emit_mi_flush(intel->batch);
   }
   if (prim_packet.verts_per_instance) {
      intel_batchbuffer_data( brw->intel.batch, &prim_packet,
			      sizeof(prim_packet));
   }
   if (intel->always_flush_cache) {
      intel_batchbuffer_emit_mi_flush(intel->batch);
   }
}
Beispiel #27
0
extern void
_mesa_get_program_resourceiv(struct gl_shader_program *shProg,
                             GLenum programInterface, GLuint index, GLsizei propCount,
                             const GLenum *props, GLsizei bufSize,
                             GLsizei *length, GLint *params)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint *val = (GLint *) params;
   const GLenum *prop = props;
   GLsizei amount = 0;

   struct gl_program_resource *res =
      _mesa_program_resource_find_index(shProg, programInterface, index);

   /* No such resource found or bufSize negative. */
   if (!res || bufSize < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glGetProgramResourceiv(%s index %d bufSize %d)",
                  _mesa_lookup_enum_by_nr(programInterface), index, bufSize);
      return;
   }

   /* Write propCount values until error occurs or bufSize reached. */
   for (int i = 0; i < propCount && i < bufSize; i++, val++, prop++) {
      int props_written =
         _mesa_program_resource_prop(shProg, res, index, *prop, val,
                                     "glGetProgramResourceiv");

      /* Error happened. */
      if (props_written == 0)
         return;

      amount += props_written;
   }

   /* If <length> is not NULL, the actual number of integer values
    * written to <params> will be written to <length>.
    */
   if (length)
      *length = amount;
}
Beispiel #28
0
void GLAPIENTRY
_mesa_ClampColor(GLenum target, GLenum clamp)
{
   GET_CURRENT_CONTEXT(ctx);

   if (clamp != GL_TRUE && clamp != GL_FALSE && clamp != GL_FIXED_ONLY_ARB) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(clamp)");
      return;
   }

   switch (target) {
   case GL_CLAMP_VERTEX_COLOR_ARB:
      if (ctx->API == API_OPENGL_CORE &&
          !ctx->Extensions.ARB_color_buffer_float) {
         goto invalid_enum;
      }
      FLUSH_VERTICES(ctx, _NEW_LIGHT);
      ctx->Light.ClampVertexColor = clamp;
      _mesa_update_clamp_vertex_color(ctx);
      break;
   case GL_CLAMP_FRAGMENT_COLOR_ARB:
      if (ctx->API == API_OPENGL_CORE &&
          !ctx->Extensions.ARB_color_buffer_float) {
         goto invalid_enum;
      }
      FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP);
      ctx->Color.ClampFragmentColor = clamp;
      _mesa_update_clamp_fragment_color(ctx);
      break;
   case GL_CLAMP_READ_COLOR_ARB:
      ctx->Color.ClampReadColor = clamp;
      break;
   default:
      goto invalid_enum;
   }
   return;

invalid_enum:
   _mesa_error(ctx, GL_INVALID_ENUM, "glClampColor(%s)",
               _mesa_lookup_enum_by_nr(target));
}
Beispiel #29
0
/**
 * Specify a logic pixel operation for color index rendering.
 *
 * \param opcode operation.
 *
 * Verifies that \p opcode is a valid enum and updates
gl_colorbuffer_attrib::LogicOp.
 * On a change, flushes the vertices and notifies the driver via the
 * dd_function_table::LogicOpcode callback.
 */
void GLAPIENTRY
_mesa_LogicOp( GLenum opcode )
{
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);

    if (MESA_VERBOSE & VERBOSE_API)
        _mesa_debug(ctx, "glLogicOp(%s)\n", _mesa_lookup_enum_by_nr(opcode));

    switch (opcode) {
    case GL_CLEAR:
    case GL_SET:
    case GL_COPY:
    case GL_COPY_INVERTED:
    case GL_NOOP:
    case GL_INVERT:
    case GL_AND:
    case GL_NAND:
    case GL_OR:
    case GL_NOR:
    case GL_XOR:
    case GL_EQUIV:
    case GL_AND_REVERSE:
    case GL_AND_INVERTED:
    case GL_OR_REVERSE:
    case GL_OR_INVERTED:
        break;
    default:
        _mesa_error( ctx, GL_INVALID_ENUM, "glLogicOp" );
        return;
    }

    if (ctx->Color.LogicOp == opcode)
        return;

    FLUSH_VERTICES(ctx, _NEW_COLOR);
    ctx->Color.LogicOp = opcode;

    if (ctx->Driver.LogicOpcode)
        ctx->Driver.LogicOpcode( ctx, opcode );
}
Beispiel #30
0
static GLboolean radeon_run_render( struct gl_context *ctx,
				    struct tnl_pipeline_stage *stage )
{
   r100ContextPtr rmesa = R100_CONTEXT(ctx);
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   struct vertex_buffer *VB = &tnl->vb;
   tnl_render_func *tab = TAG(render_tab_verts);
   GLuint i;

   if (rmesa->radeon.swtcl.RenderIndex != 0 ||   
       !radeon_dma_validate_render( ctx, VB ))
      return GL_TRUE;		

   radeon_prepare_render(&rmesa->radeon);
   if (rmesa->radeon.NewGLState)
      radeonValidateState( ctx );

   tnl->Driver.Render.Start( ctx );

   for (i = 0 ; i < VB->PrimitiveCount ; i++)
   {
      GLuint prim = VB->Primitive[i].mode;
      GLuint start = VB->Primitive[i].start;
      GLuint length = VB->Primitive[i].count;

      if (!length)
	 continue;

      radeon_print(RADEON_SWRENDER, RADEON_NORMAL,
	  "radeon_render.c: prim %s %d..%d\n",
		 _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK), 
		 start, start+length);

      if (length)
	 tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim );
   }

   tnl->Driver.Render.Finish( ctx );

   return GL_FALSE;		/* finished the pipe */
}