Beispiel #1
0
void GLAPIENTRY
_mesa_ClipControl(GLenum origin, GLenum depth)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glClipControl(%s, %s)\n",
	          _mesa_enum_to_string(origin),
                  _mesa_enum_to_string(depth));

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (!ctx->Extensions.ARB_clip_control) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glClipControl");
      return;
   }

   if (origin != GL_LOWER_LEFT && origin != GL_UPPER_LEFT) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glClipControl");
      return;
   }

   if (depth != GL_NEGATIVE_ONE_TO_ONE && depth != GL_ZERO_TO_ONE) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glClipControl");
      return;
   }

   clip_control(ctx, origin, depth);
}
Beispiel #2
0
/* GL_ARB_multitexture */
void GLAPIENTRY
_mesa_ActiveTexture(GLenum texture)
{
    const GLuint texUnit = texture - GL_TEXTURE0;
    GLuint k;
    GET_CURRENT_CONTEXT(ctx);

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

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

    k = _mesa_max_tex_unit(ctx);

    assert(k <= ARRAY_SIZE(ctx->Texture.Unit));

    if (texUnit >= k) {
        _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
                    _mesa_enum_to_string(texture));
        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];
    }
}
void
radeonReadPixels(struct gl_context * ctx,
                 GLint x, GLint y, GLsizei width, GLsizei height,
                 GLenum format, GLenum type,
                 const struct gl_pixelstore_attrib *pack, GLvoid * pixels)
{
    radeonContextPtr radeon = RADEON_CONTEXT(ctx);
    radeon_prepare_render(radeon);

    if (do_blit_readpixels(ctx, x, y, width, height, format, type, pack, pixels))
        return;

    /* Update Mesa state before calling _mesa_readpixels().
     * XXX this may not be needed since ReadPixels no longer uses the
     * span code.
     */
    radeon_print(RADEON_FALLBACKS, RADEON_NORMAL,
                 "Falling back to sw for ReadPixels (format %s, type %s)\n",
                 _mesa_enum_to_string(format), _mesa_enum_to_string(type));

    if (ctx->NewState)
        _mesa_update_state(ctx);

    _mesa_readpixels(ctx, x, y, width, height, format, type, pack, pixels);
}
Beispiel #4
0
/**
 * Set separate blend equations for one color buffer/target.
 */
void GLAPIENTRY
_mesa_BlendEquationSeparateiARB(GLuint buf, GLenum modeRGB, GLenum modeA)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glBlendEquationSeparatei(%u, %s %s)\n", buf,
                  _mesa_enum_to_string(modeRGB),
                  _mesa_enum_to_string(modeA));

   if (buf >= ctx->Const.MaxDrawBuffers) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glBlendEquationSeparatei(buffer=%u)",
                  buf);
      return;
   }

   /* Only allow simple blending equations.
    * The GL_KHR_blend_equation_advanced spec says:
    *
    *    "NOTE: These enums are not accepted by the <modeRGB> or <modeAlpha>
    *     parameters of BlendEquationSeparate or BlendEquationSeparatei."
    */
   if (!legal_simple_blend_equation(ctx, modeRGB)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeRGB)");
      return;
   }

   if (!legal_simple_blend_equation(ctx, modeA)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeA)");
      return;
   }

   blend_equation_separatei(ctx, buf, modeRGB, modeA);
}
Beispiel #5
0
/**
 * Pop the current matrix stack.
 *
 * \sa glPopMatrix().
 *
 * Flushes the vertices, verifies the current matrix stack is not empty, and
 * moves the stack head down.
 * Marks __struct gl_contextRec::NewState with the dirty stack flag.
 */
void GLAPIENTRY
_mesa_PopMatrix( void )
{
    GET_CURRENT_CONTEXT(ctx);
    struct gl_matrix_stack *stack = ctx->CurrentStack;

    FLUSH_VERTICES(ctx, 0);

    if (MESA_VERBOSE&VERBOSE_API)
        _mesa_debug(ctx, "glPopMatrix %s\n",
                    _mesa_enum_to_string(ctx->Transform.MatrixMode));

    if (stack->Depth == 0) {
        if (ctx->Transform.MatrixMode == GL_TEXTURE) {
            _mesa_error(ctx,  GL_STACK_UNDERFLOW,
                        "glPopMatrix(mode=GL_TEXTURE, unit=%d)",
                        ctx->Texture.CurrentUnit);
        }
        else {
            _mesa_error(ctx,  GL_STACK_UNDERFLOW, "glPopMatrix(mode=%s)",
                        _mesa_enum_to_string(ctx->Transform.MatrixMode));
        }
        return;
    }
    stack->Depth--;
    stack->Top = &(stack->Stack[stack->Depth]);
    ctx->NewState |= stack->DirtyFlag;
}
Beispiel #6
0
/**
 * Push the current matrix stack.
 *
 * \sa glPushMatrix().
 *
 * Verifies the current matrix stack is not full, and duplicates the top-most
 * matrix in the stack.
 * Marks __struct gl_contextRec::NewState with the stack dirty flag.
 */
void GLAPIENTRY
_mesa_PushMatrix( void )
{
    GET_CURRENT_CONTEXT(ctx);
    struct gl_matrix_stack *stack = ctx->CurrentStack;

    if (MESA_VERBOSE&VERBOSE_API)
        _mesa_debug(ctx, "glPushMatrix %s\n",
                    _mesa_enum_to_string(ctx->Transform.MatrixMode));

    if (stack->Depth + 1 >= stack->MaxDepth) {
        if (ctx->Transform.MatrixMode == GL_TEXTURE) {
            _mesa_error(ctx,  GL_STACK_OVERFLOW,
                        "glPushMatrix(mode=GL_TEXTURE, unit=%d)",
                        ctx->Texture.CurrentUnit);
        }
        else {
            _mesa_error(ctx,  GL_STACK_OVERFLOW, "glPushMatrix(mode=%s)",
                        _mesa_enum_to_string(ctx->Transform.MatrixMode));
        }
        return;
    }
    _math_matrix_copy( &stack->Stack[stack->Depth + 1],
                       &stack->Stack[stack->Depth] );
    stack->Depth++;
    stack->Top = &(stack->Stack[stack->Depth]);
    ctx->NewState |= stack->DirtyFlag;
}
Beispiel #7
0
/**
 * Set the separate blend source/dest factors for all draw buffers.
 *
 * \param sfactorRGB RGB source factor operator.
 * \param dfactorRGB RGB destination factor operator.
 * \param sfactorA alpha source factor operator.
 * \param dfactorA alpha destination factor operator.
 */
void GLAPIENTRY
_mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB,
                            GLenum sfactorA, GLenum dfactorA )
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n",
                  _mesa_enum_to_string(sfactorRGB),
                  _mesa_enum_to_string(dfactorRGB),
                  _mesa_enum_to_string(sfactorA),
                  _mesa_enum_to_string(dfactorA));



   if (skip_blend_state_update(ctx, sfactorRGB, dfactorRGB, sfactorA, dfactorA))
      return;

   if (!validate_blend_factors(ctx, "glBlendFuncSeparate",
                               sfactorRGB, dfactorRGB,
                               sfactorA, dfactorA)) {
      return;
   }

   blend_func_separate(ctx, sfactorRGB, dfactorRGB, sfactorA, dfactorA);
}
Beispiel #8
0
/**
 * Check if src/dest RGB/A blend factors are legal.  If not generate
 * a GL error.
 * \return GL_TRUE if factors are legal, GL_FALSE otherwise.
 */
static GLboolean
validate_blend_factors(struct gl_context *ctx, const char *func,
                       GLenum sfactorRGB, GLenum dfactorRGB,
                       GLenum sfactorA, GLenum dfactorA)
{
   if (!legal_src_factor(ctx, sfactorRGB)) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "%s(sfactorRGB = %s)", func,
                  _mesa_enum_to_string(sfactorRGB));
      return GL_FALSE;
   }

   if (!legal_dst_factor(ctx, dfactorRGB)) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "%s(dfactorRGB = %s)", func,
                  _mesa_enum_to_string(dfactorRGB));
      return GL_FALSE;
   }

   if (sfactorA != sfactorRGB && !legal_src_factor(ctx, sfactorA)) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "%s(sfactorA = %s)", func,
                  _mesa_enum_to_string(sfactorA));
      return GL_FALSE;
   }

   if (dfactorA != dfactorRGB && !legal_dst_factor(ctx, dfactorA)) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "%s(dfactorA = %s)", func,
                  _mesa_enum_to_string(dfactorA));
      return GL_FALSE;
   }

   return GL_TRUE;
}
Beispiel #9
0
/**
 * Returns output index for dual source blending.
 */
GLint GLAPIENTRY
_mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface,
                                      const GLchar *name)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API) {
      _mesa_debug(ctx, "glGetProgramResourceLocationIndex(%u, %s, %s)\n",
                  program, _mesa_enum_to_string(programInterface), name);
   }

   struct gl_shader_program *shProg =
      lookup_linked_program(program, "glGetProgramResourceLocationIndex");

   if (!shProg || !name)
      return -1;

   /* From the GL_ARB_program_interface_query spec:
    *
    * "For GetProgramResourceLocationIndex, <programInterface> must be
    * PROGRAM_OUTPUT."
    */
   if (programInterface != GL_PROGRAM_OUTPUT) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetProgramResourceLocationIndex(%s)",
                  _mesa_enum_to_string(programInterface));
      return -1;
   }

   return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT,
                                                name);
}
Beispiel #10
0
void GLAPIENTRY
_mesa_GetProgramResourceName(GLuint program, GLenum programInterface,
                             GLuint index, GLsizei bufSize, GLsizei *length,
                             GLchar *name)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API) {
      _mesa_debug(ctx, "glGetProgramResourceName(%u, %s, %u, %d, %p, %p)\n",
                  program, _mesa_enum_to_string(programInterface), index,
                  bufSize, length, name);
   }

   struct gl_shader_program *shProg =
      _mesa_lookup_shader_program_err(ctx, program,
                                      "glGetProgramResourceName");

   if (!shProg || !name)
      return;

   if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
       !supported_interface_enum(ctx, programInterface)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)",
                  _mesa_enum_to_string(programInterface));
      return;
   }

   _mesa_get_program_resource_name(shProg, programInterface, index, bufSize,
                                   length, name, "glGetProgramResourceName");
}
Beispiel #11
0
static void
intelTexImage(struct gl_context * ctx,
              GLuint dims,
              struct gl_texture_image *texImage,
              GLenum format, GLenum type, const void *pixels,
              const struct gl_pixelstore_attrib *unpack)
{
   struct intel_texture_image *intelImage = intel_texture_image(texImage);
   bool ok;

   bool tex_busy = intelImage->mt && drm_intel_bo_busy(intelImage->mt->bo);

   DBG("%s mesa_format %s target %s format %s type %s level %d %dx%dx%d\n",
       __func__, _mesa_get_format_name(texImage->TexFormat),
       _mesa_enum_to_string(texImage->TexObject->Target),
       _mesa_enum_to_string(format), _mesa_enum_to_string(type),
       texImage->Level, texImage->Width, texImage->Height, texImage->Depth);

   /* Allocate storage for texture data. */
   if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
      return;
   }

   assert(intelImage->mt);

   if (intelImage->mt->format == MESA_FORMAT_S_UINT8)
      intelImage->mt->r8stencil_needs_update = true;

   ok = _mesa_meta_pbo_TexSubImage(ctx, dims, texImage, 0, 0, 0,
                                   texImage->Width, texImage->Height,
                                   texImage->Depth,
                                   format, type, pixels,
                                   tex_busy, unpack);
   if (ok)
      return;

   ok = intel_texsubimage_tiled_memcpy(ctx, dims, texImage,
                                       0, 0, 0, /*x,y,z offsets*/
                                       texImage->Width,
                                       texImage->Height,
                                       texImage->Depth,
                                       format, type, pixels, unpack,
                                       false /*allocate_storage*/);
   if (ok)
      return;

   DBG("%s: upload image %dx%dx%d pixels %p\n",
       __func__, texImage->Width, texImage->Height, texImage->Depth,
       pixels);

   _mesa_store_teximage(ctx, dims, texImage,
                        format, type, pixels, unpack);
}
Beispiel #12
0
static void
i830BlendEquationSeparate(struct gl_context * ctx, GLenum modeRGB, GLenum modeA)
{
   DBG("%s -> %s, %s\n", __func__,
       _mesa_enum_to_string(modeRGB),
       _mesa_enum_to_string(modeA));

   (void) modeRGB;
   (void) modeA;
   i830_set_blend_state(ctx);
}
Beispiel #13
0
/**
 * Set the separate blend source/dest factors for all draw buffers.
 *
 * \param sfactorRGB RGB source factor operator.
 * \param dfactorRGB RGB destination factor operator.
 * \param sfactorA alpha source factor operator.
 * \param dfactorA alpha destination factor operator.
 */
void GLAPIENTRY
_mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB,
                            GLenum sfactorA, GLenum dfactorA )
{
   GLuint buf, numBuffers;
   GLboolean changed;
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n",
                  _mesa_enum_to_string(sfactorRGB),
                  _mesa_enum_to_string(dfactorRGB),
                  _mesa_enum_to_string(sfactorA),
                  _mesa_enum_to_string(dfactorA));

   if (!validate_blend_factors(ctx, "glBlendFuncSeparate",
                               sfactorRGB, dfactorRGB,
                               sfactorA, dfactorA)) {
      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].SrcRGB != sfactorRGB ||
          ctx->Color.Blend[buf].DstRGB != dfactorRGB ||
          ctx->Color.Blend[buf].SrcA != sfactorA ||
          ctx->Color.Blend[buf].DstA != dfactorA) {
         changed = GL_TRUE;
         break;
      }
   }
   if (!changed)
      return;

   FLUSH_VERTICES(ctx, _NEW_COLOR);

   for (buf = 0; buf < numBuffers; buf++) {
      ctx->Color.Blend[buf].SrcRGB = sfactorRGB;
      ctx->Color.Blend[buf].DstRGB = dfactorRGB;
      ctx->Color.Blend[buf].SrcA = sfactorA;
      ctx->Color.Blend[buf].DstA = dfactorA;
      update_uses_dual_src(ctx, buf);
   }
   ctx->Color._BlendFuncPerBuffer = GL_FALSE;

   if (ctx->Driver.BlendFuncSeparate) {
      ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB,
                                    sfactorA, dfactorA);
   }
}
Beispiel #14
0
void GLAPIENTRY
_mesa_BlendEquationSeparate( GLenum modeRGB, GLenum modeA )
{
   GLuint buf, numBuffers;
   GLboolean changed;
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glBlendEquationSeparateEXT(%s %s)\n",
                  _mesa_enum_to_string(modeRGB),
                  _mesa_enum_to_string(modeA));

   if ( (modeRGB != modeA) && !ctx->Extensions.EXT_blend_equation_separate ) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
		  "glBlendEquationSeparateEXT not supported by driver");
      return;
   }

   if (!legal_blend_equation(ctx, modeRGB)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeRGB)");
      return;
   }

   if (!legal_blend_equation(ctx, modeA)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeA)");
      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 != modeRGB ||
          ctx->Color.Blend[buf].EquationA != modeA) {
         changed = GL_TRUE;
         break;
      }
   }
   if (!changed)
      return;

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

   if (ctx->Driver.BlendEquationSeparate)
      ctx->Driver.BlendEquationSeparate(ctx, modeRGB, modeA);
}
Beispiel #15
0
GLint GLAPIENTRY
_mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface,
                                 const GLchar *name)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API) {
      _mesa_debug(ctx, "glGetProgramResourceLocation(%u, %s, %s)\n",
                  program, _mesa_enum_to_string(programInterface), name);
   }

   struct gl_shader_program *shProg =
      lookup_linked_program(program, "glGetProgramResourceLocation");

   if (!shProg || !name)
      return -1;

   /* Validate programInterface. */
   switch (programInterface) {
   case GL_UNIFORM:
   case GL_PROGRAM_INPUT:
   case GL_PROGRAM_OUTPUT:
      break;

   case GL_VERTEX_SUBROUTINE_UNIFORM:
   case GL_FRAGMENT_SUBROUTINE_UNIFORM:
      if (!_mesa_has_shader_subroutine(ctx))
         goto fail;
      break;
   case GL_GEOMETRY_SUBROUTINE_UNIFORM:
      if (!_mesa_has_geometry_shaders(ctx) || !_mesa_has_shader_subroutine(ctx))
         goto fail;
      break;
   case GL_COMPUTE_SUBROUTINE_UNIFORM:
      if (!_mesa_has_compute_shaders(ctx) || !_mesa_has_shader_subroutine(ctx))
         goto fail;
      break;
   case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
   case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
      if (!_mesa_has_tessellation(ctx) || !_mesa_has_shader_subroutine(ctx))
         goto fail;
      break;
   default:
         goto fail;
   }

   return _mesa_program_resource_location(shProg, programInterface, name);
fail:
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocation(%s %s)",
               _mesa_enum_to_string(programInterface), name);
   return -1;
}
Beispiel #16
0
TEST(EnumStrings, LookUpByNumber)
{
   for (unsigned i = 0; everything[i].name != NULL; i++) {
      EXPECT_STREQ(everything[i].name,
		   _mesa_enum_to_string(everything[i].value));
   }
}
Beispiel #17
0
static void
i830BlendFuncSeparate(struct gl_context * ctx, GLenum sfactorRGB,
                      GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA)
{
   DBG("%s -> RGB(%s, %s) A(%s, %s)\n", __func__,
       _mesa_enum_to_string(sfactorRGB),
       _mesa_enum_to_string(dfactorRGB),
       _mesa_enum_to_string(sfactorA),
       _mesa_enum_to_string(dfactorA));

   (void) sfactorRGB;
   (void) dfactorRGB;
   (void) sfactorA;
   (void) dfactorA;
   i830_set_blend_state(ctx);
}
Beispiel #18
0
/**
 * Specify the alpha test function.
 *
 * \param func alpha comparison function.
 * \param ref reference value.
 *
 * Verifies the parameters and updates gl_colorbuffer_attrib. 
 * On a change, flushes the vertices and notifies the driver via
 * dd_function_table::AlphaFunc callback.
 */
void GLAPIENTRY
_mesa_AlphaFunc( GLenum func, GLclampf ref )
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glAlphaFunc(%s, %f)\n",
                  _mesa_enum_to_string(func), ref);

   if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRefUnclamped == ref)
      return; /* no change */

   switch (func) {
   case GL_NEVER:
   case GL_LESS:
   case GL_EQUAL:
   case GL_LEQUAL:
   case GL_GREATER:
   case GL_NOTEQUAL:
   case GL_GEQUAL:
   case GL_ALWAYS:
      FLUSH_VERTICES(ctx, _NEW_COLOR);
      ctx->Color.AlphaFunc = func;
      ctx->Color.AlphaRefUnclamped = ref;
      ctx->Color.AlphaRef = CLAMP(ref, 0.0F, 1.0F);

      if (ctx->Driver.AlphaFunc)
         ctx->Driver.AlphaFunc(ctx, func, ctx->Color.AlphaRef);
      return;

   default:
      _mesa_error( ctx, GL_INVALID_ENUM, "glAlphaFunc(func)" );
      return;
   }
}
Beispiel #19
0
/**
 * Set blend equation for one color buffer/target.
 */
void GLAPIENTRY
_mesa_BlendEquationiARB(GLuint buf, GLenum mode)
{
   GET_CURRENT_CONTEXT(ctx);
   enum gl_advanced_blend_mode advanced_mode = advanced_blend_mode(ctx, mode);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glBlendEquationi(%u, %s)\n",
                  buf, _mesa_enum_to_string(mode));

   if (buf >= ctx->Const.MaxDrawBuffers) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glBlendEquationi(buffer=%u)",
                  buf);
      return;
   }

   if (!legal_simple_blend_equation(ctx, mode) && !advanced_mode) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationi");
      return;
   }

   if (ctx->Color.Blend[buf].EquationRGB == mode &&
       ctx->Color.Blend[buf].EquationA == mode)
      return;  /* no change */

   FLUSH_VERTICES(ctx, _NEW_COLOR);
   ctx->Color.Blend[buf].EquationRGB = mode;
   ctx->Color.Blend[buf].EquationA = mode;
   ctx->Color._BlendEquationPerBuffer = GL_TRUE;

   if (buf == 0)
      ctx->Color._AdvancedBlendMode = advanced_mode;
}
Beispiel #20
0
/* When the primitive changes, set a state bit and re-validate.  Not
 * the nicest and would rather deal with this by having all the
 * programs be immune to the active primitive (ie. cope with all
 * possibilities).  That may not be realistic however.
 */
static void
brw_set_prim(struct brw_context *brw, const struct _mesa_prim *prim)
{
   struct gl_context *ctx = &brw->ctx;
   uint32_t hw_prim = get_hw_prim_for_gl_prim(prim->mode);

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

   /* Slight optimization to avoid the GS program when not needed:
    */
   if (prim->mode == GL_QUAD_STRIP &&
       ctx->Light.ShadeModel != GL_FLAT &&
       ctx->Polygon.FrontMode == GL_FILL &&
       ctx->Polygon.BackMode == GL_FILL)
      hw_prim = _3DPRIM_TRISTRIP;

   if (prim->mode == GL_QUADS && prim->count == 4 &&
       ctx->Light.ShadeModel != GL_FLAT &&
       ctx->Polygon.FrontMode == GL_FILL &&
       ctx->Polygon.BackMode == GL_FILL) {
      hw_prim = _3DPRIM_TRIFAN;
   }

   if (hw_prim != brw->primitive) {
      brw->primitive = hw_prim;
      brw->ctx.NewDriverState |= BRW_NEW_PRIMITIVE;

      if (reduced_prim[prim->mode] != brw->reduced_primitive) {
	 brw->reduced_primitive = reduced_prim[prim->mode];
	 brw->ctx.NewDriverState |= BRW_NEW_REDUCED_PRIMITIVE;
      }
   }
}
/**
 * Print framebuffer info to stderr, for debugging.
 */
void
_mesa_print_framebuffer(const struct gl_framebuffer *fb)
{
   GLuint i;

   fprintf(stderr, "Mesa Framebuffer %u at %p\n", fb->Name, (void *) fb);
   fprintf(stderr, "  Size: %u x %u  Status: %s\n", fb->Width, fb->Height,
           _mesa_enum_to_string(fb->_Status));
   fprintf(stderr, "  Attachments:\n");

   for (i = 0; i < BUFFER_COUNT; i++) {
      const struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
      if (att->Type == GL_TEXTURE) {
         const struct gl_texture_image *texImage = att->Renderbuffer->TexImage;
         fprintf(stderr,
                 "  %2d: Texture %u, level %u, face %u, slice %u, complete %d\n",
                 i, att->Texture->Name, att->TextureLevel, att->CubeMapFace,
                 att->Zoffset, att->Complete);
         fprintf(stderr, "       Size: %u x %u x %u  Format %s\n",
                 texImage->Width, texImage->Height, texImage->Depth,
                 _mesa_get_format_name(texImage->TexFormat));
      }
      else if (att->Type == GL_RENDERBUFFER) {
         fprintf(stderr, "  %2d: Renderbuffer %u, complete %d\n",
                 i, att->Renderbuffer->Name, att->Complete);
         fprintf(stderr, "       Size: %u x %u  Format %s\n",
                 att->Renderbuffer->Width, att->Renderbuffer->Height,
                 _mesa_get_format_name(att->Renderbuffer->Format));
      }
      else {
         fprintf(stderr, "  %2d: none\n", i);
      }
   }
}
Beispiel #22
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);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glLogicOp(%s)\n", _mesa_enum_to_string(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;
   }

   logic_op(ctx, opcode);
}
/**
 * @param for_bo Indicates that the caller is
 *        intel_miptree_create_for_bo(). If true, then do not create
 *        \c stencil_mt.
 */
struct intel_mipmap_tree *
intel_miptree_create_layout(struct intel_context *intel,
                            GLenum target,
                            mesa_format format,
                            GLuint first_level,
                            GLuint last_level,
                            GLuint width0,
                            GLuint height0,
                            GLuint depth0,
                            bool for_bo)
{
    struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
    if (!mt)
        return NULL;

    DBG("%s target %s format %s level %d..%d <-- %p\n", __func__,
        _mesa_enum_to_string(target),
        _mesa_get_format_name(format),
        first_level, last_level, mt);

    mt->target = target_to_target(target);
    mt->format = format;
    mt->first_level = first_level;
    mt->last_level = last_level;
    mt->logical_width0 = width0;
    mt->logical_height0 = height0;
    mt->logical_depth0 = depth0;

    /* The cpp is bytes per (1, blockheight)-sized block for compressed
     * textures.  This is why you'll see divides by blockheight all over
     */
    unsigned bw, bh;
    _mesa_get_format_block_size(format, &bw, &bh);
    assert(_mesa_get_format_bytes(mt->format) % bw == 0);
    mt->cpp = _mesa_get_format_bytes(mt->format) / bw;

    mt->compressed = _mesa_is_format_compressed(format);
    mt->refcount = 1;

    if (target == GL_TEXTURE_CUBE_MAP) {
        assert(depth0 == 1);
        depth0 = 6;
    }

    mt->physical_width0 = width0;
    mt->physical_height0 = height0;
    mt->physical_depth0 = depth0;

    intel_get_texture_alignment_unit(intel, mt->format,
                                     &mt->align_w, &mt->align_h);

    (void) intel;
    if (intel->is_945)
        i945_miptree_layout(mt);
    else
        i915_miptree_layout(mt);

    return mt;
}
Beispiel #24
0
/* GL_ARB_multitexture */
static ALWAYS_INLINE void
active_texture(GLenum texture, bool no_error)
{
   const GLuint texUnit = texture - GL_TEXTURE0;

   GET_CURRENT_CONTEXT(ctx);

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

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

   if (!no_error) {
      GLuint k = _mesa_max_tex_unit(ctx);

      assert(k <= ARRAY_SIZE(ctx->Texture.Unit));

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


   /* The below flush call seems useless because
    * gl_context::Texture::CurrentUnit is not used by
    * _mesa_update_texture_state() and friends.
    *
    * However removing the flush
    * introduced some blinking textures in UT2004. More investigation is
    * needed to find the root cause.
    *
    * https://bugs.freedesktop.org/show_bug.cgi?id=105436
    */
   FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE);

   ctx->Texture.CurrentUnit = texUnit;
   if (ctx->Transform.MatrixMode == GL_TEXTURE) {
      /* update current stack pointer */
      ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
   }
}
Beispiel #25
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
_mesa_draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
                  GLenum buffer, const char *caller)
{
   GLbitfield destMask;

   FLUSH_VERTICES(ctx, 0);

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

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

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

   /* Call device driver function only if fb is the bound draw buffer */
   if (fb == ctx->DrawBuffer) {
      if (ctx->Driver.DrawBuffers)
         ctx->Driver.DrawBuffers(ctx, 1, &buffer);
      else if (ctx->Driver.DrawBuffer)
         ctx->Driver.DrawBuffer(ctx, buffer);
   }
}
Beispiel #26
0
void
brw_draw_prims(struct gl_context *ctx,
               const struct _mesa_prim *prims,
               GLuint nr_prims,
               const struct _mesa_index_buffer *ib,
               GLboolean index_bounds_valid,
               GLuint min_index,
               GLuint max_index,
               struct gl_transform_feedback_object *gl_xfb_obj,
               unsigned stream,
               struct gl_buffer_object *indirect)
{
   struct brw_context *brw = brw_context(ctx);
   const struct gl_client_array **arrays = ctx->Array._DrawArrays;
   struct brw_transform_feedback_object *xfb_obj =
      (struct brw_transform_feedback_object *) gl_xfb_obj;

   if (!brw_check_conditional_render(brw))
      return;

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

   /* 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_enum_to_string(ctx->RenderMode));
      _swsetup_Wakeup(ctx);
      _tnl_wakeup(ctx);
      _tnl_draw_prims(ctx, prims, nr_prims, ib,
                      index_bounds_valid, min_index, max_index, NULL, 0, NULL);
      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 (!index_bounds_valid && !vbo_all_varyings_in_vbos(arrays)) {
      perf_debug("Scanning index buffer to compute index buffer bounds.  "
                 "Use glDrawRangeElements() to avoid this.\n");
      vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, nr_prims);
      index_bounds_valid = true;
   }

   /* 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, prims, nr_prims, ib, index_bounds_valid,
                      min_index, max_index, xfb_obj, stream, indirect);
}
Beispiel #27
0
/**
 * Called by glReadBuffer to set the source renderbuffer for reading pixels.
 * \param mode color buffer such as GL_FRONT, GL_BACK, etc.
 */
void
_mesa_read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb,
                  GLenum buffer, const char *caller)
{
   GLbitfield supportedMask;
   GLint srcBuffer;

   FLUSH_VERTICES(ctx, 0);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "%s %s\n", caller, _mesa_enum_to_string(buffer));

   if (buffer == GL_NONE) {
      /* This is legal--it means that no buffer should be bound for reading. */
      srcBuffer = -1;
   }
   else {
      /* general case / window-system framebuffer */
      srcBuffer = read_buffer_enum_to_index(buffer);
      if (srcBuffer == -1) {
         _mesa_error(ctx, GL_INVALID_ENUM,
                     "%s(invalid buffer %s)", caller,
                     _mesa_enum_to_string(buffer));
         return;
      }
      supportedMask = supported_buffer_bitmask(ctx, fb);
      if (((1 << srcBuffer) & supportedMask) == 0) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "%s(invalid buffer %s)", caller,
                     _mesa_enum_to_string(buffer));
         return;
      }
   }

   /* OK, all error checking has been completed now */

   _mesa_readbuffer(ctx, fb, buffer, srcBuffer);

   /* Call the device driver function only if fb is the bound read buffer */
   if (fb == ctx->ReadBuffer) {
      if (ctx->Driver.ReadBuffer)
         (*ctx->Driver.ReadBuffer)(ctx, buffer);
   }
}
Beispiel #28
0
void GLAPIENTRY
_mesa_ClipControl(GLenum origin, GLenum depth)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glClipControl(%s, %s)\n",
	          _mesa_enum_to_string(origin),
                  _mesa_enum_to_string(depth));

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (!ctx->Extensions.ARB_clip_control) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glClipControl");
      return;
   }

   clip_control(ctx, origin, depth, false);
}
Beispiel #29
0
/**
 * Set separate blend equations for one color buffer/target.
 */
void GLAPIENTRY
_mesa_BlendEquationSeparateiARB(GLuint buf, GLenum modeRGB, GLenum modeA)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glBlendEquationSeparatei(%u, %s %s)\n", buf,
                  _mesa_enum_to_string(modeRGB),
                  _mesa_enum_to_string(modeA));

   if (buf >= ctx->Const.MaxDrawBuffers) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glBlendEquationSeparatei(buffer=%u)",
                  buf);
      return;
   }

   /* Only allow simple blending equations.
    * The GL_KHR_blend_equation_advanced spec says:
    *
    *    "NOTE: These enums are not accepted by the <modeRGB> or <modeAlpha>
    *     parameters of BlendEquationSeparate or BlendEquationSeparatei."
    */
   if (!legal_simple_blend_equation(ctx, modeRGB)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeRGB)");
      return;
   }

   if (!legal_simple_blend_equation(ctx, modeA)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeA)");
      return;
   }

   if (ctx->Color.Blend[buf].EquationRGB == modeRGB &&
       ctx->Color.Blend[buf].EquationA == modeA)
      return;  /* no change */

   FLUSH_VERTICES(ctx, _NEW_COLOR);
   ctx->Color.Blend[buf].EquationRGB = modeRGB;
   ctx->Color.Blend[buf].EquationA = modeA;
   ctx->Color._BlendEquationPerBuffer = GL_TRUE;
   ctx->Color._AdvancedBlendMode = BLEND_NONE;
}
Beispiel #30
0
static void
gen6_set_prim(struct brw_context *brw, const struct _mesa_prim *prim)
{
   DBG("PRIM: %s\n", _mesa_enum_to_string(prim->mode));

   const uint32_t hw_prim = get_hw_prim_for_gl_prim(prim->mode);
   if (hw_prim != brw->primitive) {
      brw->primitive = hw_prim;
      brw->ctx.NewDriverState |= BRW_NEW_PRIMITIVE;
   }
}