static void GLAPIENTRY _tnl_EvalCoord2f( GLfloat u, GLfloat v ) { GET_CURRENT_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); /* TODO: use a CHOOSE() function for this: */ { GLint i; if (tnl->vtx.eval.new_state) _tnl_update_eval( ctx ); for (i = 0 ; i <= _TNL_ATTRIB_INDEX ; i++) { if (tnl->vtx.eval.map2[i].map) if (tnl->vtx.attrsz[i] != tnl->vtx.eval.map2[i].sz) _tnl_fixup_vertex( ctx, i, tnl->vtx.eval.map2[i].sz ); } if (ctx->Eval.AutoNormal) if (tnl->vtx.attrsz[_TNL_ATTRIB_NORMAL] != 3) _tnl_fixup_vertex( ctx, _TNL_ATTRIB_NORMAL, 3 ); } _mesa_memcpy( tnl->vtx.copied.buffer, tnl->vtx.vertex, tnl->vtx.vertex_size * sizeof(GLfloat)); _tnl_do_EvalCoord2f( ctx, u, v ); _mesa_memcpy( tnl->vtx.vertex, tnl->vtx.copied.buffer, tnl->vtx.vertex_size * sizeof(GLfloat)); }
static void GLAPIENTRY vbo_exec_EvalCoord2f( GLfloat u, GLfloat v ) { GET_CURRENT_CONTEXT( ctx ); struct vbo_exec_context *exec = &vbo_context(ctx)->exec; { GLint i; if (exec->eval.recalculate_maps) vbo_exec_eval_update( exec ); for (i = 0; i <= VBO_ATTRIB_TEX7; i++) { if (exec->eval.map2[i].map) if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz) vbo_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz ); } if (ctx->Eval.AutoNormal) if (exec->vtx.active_sz[VBO_ATTRIB_NORMAL] != 3) vbo_exec_fixup_vertex( ctx, VBO_ATTRIB_NORMAL, 3 ); } _mesa_memcpy( exec->vtx.copied.buffer, exec->vtx.vertex, exec->vtx.vertex_size * sizeof(GLfloat)); vbo_exec_do_EvalCoord2f( exec, u, v ); _mesa_memcpy( exec->vtx.vertex, exec->vtx.copied.buffer, exec->vtx.vertex_size * sizeof(GLfloat)); }
/* Deal with buffer wrapping where provoked by the vertex buffer * filling up, as opposed to upgrade_vertex(). * * Make it GLAPIENTRY, so we can tail from the codegen'ed Vertex*fv */ void GLAPIENTRY _tnl_wrap_filled_vertex( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLfloat *data = tnl->vtx.copied.buffer; GLuint i; /* Run pipeline on current vertices, copy wrapped vertices * to tnl->copied. */ _tnl_wrap_buffers( ctx ); /* Copy stored stored vertices to start of new list. */ assert(tnl->vtx.counter > tnl->vtx.copied.nr); for (i = 0 ; i < tnl->vtx.copied.nr ; i++) { _mesa_memcpy( tnl->vtx.vbptr, data, tnl->vtx.vertex_size * sizeof(GLfloat)); tnl->vtx.vbptr += tnl->vtx.vertex_size; data += tnl->vtx.vertex_size; tnl->vtx.counter--; } tnl->vtx.copied.nr = 0; }
/** * Construct the GL_EXTENSIONS string. Called the first time that * glGetString(GL_EXTENSIONS) is called. */ GLubyte * _mesa_make_extension_string( GLcontext *ctx ) { const GLboolean *base = (const GLboolean *) &ctx->Extensions; GLuint extStrLen = 0; GLubyte *s; GLuint i; /* first, compute length of the extension string */ for (i = 0 ; i < Elements(default_extensions) ; i++) { if (!default_extensions[i].flag_offset || *(base + default_extensions[i].flag_offset)) { extStrLen += (GLuint)_mesa_strlen(default_extensions[i].name) + 1; } } s = (GLubyte *) _mesa_malloc(extStrLen); /* second, build the extension string */ extStrLen = 0; for (i = 0 ; i < Elements(default_extensions) ; i++) { if (!default_extensions[i].flag_offset || *(base + default_extensions[i].flag_offset)) { GLuint len = (GLuint)_mesa_strlen(default_extensions[i].name); _mesa_memcpy(s + extStrLen, default_extensions[i].name, len); extStrLen += len; s[extStrLen] = (GLubyte) ' '; extStrLen++; } } ASSERT(extStrLen > 0); s[extStrLen - 1] = 0; return s; }
/** * glGetTexImage for YCbCr pixels. */ static void get_tex_ycbcr(GLcontext *ctx, GLuint dimensions, GLenum format, GLenum type, GLvoid *pixels, const struct gl_texture_image *texImage) { const GLint width = texImage->Width; const GLint height = texImage->Height; const GLint depth = texImage->Depth; const GLint rowstride = texImage->RowStride; const GLushort *src = (const GLushort *) texImage->Data; GLint img, row; for (img = 0; img < depth; img++) { for (row = 0; row < height; row++) { void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, width, height, format, type, img, row, 0); _mesa_memcpy(dest, src, width * sizeof(GLushort)); /* check for byte swapping */ if ((texImage->TexFormat == MESA_FORMAT_YCBCR && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) || (texImage->TexFormat == MESA_FORMAT_YCBCR_REV && type == GL_UNSIGNED_SHORT_8_8_MESA)) { if (!ctx->Pack.SwapBytes) _mesa_swap2((GLushort *) dest, width); } else if (ctx->Pack.SwapBytes) { _mesa_swap2((GLushort *) dest, width); } src += rowstride; } } }
void GLAPIENTRY _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) { const struct gl_program *prog; char *dst = (char *) string; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (target == GL_VERTEX_PROGRAM_ARB) { prog = &(ctx->VertexProgram.Current->Base); } else if (target == GL_FRAGMENT_PROGRAM_ARB) { prog = &(ctx->FragmentProgram.Current->Base); } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)"); return; } ASSERT(prog); if (pname != GL_PROGRAM_STRING_ARB) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)"); return; } if (prog->String) _mesa_memcpy(dst, prog->String, _mesa_strlen((char *) prog->String)); else *dst = '\0'; }
/** * Find the line number and column for 'pos' within 'string'. * Return a copy of the line which contains 'pos'. Free the line with * _mesa_free(). * \param string the program string * \param pos the position within the string * \param line returns the line number corresponding to 'pos'. * \param col returns the column number corresponding to 'pos'. * \return copy of the line containing 'pos'. */ const GLubyte * _mesa_find_line_column(const GLubyte *string, const GLubyte *pos, GLint *line, GLint *col) { const GLubyte *lineStart = string; const GLubyte *p = string; GLubyte *s; int len; *line = 1; while (p != pos) { if (*p == (GLubyte) '\n') { (*line)++; lineStart = p + 1; } p++; } *col = (pos - lineStart) + 1; /* return copy of this line */ while (*p != 0 && *p != '\n') p++; len = p - lineStart; s = (GLubyte *) _mesa_malloc(len + 1); _mesa_memcpy(s, lineStart, len); s[len] = 0; return s; }
/** * glGetTexImage for depth/stencil pixels. */ static void get_tex_depth_stencil(GLcontext *ctx, GLuint dimensions, GLenum format, GLenum type, GLvoid *pixels, const struct gl_texture_image *texImage) { const GLint width = texImage->Width; const GLint height = texImage->Height; const GLint depth = texImage->Depth; const GLuint *src = (const GLuint *) texImage->Data; GLint img, row; for (img = 0; img < depth; img++) { for (row = 0; row < height; row++) { void *dest = _mesa_image_address(dimensions, &ctx->Pack, pixels, width, height, format, type, img, row, 0); _mesa_memcpy(dest, src, width * sizeof(GLuint)); if (ctx->Pack.SwapBytes) { _mesa_swap4((GLuint *) dest, width); } src += width * row + width * height * img; } } }
void * _slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize) { #if USE_MALLOC_FREE return _mesa_realloc(oldBuffer, oldSize, newSize); #else GET_CURRENT_CONTEXT(ctx); slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool; if (newSize < oldSize) { return oldBuffer; } else { const GLuint copySize = (oldSize < newSize) ? oldSize : newSize; void *newBuffer = _slang_alloc(newSize); if (oldBuffer) ASSERT(is_valid_address(pool, oldBuffer)); if (newBuffer && oldBuffer && copySize > 0) _mesa_memcpy(newBuffer, oldBuffer, copySize); return newBuffer; } #endif }
/* Extract a named attribute from a hardware vertex. Will have to * reverse any viewport transformation, swizzling or other conversions * which may have been applied: */ void _tnl_get_attr( GLcontext *ctx, const void *vin, GLenum attr, GLfloat *dest ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); const struct tnl_clipspace_attr *a = vtx->attr; const GLuint attr_count = vtx->attr_count; GLuint j; for (j = 0; j < attr_count; j++) { if (a[j].attrib == attr) { a[j].extract( &a[j], dest, (GLubyte *)vin + a[j].vertoffset ); return; } } /* Else return the value from ctx->Current. */ if (attr == _TNL_ATTRIB_POINTSIZE) { /* If the hardware vertex doesn't have point size then use size from * GLcontext. XXX this will be wrong if drawing attenuated points! */ dest[0] = ctx->Point.Size; } else { _mesa_memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat)); } }
void GLAPIENTRY _mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) { GET_CURRENT_CONTEXT(ctx); struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync; GLsizei size = 0; GLint v[1]; ASSERT_OUTSIDE_BEGIN_END(ctx); if (!_mesa_validate_sync(syncObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetSynciv"); return; } switch (pname) { case GL_OBJECT_TYPE: v[0] = syncObj->Type; size = 1; break; case GL_SYNC_CONDITION: v[0] = syncObj->SyncCondition; size = 1; break; case GL_SYNC_STATUS: /* Update the state of the sync by dipping into the driver. Note that * this call won't block. It just updates state in the common object * data from the current driver state. */ ctx->Driver.CheckSync(ctx, syncObj); v[0] = (syncObj->StatusFlag) ? GL_SIGNALED : GL_UNSIGNALED; size = 1; break; case GL_SYNC_FLAGS: v[0] = syncObj->Flags; size = 1; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetSynciv(pname=0x%x)\n", pname); return; } if (size > 0) { const GLsizei copy_count = MIN2(size, bufSize); _mesa_memcpy(values, v, sizeof(GLint) * copy_count); } if (length != NULL) { *length = size; } }
/* If the backbuffer is on a videocard, this is extraordinarily slow! */ static EGLBoolean fbSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) { fbContext *context = (fbContext *)_eglGetCurrentContext(); fbSurface *fs = Lookup_fbSurface(draw); struct gl_renderbuffer * front_renderbuffer = fs->mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; void *frontBuffer = front_renderbuffer->Data; int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch; void *backBuffer = fs->mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data; if (!_eglSwapBuffers(drv, dpy, draw)) return EGL_FALSE; if (context) { GLcontext *ctx = context->glCtx; if (ctx->Visual.doubleBufferMode) { int i; int offset = 0; char *tmp = _mesa_malloc(currentPitch); _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ ASSERT(frontBuffer); ASSERT(backBuffer); for (i = 0; i < fs->Base.Height; i++) { _mesa_memcpy(tmp, (char *) backBuffer + offset, currentPitch); _mesa_memcpy((char *) frontBuffer + offset, tmp, currentPitch); offset += currentPitch; } _mesa_free(tmp); } } else { /* XXX this shouldn't be an error but we can't handle it for now */ _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n"); return EGL_FALSE; } return EGL_TRUE; }
/** * Retrieve data from a subrange of buffer object. If the data range * specified by \c size + \c offset extends beyond the end of the buffer or * if \c data is \c NULL, no copy is performed. * * This is the default callback for \c dd_function_table::GetBufferSubData() * Note that all GL error checking will have been done already. * * \param ctx GL context. * \param target Buffer object target on which to operate. * \param offset Offset of the first byte to be fetched. * \param size Size, in bytes, of the data range. * \param data Destination for data * \param bufObj Object to be used. * * \sa glBufferGetSubDataARB, dd_function_table::GetBufferSubData. */ static void _mesa_buffer_get_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid * data, struct gl_buffer_object * bufObj ) { (void) ctx; (void) target; if (bufObj->Data && ((GLsizeiptrARB) (size + offset) <= bufObj->Size)) { _mesa_memcpy( data, (GLubyte *) bufObj->Data + offset, size ); } }
void brw_init_state( struct brw_context *brw ) { GLuint i; brw_init_pools(brw); brw_init_caches(brw); brw->state.atoms = _mesa_malloc(sizeof(atoms)); brw->state.nr_atoms = sizeof(atoms)/sizeof(*atoms); _mesa_memcpy(brw->state.atoms, atoms, sizeof(atoms)); /* Patch in a pointer to the dynamic state atom: */ for (i = 0; i < brw->state.nr_atoms; i++) if (brw->state.atoms[i] == NULL) brw->state.atoms[i] = &brw->curbe.tracked_state; _mesa_memcpy(&brw->curbe.tracked_state, &brw_constant_buffer, sizeof(brw_constant_buffer)); }
/* If the backbuffer is on a videocard, this is extraordinarily slow! */ static void fbSwapBuffers( __DRIdrawablePrivate *dPriv ) { struct gl_framebuffer *mesa_framebuffer = (struct gl_framebuffer *)dPriv->driverPrivate; struct gl_renderbuffer * front_renderbuffer = mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; void *frontBuffer = front_renderbuffer->Data; int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch; void *backBuffer = mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data; if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { fbContextPtr fbmesa = (fbContextPtr) dPriv->driContextPriv->driverPrivate; GLcontext *ctx = fbmesa->glCtx; if (ctx->Visual.doubleBufferMode) { int i; int offset = 0; char *tmp = _mesa_malloc(currentPitch); _mesa_notifySwapBuffers( ctx ); /* flush pending rendering commands */ ASSERT(frontBuffer); ASSERT(backBuffer); for (i = 0; i < dPriv->h; i++) { _mesa_memcpy(tmp, (char *) backBuffer + offset, currentPitch); _mesa_memcpy((char *) frontBuffer + offset, tmp, currentPitch); offset += currentPitch; } _mesa_free(tmp); } } else { /* XXX this shouldn't be an error but we can't handle it for now */ _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n"); } }
static GLboolean pp_symbols_erase (pp_symbols *self, pp_symbol *symbol) { assert (symbol >= self->symbols && symbol < self->symbols + self->count); self->count--; pp_symbol_free (symbol); if (symbol < self->symbols + self->count) _mesa_memcpy (symbol, symbol + 1, sizeof (pp_symbol) * (self->symbols + self->count - symbol)); self->symbols = (pp_symbol *) (_mesa_realloc (self->symbols, (self->count + 1) * sizeof (pp_symbol), self->count * sizeof (pp_symbol))); return self->symbols != NULL; }
/** * Replace data in a subrange of buffer object. If the data range * specified by \c size + \c offset extends beyond the end of the buffer or * if \c data is \c NULL, no copy is performed. * * This is the default callback for \c dd_function_table::BufferSubData() * Note that all GL error checking will have been done already. * * \param ctx GL context. * \param target Buffer object target on which to operate. * \param offset Offset of the first byte to be modified. * \param size Size, in bytes, of the data range. * \param data Pointer to the data to store in the buffer object. * \param bufObj Object to be used. * * \sa glBufferSubDataARB, dd_function_table::BufferSubData. */ static void _mesa_buffer_subdata( GLcontext *ctx, GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data, struct gl_buffer_object * bufObj ) { (void) ctx; (void) target; /* this should have been caught in _mesa_BufferSubData() */ ASSERT(size + offset <= bufObj->Size); if (bufObj->Data) { _mesa_memcpy( (GLubyte *) bufObj->Data + offset, data, size ); } }
static GLboolean Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst) { const GLubyte *str; GLubyte *msg; GLuint len; GLint idx; /* The first argument is a literal string 'just like this' */ if (!Parse_String(parseState, "'")) RETURN_ERROR1("Expected '"); str = parseState->pos; for (len = 0; str[len] != '\''; len++) /* find closing quote */ ; parseState->pos += len + 1; msg = (GLubyte*) _mesa_malloc(len + 1); _mesa_memcpy(msg, str, len); msg[len] = 0; inst->Data = msg; if (Parse_String(parseState, ",")) { /* got an optional register to print */ GLubyte token[100]; GetToken(parseState, token); if (token[0] == 'o') { /* dst reg */ if (!Parse_OutputReg(parseState, &idx)) RETURN_ERROR; inst->SrcReg[0].Index = idx; inst->SrcReg[0].File = PROGRAM_OUTPUT; } else { /* src reg */ if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) RETURN_ERROR; } } else { inst->SrcReg[0].File = PROGRAM_UNDEFINED; } inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; inst->SrcReg[0].Abs = GL_FALSE; inst->SrcReg[0].Negate = NEGATE_NONE; return GL_TRUE; }
/** * This is the software fallback for Driver.GetCompressedTexImage(). * All error checking will have been done before this routine is called. */ void _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level, GLvoid *img, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { const GLuint row_stride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); const GLuint row_stride_stored = _mesa_format_row_stride(texImage->TexFormat, texImage->RowStride); GLuint i; if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { /* pack texture image into a PBO */ GLubyte *buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); if (!buf) { /* out of memory or other unexpected error */ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetCompresssedTexImage(map PBO failed)"); return; } img = ADD_POINTERS(buf, img); } /* no pixelstore or pixel transfer, but respect stride */ if (row_stride == row_stride_stored) { const GLuint size = _mesa_format_image_size(texImage->TexFormat, texImage->Width, texImage->Height, texImage->Depth); _mesa_memcpy(img, texImage->Data, size); } else { GLuint bw, bh; _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); for (i = 0; i < (texImage->Height + bh - 1) / bh; i++) { memcpy((GLubyte *)img + i * row_stride, (GLubyte *)texImage->Data + i * row_stride_stored, row_stride); } } if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, ctx->Pack.BufferObj); } }
/** * This is the software fallback for Driver.GetCompressedTexImage(). * All error checking will have been done before this routine is called. */ void _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level, GLvoid *img, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { GLuint size; if (ctx->Pack.BufferObj->Name) { /* pack texture image into a PBO */ GLubyte *buf; if ((const GLubyte *) img + texImage->CompressedSize > (const GLubyte *) ctx->Pack.BufferObj->Size) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImage(invalid PBO access)"); return; } buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj); if (!buf) { /* buffer is already mapped - that's an error */ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImage(PBO is mapped)"); return; } img = ADD_POINTERS(buf, img); } else if (!img) { /* not an error */ return; } /* don't use texImage->CompressedSize since that may be padded out */ size = _mesa_compressed_texture_size(ctx, texImage->Width, texImage->Height, texImage->Depth, texImage->TexFormat->MesaFormat); /* just memcpy, no pixelstore or pixel transfer */ _mesa_memcpy(img, texImage->Data, size); if (ctx->Pack.BufferObj->Name) { ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, ctx->Pack.BufferObj); } }
/* Extract a named attribute from a hardware vertex. Will have to * reverse any viewport transformation, swizzling or other conversions * which may have been applied: */ void _tnl_get_attr( GLcontext *ctx, const void *vin, GLenum attr, GLfloat *dest ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); const struct tnl_clipspace_attr *a = vtx->attr; const GLuint attr_count = vtx->attr_count; GLuint j; for (j = 0; j < attr_count; j++) { if (a[j].attrib == attr) { a[j].extract( &a[j], dest, (GLubyte *)vin + a[j].vertoffset ); return; } } /* Else return the value from ctx->Current -- dangerous??? */ _mesa_memcpy( dest, ctx->Current.Attrib[attr], 4*sizeof(GLfloat)); }
/* Extract color attributes from one vertex and insert them into * another. (Shortcircuit extract/insert with memcpy). */ static void generic_copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc ) { struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size; GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size; const struct tnl_clipspace_attr *a = vtx->attr; const GLuint attr_count = vtx->attr_count; GLuint j; for (j = 0; j < attr_count; j++) { if (a[j].attrib == VERT_ATTRIB_COLOR0 || a[j].attrib == VERT_ATTRIB_COLOR1) { _mesa_memcpy( vdst + a[j].vertoffset, vsrc + a[j].vertoffset, a[j].vertattrsize ); } } }
/** * Allocate space for and store data in a buffer object. Any data that was * previously stored in the buffer object is lost. If \c data is \c NULL, * memory will be allocated, but no copy will occur. * * This is the default callback for \c dd_function_table::BufferData() * Note that all GL error checking will have been done already. * * \param ctx GL context. * \param target Buffer object target on which to operate. * \param size Size, in bytes, of the new data store. * \param data Pointer to the data to store in the buffer object. This * pointer may be \c NULL. * \param usage Hints about how the data will be used. * \param bufObj Object to be used. * * \sa glBufferDataARB, dd_function_table::BufferData. */ static void _mesa_buffer_data( GLcontext *ctx, GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage, struct gl_buffer_object * bufObj ) { void * new_data; (void) ctx; (void) target; new_data = _mesa_realloc( bufObj->Data, bufObj->Size, size ); if (new_data) { bufObj->Data = (GLubyte *) new_data; bufObj->Size = size; bufObj->Usage = usage; if (data) { _mesa_memcpy( bufObj->Data, data, size ); } } }
/* Called only when buffers are wrapped as the result of filling the * vertex_store struct. */ static void _save_wrap_filled_vertex( GLcontext *ctx ) { struct vbo_save_context *save = &vbo_context(ctx)->save; GLfloat *data = save->copied.buffer; GLuint i; /* Emit a glEnd to close off the last vertex list. */ _save_wrap_buffers( ctx ); /* Copy stored stored vertices to start of new list. */ assert(save->max_vert - save->vert_count > save->copied.nr); for (i = 0 ; i < save->copied.nr ; i++) { _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat)); data += save->vertex_size; save->vbptr += save->vertex_size; save->vert_count++; } }
/* Called only when buffers are wrapped as the result of filling the * vertex_store struct. */ static void _save_wrap_filled_vertex( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLfloat *data = tnl->save.copied.buffer; GLuint i; /* Emit a glEnd to close off the last vertex list. */ _save_wrap_buffers( ctx ); /* Copy stored stored vertices to start of new list. */ assert(tnl->save.counter > tnl->save.copied.nr); for (i = 0 ; i < tnl->save.copied.nr ; i++) { _mesa_memcpy( tnl->save.vbptr, data, tnl->save.vertex_size * sizeof(GLfloat)); data += tnl->save.vertex_size; tnl->save.vbptr += tnl->save.vertex_size; tnl->save.counter--; } }
/* Extract a named attribute from a hardware vertex. Will have to * reverse any viewport transformation, swizzling or other conversions * which may have been applied. * * This is mainly required for on-the-fly vertex translations to * swrast format. */ void vf_get_attr( struct vertex_fetch *vf, const void *vertex, GLenum attr, const GLfloat *dflt, GLfloat *dest ) { const struct vf_attr *a = vf->attr; const GLuint attr_count = vf->attr_count; GLuint j; for (j = 0; j < attr_count; j++) { if (a[j].attrib == attr) { a[j].extract( &a[j], dest, (GLubyte *)vertex + a[j].vertoffset ); return; } } /* Else return the value from ctx->Current. */ _mesa_memcpy( dest, dflt, 4*sizeof(GLfloat)); }
/** * Default fallback for \c dd_function_table::CopyBufferSubData(). * Called via glCopyBuffserSubData(). */ static void _mesa_copy_buffer_subdata(GLcontext *ctx, struct gl_buffer_object *src, struct gl_buffer_object *dst, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { GLubyte *srcPtr, *dstPtr; /* buffer should not already be mapped */ assert(!src->Pointer); assert(!dst->Pointer); srcPtr = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_COPY_READ_BUFFER, GL_READ_ONLY, src); dstPtr = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_COPY_WRITE_BUFFER, GL_WRITE_ONLY, dst); if (srcPtr && dstPtr) _mesa_memcpy(dstPtr + writeOffset, srcPtr + readOffset, size); ctx->Driver.UnmapBuffer(ctx, GL_COPY_READ_BUFFER, src); ctx->Driver.UnmapBuffer(ctx, GL_COPY_WRITE_BUFFER, dst); }
/** * Deal with buffer wrapping where provoked by the vertex buffer * filling up, as opposed to upgrade_vertex(). */ void vbo_exec_vtx_wrap( struct vbo_exec_context *exec ) { GLfloat *data = exec->vtx.copied.buffer; GLuint i; /* Run pipeline on current vertices, copy wrapped vertices * to exec->vtx.copied. */ vbo_exec_wrap_buffers( exec ); /* Copy stored stored vertices to start of new list. */ assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr); for (i = 0 ; i < exec->vtx.copied.nr ; i++) { _mesa_memcpy( exec->vtx.buffer_ptr, data, exec->vtx.vertex_size * sizeof(GLfloat)); exec->vtx.buffer_ptr += exec->vtx.vertex_size; data += exec->vtx.vertex_size; exec->vtx.vert_count++; } exec->vtx.copied.nr = 0; }
static void GLAPIENTRY _mesa_GetColorTable( GLenum target, GLenum format, GLenum type, GLvoid *data ) { GET_CURRENT_CONTEXT(ctx); struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx); struct gl_color_table *table = NULL; GLfloat rgba[MAX_COLOR_TABLE_SIZE][4]; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (ctx->NewState) { _mesa_update_state(ctx); } switch (target) { case GL_SHARED_TEXTURE_PALETTE_EXT: table = &ctx->Texture.Palette; break; case GL_COLOR_TABLE: table = &ctx->ColorTable[COLORTABLE_PRECONVOLUTION]; break; case GL_TEXTURE_COLOR_TABLE_SGI: if (!ctx->Extensions.SGI_texture_color_table) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); return; } table = &(texUnit->ColorTable); break; case GL_POST_CONVOLUTION_COLOR_TABLE: table = &ctx->ColorTable[COLORTABLE_POSTCONVOLUTION]; break; case GL_POST_COLOR_MATRIX_COLOR_TABLE: table = &ctx->ColorTable[COLORTABLE_POSTCOLORMATRIX]; break; default: /* try texture targets */ { struct gl_texture_object *texobj = _mesa_select_tex_object(ctx, texUnit, target); if (texobj && !_mesa_is_proxy_texture(target)) { table = &texobj->Palette; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); return; } } } ASSERT(table); if (table->Size <= 0) { return; } switch (table->_BaseFormat) { case GL_ALPHA: { GLuint i; for (i = 0; i < table->Size; i++) { rgba[i][RCOMP] = 0; rgba[i][GCOMP] = 0; rgba[i][BCOMP] = 0; rgba[i][ACOMP] = table->TableF[i]; } } break; case GL_LUMINANCE: { GLuint i; for (i = 0; i < table->Size; i++) { rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = table->TableF[i]; rgba[i][ACOMP] = 1.0F; } } break; case GL_LUMINANCE_ALPHA: { GLuint i; for (i = 0; i < table->Size; i++) { rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = table->TableF[i*2+0]; rgba[i][ACOMP] = table->TableF[i*2+1]; } } break; case GL_INTENSITY: { GLuint i; for (i = 0; i < table->Size; i++) { rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = rgba[i][ACOMP] = table->TableF[i]; } } break; case GL_RGB: { GLuint i; for (i = 0; i < table->Size; i++) { rgba[i][RCOMP] = table->TableF[i*3+0]; rgba[i][GCOMP] = table->TableF[i*3+1]; rgba[i][BCOMP] = table->TableF[i*3+2]; rgba[i][ACOMP] = 1.0F; } } break; case GL_RGBA: _mesa_memcpy(rgba, table->TableF, 4 * table->Size * sizeof(GLfloat)); break; default: _mesa_problem(ctx, "bad table format in glGetColorTable"); return; } data = _mesa_map_validate_pbo_dest(ctx, 1, &ctx->Pack, table->Size, 1, 1, format, type, data, "glGetColorTable"); if (!data) return; _mesa_pack_rgba_span_float(ctx, table->Size, rgba, format, type, data, &ctx->Pack, 0x0); _mesa_unmap_pbo_dest(ctx, &ctx->Pack); }
void _mesa_GetProgramRegisterfvMESA(GLenum target, GLsizei len, const GLubyte *registerName, GLfloat *v) { char reg[1000]; GET_CURRENT_CONTEXT(ctx); /* We _should_ be inside glBegin/glEnd */ #if 0 if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); return; } #endif /* make null-terminated copy of registerName */ len = MIN2((unsigned int) len, sizeof(reg) - 1); _mesa_memcpy(reg, registerName, len); reg[len] = 0; switch (target) { case GL_VERTEX_PROGRAM_NV: if (!ctx->Extensions.ARB_vertex_program && !ctx->Extensions.NV_vertex_program) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramRegisterfvMESA(target)"); return; } if (!ctx->VertexProgram.Enabled) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); return; } /* GL_NV_vertex_program */ if (reg[0] == 'R') { /* Temp register */ GLint i = _mesa_atoi(reg + 1); if (i >= (GLint)ctx->Const.MaxVertexProgramTemps) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } COPY_4V(v, ctx->VertexProgram.Temporaries[i]); } else if (reg[0] == 'v' && reg[1] == '[') { /* Vertex Input attribute */ GLuint i; for (i = 0; i < ctx->Const.MaxVertexProgramAttribs; i++) { const char *name = _mesa_nv_vertex_input_register_name(i); char number[10]; sprintf(number, "%d", i); if (_mesa_strncmp(reg + 2, name, 4) == 0 || _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) { COPY_4V(v, ctx->VertexProgram.Inputs[i]); return; } } _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } else if (reg[0] == 'o' && reg[1] == '[') { /* Vertex output attribute */ } /* GL_ARB_vertex_program */ else if (_mesa_strncmp(reg, "vertex.", 7) == 0) { } else { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } break; case GL_FRAGMENT_PROGRAM_ARB: if (!ctx->Extensions.ARB_fragment_program) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramRegisterfvMESA(target)"); return; } if (!ctx->FragmentProgram.Enabled) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); return; } /* XXX to do */ break; case GL_FRAGMENT_PROGRAM_NV: if (!ctx->Extensions.NV_fragment_program) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramRegisterfvMESA(target)"); return; } if (!ctx->FragmentProgram.Enabled) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); return; } if (reg[0] == 'R') { /* Temp register */ GLint i = _mesa_atoi(reg + 1); if (i >= (GLint)ctx->Const.MaxFragmentProgramTemps) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } COPY_4V(v, ctx->FragmentProgram.Machine.Temporaries[i]); } else if (reg[0] == 'f' && reg[1] == '[') { /* Fragment input attribute */ GLuint i; for (i = 0; i < ctx->Const.MaxFragmentProgramAttribs; i++) { const char *name = _mesa_nv_fragment_input_register_name(i); if (_mesa_strncmp(reg + 2, name, 4) == 0) { COPY_4V(v, ctx->FragmentProgram.Machine.Inputs[i]); return; } } _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } else if (_mesa_strcmp(reg, "o[COLR]") == 0) { /* Fragment output color */ COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLR]); } else if (_mesa_strcmp(reg, "o[COLH]") == 0) { /* Fragment output color */ COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLH]); } else if (_mesa_strcmp(reg, "o[DEPR]") == 0) { /* Fragment output depth */ COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR]); } else { /* try user-defined identifiers */ const GLfloat *value = _mesa_lookup_parameter_value( ctx->FragmentProgram.Current->Parameters, -1, reg); if (value) { COPY_4V(v, value); } else { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramRegisterfvMESA(registerName)"); return; } } break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramRegisterfvMESA(target)"); return; } }