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); }
/* 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); }
/** * 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); }
/** * 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; }
/** * 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; }
/** * 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); }
/** * 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; }
/** * 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); }
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"); }
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); }
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); }
/** * 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); } }
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); }
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; }
TEST(EnumStrings, LookUpByNumber) { for (unsigned i = 0; everything[i].name != NULL; i++) { EXPECT_STREQ(everything[i].name, _mesa_enum_to_string(everything[i].value)); } }
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); }
/** * 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; } }
/** * 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; }
/* 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); } } }
/** * 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; }
/* 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]; } }
/** * 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); } }
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); }
/** * 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); } }
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); }
/** * 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; }
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; } }