struct mem_block * mmInit(unsigned ofs, unsigned size) { struct mem_block *heap, *block; if (!size) return NULL; heap = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block)); if (!heap) return NULL; block = (struct mem_block *) _mesa_calloc(sizeof(struct mem_block)); if (!block) { _mesa_free(heap); return NULL; } heap->next = block; heap->prev = block; heap->next_free = block; heap->prev_free = block; block->heap = heap; block->next = heap; block->prev = heap; block->next_free = heap; block->prev_free = heap; block->ofs = ofs; block->size = size; block->free = 1; return heap; }
struct gl_program_parameter_list * _mesa_new_parameter_list_sized(unsigned size) { struct gl_program_parameter_list *p = _mesa_new_parameter_list(); if ((p != NULL) && (size != 0)) { p->Size = size; /* alloc arrays */ p->Parameters = (struct gl_program_parameter *) _mesa_calloc(size * sizeof(struct gl_program_parameter)); p->ParameterValues = (GLfloat (*)[4]) _mesa_align_malloc(size * 4 *sizeof(GLfloat), 16); if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) { _mesa_free(p->Parameters); _mesa_align_free(p->ParameterValues); _mesa_free(p); p = NULL; } } return p; }
/** * Allocates a GLvisual structure and initializes it via * _mesa_initialize_visual(). * * \param rgbFlag GL_TRUE for RGB(A) mode, GL_FALSE for Color Index mode. * \param dbFlag double buffering * \param stereoFlag stereo buffer * \param depthBits requested bits per depth buffer value. Any value in [0, 32] * is acceptable but the actual depth type will be GLushort or GLuint as * needed. * \param stencilBits requested minimum bits per stencil buffer value * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number of bits per color component in accum buffer. * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE * \param redBits number of bits per color component in frame buffer for RGB(A) * mode. We always use 8 in core Mesa though. * \param greenBits same as above. * \param blueBits same as above. * \param alphaBits same as above. * \param numSamples not really used. * * \return pointer to new GLvisual or NULL if requested parameters can't be * met. * * \note Need to add params for level and numAuxBuffers (at least) */ GLvisual * _mesa_create_visual( GLboolean rgbFlag, GLboolean dbFlag, GLboolean stereoFlag, GLint redBits, GLint greenBits, GLint blueBits, GLint alphaBits, GLint indexBits, GLint depthBits, GLint stencilBits, GLint accumRedBits, GLint accumGreenBits, GLint accumBlueBits, GLint accumAlphaBits, GLint numSamples ) { GLvisual *vis = (GLvisual *) _mesa_calloc(sizeof(GLvisual)); if (vis) { if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag, redBits, greenBits, blueBits, alphaBits, indexBits, depthBits, stencilBits, accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits, numSamples)) { _mesa_free(vis); return NULL; } } return vis; }
slang_mempool * _slang_new_mempool(GLuint initialSize) { slang_mempool *pool = (slang_mempool *) _mesa_calloc(sizeof(slang_mempool)); if (pool) { pool->Data = (char *) _mesa_calloc(initialSize); /*printf("ALLOC MEMPOOL %d at %p\n", initialSize, pool->Data);*/ if (!pool->Data) { _mesa_free(pool); return NULL; } pool->Size = initialSize; pool->Used = 0; } return pool; }
struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx, struct gl_vertex_program *mesa_vp) { context_t *context = R700_CONTEXT(ctx); struct r700_vertex_program *vp; unsigned int i; vp = _mesa_calloc(sizeof(*vp)); vp->mesa_program = (struct gl_vertex_program *)_mesa_clone_program(ctx, &mesa_vp->Base); if (mesa_vp->IsPositionInvariant) { _mesa_insert_mvp_code(ctx, vp->mesa_program); } for(i=0; i<context->nNumActiveAos; i++) { vp->aos_desc[i].size = context->stream_desc[i].size; vp->aos_desc[i].stride = context->stream_desc[i].stride; vp->aos_desc[i].type = context->stream_desc[i].type; } if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) { vp->r700AsmCode.bR6xx = 1; } //Init_Program Init_r700_AssemblerBase(SPT_VP, &(vp->r700AsmCode), &(vp->r700Shader) ); Map_Vertex_Program(ctx, vp, vp->mesa_program ); if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, vp->mesa_program)) { return NULL; } if(GL_FALSE == AssembleInstr(vp->mesa_program->Base.NumInstructions, &(vp->mesa_program->Base.Instructions[0]), &(vp->r700AsmCode)) ) { return NULL; } if(GL_FALSE == Process_Vertex_Exports(&(vp->r700AsmCode), vp->mesa_program->Base.OutputsWritten) ) { return NULL; } vp->r700Shader.nRegs = (vp->r700AsmCode.number_used_registers == 0) ? 0 : (vp->r700AsmCode.number_used_registers - 1); vp->r700Shader.nParamExports = vp->r700AsmCode.number_of_exports; vp->translated = GL_TRUE; return vp; }
static struct gl_sync_object * intel_new_sync_object(GLcontext *ctx, GLuint id) { struct intel_sync_object *sync; sync = _mesa_calloc(sizeof(struct intel_sync_object)); return &sync->Base; }
GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program, const struct radeon_pair_handler* handler, void *userdata) { struct pair_state s; _mesa_bzero(&s, sizeof(s)); s.Ctx = ctx; s.Program = program; s.Handler = handler; s.UserData = userdata; s.Debug = (RADEON_DEBUG & DEBUG_PIXEL) ? GL_TRUE : GL_FALSE; s.Verbose = GL_FALSE && s.Debug; s.Instructions = (struct pair_state_instruction*)_mesa_calloc( sizeof(struct pair_state_instruction)*s.Program->NumInstructions); s.ValuePool = (struct reg_value*)_mesa_calloc(sizeof(struct reg_value)*s.Program->NumInstructions*4); s.ReaderPool = (struct reg_value_reader*)_mesa_calloc( sizeof(struct reg_value_reader)*s.Program->NumInstructions*12); if (s.Debug) _mesa_printf("Emit paired program\n"); scan_instructions(&s); allocate_input_registers(&s); while(!s.Error && (s.ReadyTEX || s.ReadyRGB || s.ReadyAlpha || s.ReadyFullALU)) { if (s.ReadyTEX) emit_all_tex(&s); while(s.ReadyFullALU || s.ReadyRGB || s.ReadyAlpha) emit_alu(&s); } if (s.Debug) _mesa_printf(" END\n"); _mesa_free(s.Instructions); _mesa_free(s.ValuePool); _mesa_free(s.ReaderPool); return !s.Error; }
void brw_ProgramCacheInit( GLcontext *ctx ) { struct brw_context *brw = brw_context(ctx); brw->tnl_program_cache.size = 17; brw->tnl_program_cache.n_items = 0; brw->tnl_program_cache.items = (struct brw_tnl_cache_item **) _mesa_calloc(brw->tnl_program_cache.size * sizeof(struct brw_tnl_cache_item)); }
void _tnl_ProgramCacheInit( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); tnl->vp_cache = (struct tnl_cache *) MALLOC(sizeof(*tnl->vp_cache)); tnl->vp_cache->size = 17; tnl->vp_cache->n_items = 0; tnl->vp_cache->items = (struct tnl_cache_item**) _mesa_calloc(tnl->vp_cache->size * sizeof(*tnl->vp_cache->items)); }
/* Create the device specific context. */ static GLboolean fbCreateContext( const __GLcontextModes *glVisual, __DRIcontextPrivate *driContextPriv, void *sharedContextPrivate) { fbContextPtr fbmesa; GLcontext *ctx, *shareCtx; struct dd_function_table functions; assert(glVisual); assert(driContextPriv); /* Allocate the Fb context */ fbmesa = (fbContextPtr) _mesa_calloc( sizeof(*fbmesa) ); if ( !fbmesa ) return GL_FALSE; /* Init default driver functions then plug in our FBdev-specific functions */ _mesa_init_driver_functions(&functions); init_core_functions(&functions); /* Allocate the Mesa context */ if (sharedContextPrivate) shareCtx = ((fbContextPtr) sharedContextPrivate)->glCtx; else shareCtx = NULL; ctx = fbmesa->glCtx = _mesa_create_context(glVisual, shareCtx, &functions, (void *) fbmesa); if (!fbmesa->glCtx) { _mesa_free(fbmesa); return GL_FALSE; } driContextPriv->driverPrivate = fbmesa; /* Create module contexts */ _swrast_CreateContext( ctx ); _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _swsetup_Wakeup( ctx ); /* use default TCL pipeline */ { TNLcontext *tnl = TNL_CONTEXT(ctx); tnl->Driver.RunPipeline = _tnl_run_pipeline; } _mesa_enable_sw_extensions(ctx); return GL_TRUE; }
/** * Alloc 'bytes' from shader mempool. */ void * _slang_alloc(GLuint bytes) { #if USE_MALLOC_FREE return _mesa_calloc(bytes); #else slang_mempool *pool; GET_CURRENT_CONTEXT(ctx); pool = (slang_mempool *) ctx->Shader.MemPool; if (bytes == 0) bytes = 1; while (pool) { if (pool->Used + bytes <= pool->Size) { /* found room */ void *addr = (void *) (pool->Data + pool->Used); #ifdef DEBUG check_zero((char*) addr, bytes); #endif pool->Used += ROUND_UP(bytes); pool->Largest = MAX2(pool->Largest, bytes); pool->Count++; /*printf("alloc %u Used %u\n", bytes, pool->Used);*/ return addr; } else if (pool->Next) { /* try next block */ pool = pool->Next; } else { /* alloc new pool */ const GLuint sz = MAX2(bytes, pool->Size); pool->Next = _slang_new_mempool(sz); if (!pool->Next) { /* we're _really_ out of memory */ return NULL; } else { pool = pool->Next; pool->Largest = bytes; pool->Count++; pool->Used = ROUND_UP(bytes); #ifdef DEBUG check_zero((char*) pool->Data, bytes); #endif return (void *) pool->Data; } } } return NULL; #endif }
static GLboolean CreateContext(void) { struct dd_function_table ddFuncs; GLvisual *vis; GLframebuffer *buf; GLcontext *ctx; CompilerContext *cc; vis = _mesa_create_visual(GL_TRUE, GL_FALSE, GL_FALSE, /* RGB */ 8, 8, 8, 8, /* color */ 0, 0, 0, /* z, stencil */ 0, 0, 0, 0, 1); /* accum */ buf = _mesa_create_framebuffer(vis); cc = _mesa_calloc(sizeof(*cc)); if (!vis || !buf || !cc) { if (vis) _mesa_destroy_visual(vis); if (buf) _mesa_destroy_framebuffer(buf); return GL_FALSE; } _mesa_init_driver_functions(&ddFuncs); ddFuncs.GetString = NULL;/*get_string;*/ ddFuncs.UpdateState = UpdateState; ddFuncs.GetBufferSize = NULL; ctx = &cc->MesaContext; _mesa_initialize_context(ctx, vis, NULL, &ddFuncs, cc); _mesa_enable_sw_extensions(ctx); if (!_swrast_CreateContext( ctx ) || !_vbo_CreateContext( ctx ) || !_tnl_CreateContext( ctx ) || !_swsetup_CreateContext( ctx )) { _mesa_destroy_visual(vis); _mesa_free_context_data(ctx); _mesa_free(cc); return GL_FALSE; } TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; _swsetup_Wakeup( ctx ); /* Override the context's default pragma settings */ ctx->Shader.DefaultPragmas = Options.Pragmas; _mesa_make_current(ctx, buf, buf); return GL_TRUE; }
static struct gl_query_object * radeonNewQueryObject(GLcontext *ctx, GLuint id) { struct radeon_query_object *query; query = _mesa_calloc(sizeof(struct radeon_query_object)); query->Base.Id = id; query->Base.Result = 0; query->Base.Active = GL_FALSE; query->Base.Ready = GL_TRUE; radeon_print(RADEON_STATE, RADEON_VERBOSE,"%s: query id %d\n", __FUNCTION__, query->Base.Id); return &query->Base; }
/** * Generate a list of new program identifiers. * \note Not compiled into display lists. * \note Called by both glGenProgramsNV and glGenProgramsARB. */ void GLAPIENTRY _mesa_GenPrograms(GLsizei n, GLuint *ids) { GLuint first; GLuint i; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (n < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGenPrograms"); return; } if (!ids) return; first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, n); for (i = 0; i < (GLuint) n; i++) { const int bytes = MAX2(sizeof(struct vertex_program), sizeof(struct fragment_program)); struct program *prog = (struct program *) _mesa_calloc(bytes); if (!prog) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenPrograms"); return; } prog->RefCount = 1; prog->Id = first + i; _mesa_HashInsert(ctx->Shared->Programs, first + i, prog); } /* Return the program names */ for (i = 0; i < (GLuint) n; i++) { ids[i] = first + i; } }
/** * Allocate and initialize a GLcontext structure. * Note that the driver needs to pass in its dd_function_table here since * we need to at least call driverFunctions->NewTextureObject to initialize * the rendering context. * * \param visual a GLvisual pointer (we copy the struct contents) * \param share_list another context to share display lists with or NULL * \param driverFunctions points to the dd_function_table into which the * driver has plugged in all its special functions. * \param driverContext points to the device driver's private context state * * \return pointer to a new __GLcontextRec or NULL if error. */ GLcontext * _mesa_create_context(const GLvisual *visual, GLcontext *share_list, const struct dd_function_table *driverFunctions, void *driverContext) { GLcontext *ctx; ASSERT(visual); /*ASSERT(driverContext);*/ ctx = (GLcontext *) _mesa_calloc(sizeof(GLcontext)); if (!ctx) return NULL; if (_mesa_initialize_context(ctx, visual, share_list, driverFunctions, driverContext)) { return ctx; } else { _mesa_free(ctx); return NULL; } }
MesaSoftwareRenderer::MesaSoftwareRenderer(BGLView* view, ulong options, BGLDispatcher* dispatcher) : BGLRenderer(view, options, dispatcher), fBitmap(NULL), fDirectModeEnabled(false), fInfo(NULL), fInfoLocker("info locker"), fContext(NULL), fVisual(NULL), fFrameBuffer(NULL), fFrontRenderBuffer(NULL), fBackRenderBuffer(NULL), fColorSpace(B_NO_COLOR_SPACE) { CALLED(); fClearColor[BE_RCOMP] = 0; fClearColor[BE_GCOMP] = 0; fClearColor[BE_BCOMP] = 0; fClearColor[BE_ACOMP] = 0; fClearIndex = 0; fColorSpace = BScreen(GLView()->Window()).ColorSpace(); // We force single buffering for the time being //options &= !BGL_DOUBLE; const GLboolean rgbFlag = ((options & BGL_INDEX) == 0); const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA); const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE); const GLboolean stereoFlag = false; const GLint depth = (options & BGL_DEPTH) ? 16 : 0; const GLint stencil = (options & BGL_STENCIL) ? 8 : 0; const GLint accum = (options & BGL_ACCUM) ? 16 : 0; const GLint index = (options & BGL_INDEX) ? 32 : 0; const GLint red = rgbFlag ? 8 : 0; const GLint green = rgbFlag ? 8 : 0; const GLint blue = rgbFlag ? 8 : 0; const GLint alpha = alphaFlag ? 8 : 0; fOptions = options; // | BGL_INDIRECT; struct dd_function_table functions; fVisual = _mesa_create_visual(rgbFlag, dblFlag, stereoFlag, red, green, blue, alpha, index, depth, stencil, accum, accum, accum, alpha ? accum : 0, 1); // Initialize device driver function table _mesa_init_driver_functions(&functions); functions.GetString = _GetString; functions.UpdateState = _UpdateState; functions.GetBufferSize = NULL; functions.Error = _Error; functions.Viewport = _Viewport; functions.Flush = _Flush; // create core context fContext = _mesa_create_context(fVisual, NULL, &functions, this); if (!fContext) { _mesa_destroy_visual(fVisual); return; } /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext(fContext); _vbo_CreateContext(fContext); _tnl_CreateContext(fContext); _swsetup_CreateContext(fContext); _swsetup_Wakeup(fContext); // Use default TCL pipeline TNL_CONTEXT(fContext)->Driver.RunPipeline = _tnl_run_pipeline; _mesa_enable_sw_extensions(fContext); _mesa_enable_1_3_extensions(fContext); _mesa_enable_1_4_extensions(fContext); _mesa_enable_1_5_extensions(fContext); _mesa_enable_2_0_extensions(fContext); _mesa_enable_2_1_extensions(fContext); // create core framebuffer fFrameBuffer = (struct msr_framebuffer*)_mesa_calloc( sizeof(*fFrameBuffer)); _mesa_initialize_framebuffer(&fFrameBuffer->Base, fVisual); fFrontRenderBuffer = (struct msr_renderbuffer*)_mesa_calloc( sizeof(*fFrontRenderBuffer)); _mesa_init_renderbuffer(&fFrontRenderBuffer->Base, 0); fFrontRenderBuffer->Base.AllocStorage = _FrontRenderbufferStorage; fFrontRenderBuffer->Base.Data = NULL; fFrontRenderBuffer->Base.InternalFormat = GL_RGBA; fFrontRenderBuffer->Base._BaseFormat = GL_RGBA; fFrontRenderBuffer->Base.DataType = GL_UNSIGNED_BYTE; fFrontRenderBuffer->Base.RedBits = 8 * sizeof(GLubyte); fFrontRenderBuffer->Base.GreenBits = 8 * sizeof(GLubyte); fFrontRenderBuffer->Base.BlueBits = 8 * sizeof(GLubyte); fFrontRenderBuffer->Base.AlphaBits = 8 * sizeof(GLubyte); _SetSpanFuncs(fFrontRenderBuffer, fColorSpace); _mesa_add_renderbuffer(&fFrameBuffer->Base, BUFFER_FRONT_LEFT, &fFrontRenderBuffer->Base); if (dblFlag) { fBackRenderBuffer = (struct msr_renderbuffer*)_mesa_calloc( sizeof(*fBackRenderBuffer)); _mesa_init_renderbuffer(&fBackRenderBuffer->Base, 0); fBackRenderBuffer->Base.AllocStorage = _BackRenderbufferStorage; fBackRenderBuffer->Base.Data = NULL; fBackRenderBuffer->Base.Delete = _DeleteBackBuffer; fBackRenderBuffer->Base.InternalFormat = GL_RGBA; fBackRenderBuffer->Base._BaseFormat = GL_RGBA; fBackRenderBuffer->Base.DataType = GL_UNSIGNED_BYTE; fBackRenderBuffer->Base.RedBits = 8 * sizeof(GLubyte); fBackRenderBuffer->Base.GreenBits = 8 * sizeof(GLubyte); fBackRenderBuffer->Base.BlueBits = 8 * sizeof(GLubyte); fBackRenderBuffer->Base.AlphaBits = 8 * sizeof(GLubyte); _SetSpanFuncs(fBackRenderBuffer, fColorSpace); _mesa_add_renderbuffer(&fFrameBuffer->Base, BUFFER_BACK_LEFT, &fBackRenderBuffer->Base); } _mesa_add_soft_renderbuffers(&fFrameBuffer->Base, GL_FALSE, fVisual->haveDepthBuffer, fVisual->haveStencilBuffer, fVisual->haveAccumBuffer, alphaFlag, GL_FALSE); BRect bounds = view->Bounds(); fWidth = fNewWidth = (GLint)bounds.Width(); fHeight = fNewHeight = (GLint)bounds.Height(); // some stupid applications (Quake2) don't even think about calling LockGL() // before using glGetString and its glGet*() friends... // so make sure there is at least a valid context. if (!_mesa_get_current_context()) { LockGL(); // not needed, we don't have a looper yet: UnlockLooper(); } }
struct program_parameter_list * _mesa_new_parameter_list(void) { return (struct program_parameter_list *) _mesa_calloc(sizeof(struct program_parameter_list)); }
/** * Allocate a new driRenderbuffer object. * Individual drivers are free to implement different versions of * this function. * \param format Either GL_RGBA, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, * GL_DEPTH_COMPONENT32, or GL_STENCIL_INDEX8_EXT (for now). * \param cpp chars or bytes per pixel * \param offset start of buffer with respect to framebuffer address * \param pitch pixels per row */ driRenderbuffer * driNewRenderbuffer(GLenum format, GLint cpp, GLint offset, GLint pitch) { driRenderbuffer *drb; assert(format == GL_RGBA || format == GL_DEPTH_COMPONENT16 || format == GL_DEPTH_COMPONENT24 || format == GL_DEPTH_COMPONENT32 || format == GL_STENCIL_INDEX8_EXT); assert(cpp > 0); assert(pitch > 0); drb = _mesa_calloc(sizeof(driRenderbuffer)); if (drb) { const GLuint name = 0; _mesa_init_renderbuffer(&drb->Base, name); /* Make sure we're using a null-valued GetPointer routine */ assert(drb->Base.GetPointer(NULL, &drb->Base, 0, 0) == NULL); drb->Base.InternalFormat = format; if (format == GL_RGBA) { /* Color */ drb->Base._BaseFormat = GL_RGBA; drb->Base.DataType = GL_UNSIGNED_BYTE; } else if (format == GL_DEPTH_COMPONENT16) { /* Depth */ drb->Base._BaseFormat = GL_DEPTH_COMPONENT; /* we always Get/Put 32-bit Z values */ drb->Base.DataType = GL_UNSIGNED_INT; } else if (format == GL_DEPTH_COMPONENT24) { /* Depth */ drb->Base._BaseFormat = GL_DEPTH_COMPONENT; /* we always Get/Put 32-bit Z values */ drb->Base.DataType = GL_UNSIGNED_INT; } else { /* Stencil */ ASSERT(format == GL_STENCIL_INDEX8); drb->Base._BaseFormat = GL_STENCIL_INDEX; drb->Base.DataType = GL_UNSIGNED_BYTE; } /* XXX if we were allocating a user-created renderbuffer, we'd have * to fill in the ComponentSizes[] array too. */ drb->Base.AllocStorage = driRenderbufferStorage; /* using default Delete function */ /* DRI renderbuffer-specific fields: */ drb->offset = offset; drb->pitch = pitch; drb->cpp = cpp; } return drb; }
/** * Remove dead instructions from the given program. * This is very primitive for now. Basically look for temp registers * that are written to but never read. Remove any instructions that * write to such registers. Be careful with condition code setters. */ static void _mesa_remove_dead_code(struct gl_program *prog) { GLboolean tempWritten[MAX_PROGRAM_TEMPS], tempRead[MAX_PROGRAM_TEMPS]; GLboolean *removeInst; /* per-instruction removal flag */ GLuint i, rem; memset(tempWritten, 0, sizeof(tempWritten)); memset(tempRead, 0, sizeof(tempRead)); if (dbg) { _mesa_printf("Optimize: Begin dead code removal\n"); /*_mesa_print_program(prog);*/ } removeInst = (GLboolean *) _mesa_calloc(prog->NumInstructions * sizeof(GLboolean)); /* Determine which temps are read and written */ for (i = 0; i < prog->NumInstructions; i++) { const struct prog_instruction *inst = prog->Instructions + i; const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); GLuint j; /* check src regs */ for (j = 0; j < numSrc; j++) { if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) { const GLuint index = inst->SrcReg[j].Index; ASSERT(index < MAX_PROGRAM_TEMPS); if (inst->SrcReg[j].RelAddr) { if (dbg) _mesa_printf("abort remove dead code (indirect temp)\n"); return; } tempRead[index] = GL_TRUE; } } /* check dst reg */ if (inst->DstReg.File == PROGRAM_TEMPORARY) { const GLuint index = inst->DstReg.Index; ASSERT(index < MAX_PROGRAM_TEMPS); if (inst->DstReg.RelAddr) { if (dbg) _mesa_printf("abort remove dead code (indirect temp)\n"); return; } tempWritten[index] = GL_TRUE; if (inst->CondUpdate) { /* If we're writing to this register and setting condition * codes we cannot remove the instruction. Prevent removal * by setting the 'read' flag. */ tempRead[index] = GL_TRUE; } } } if (dbg) { for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { if (tempWritten[i] && !tempRead[i]) _mesa_printf("Remove writes to tmp %u\n", i); } } /* find instructions that write to dead registers, flag for removal */ for (i = 0; i < prog->NumInstructions; i++) { const struct prog_instruction *inst = prog->Instructions + i; if (inst->DstReg.File == PROGRAM_TEMPORARY) { GLint index = inst->DstReg.Index; removeInst[i] = (tempWritten[index] && !tempRead[index]); if (dbg && removeInst[i]) { _mesa_printf("Remove inst %u: ", i); _mesa_print_instruction(inst); } } } /* now remove the instructions which aren't needed */ rem = remove_instructions(prog, removeInst); _mesa_free(removeInst); if (dbg) { _mesa_printf("Optimize: End dead code removal. %u instructions removed\n", rem); /*_mesa_print_program(prog);*/ } }
/** * Try to remove extraneous MOV instructions from the given program. */ static void _mesa_remove_extra_moves(struct gl_program *prog) { GLboolean *removeInst; /* per-instruction removal flag */ GLuint i, rem, loopNesting = 0, subroutineNesting = 0; if (dbg) { _mesa_printf("Optimize: Begin remove extra moves\n"); _mesa_print_program(prog); } removeInst = (GLboolean *) _mesa_calloc(prog->NumInstructions * sizeof(GLboolean)); /* * Look for sequences such as this: * FOO tmpX, arg0, arg1; * MOV tmpY, tmpX; * and convert into: * FOO tmpY, arg0, arg1; */ for (i = 0; i < prog->NumInstructions; i++) { const struct prog_instruction *inst = prog->Instructions + i; switch (inst->Opcode) { case OPCODE_BGNLOOP: loopNesting++; break; case OPCODE_ENDLOOP: loopNesting--; break; case OPCODE_BGNSUB: subroutineNesting++; break; case OPCODE_ENDSUB: subroutineNesting--; break; case OPCODE_MOV: if (i > 0 && loopNesting == 0 && subroutineNesting == 0 && inst->SrcReg[0].File == PROGRAM_TEMPORARY && inst->SrcReg[0].Swizzle == SWIZZLE_XYZW) { /* see if this MOV can be removed */ const GLuint tempIndex = inst->SrcReg[0].Index; struct prog_instruction *prevInst; GLuint prevI; /* get pointer to previous instruction */ prevI = i - 1; while (removeInst[prevI] && prevI > 0) prevI--; prevInst = prog->Instructions + prevI; if (prevInst->DstReg.File == PROGRAM_TEMPORARY && prevInst->DstReg.Index == tempIndex && prevInst->DstReg.WriteMask == WRITEMASK_XYZW) { enum temp_use next_use = find_next_temp_use(prog, i + 1, tempIndex); if (next_use == WRITE || next_use == END) { /* OK, we can safely remove this MOV instruction. * Transform: * prevI: FOO tempIndex, x, y; * i: MOV z, tempIndex; * Into: * prevI: FOO z, x, y; */ /* patch up prev inst */ prevInst->DstReg.File = inst->DstReg.File; prevInst->DstReg.Index = inst->DstReg.Index; /* flag this instruction for removal */ removeInst[i] = GL_TRUE; if (dbg) { _mesa_printf("Remove MOV at %u\n", i); _mesa_printf("new prev inst %u: ", prevI); _mesa_print_instruction(prevInst); } } } } break; default: ; /* nothing */ } } /* now remove the instructions which aren't needed */ rem = remove_instructions(prog, removeInst); if (dbg) { _mesa_printf("Optimize: End remove extra moves. %u instructions removed\n", rem); /*_mesa_print_program(prog);*/ } }
static struct mem_block * SliceBlock(struct mem_block *p, unsigned startofs, unsigned size, unsigned reserved, unsigned alignment) { struct mem_block *newblock; /* break left [p, newblock, p->next], then p = newblock */ if (startofs > p->ofs) { newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block)); if (!newblock) return NULL; newblock->ofs = startofs; newblock->size = p->size - (startofs - p->ofs); newblock->free = 1; newblock->heap = p->heap; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; p->next = newblock; newblock->next_free = p->next_free; newblock->prev_free = p; p->next_free->prev_free = newblock; p->next_free = newblock; p->size -= newblock->size; p = newblock; } /* break right, also [p, newblock, p->next] */ if (size < p->size) { newblock = (struct mem_block*) _mesa_calloc(sizeof(struct mem_block)); if (!newblock) return NULL; newblock->ofs = startofs + size; newblock->size = p->size - size; newblock->free = 1; newblock->heap = p->heap; newblock->next = p->next; newblock->prev = p; p->next->prev = newblock; p->next = newblock; newblock->next_free = p->next_free; newblock->prev_free = p; p->next_free->prev_free = newblock; p->next_free = newblock; p->size = size; } /* p = middle block */ p->free = 0; /* Remove p from the free list: */ p->next_free->prev_free = p->prev_free; p->prev_free->next_free = p->next_free; p->next_free = 0; p->prev_free = 0; p->reserved = reserved; return p; }
/** * Allocate a new driRenderbuffer object. * Individual drivers are free to implement different versions of * this function. * * At this time, this function can only be used for window-system * renderbuffers, not user-created RBOs. * * \param format Either GL_RGBA, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, * GL_DEPTH_COMPONENT32, or GL_STENCIL_INDEX8_EXT (for now). * \param addr address in main memory of the buffer. Probably a memory * mapped region. * \param cpp chars or bytes per pixel * \param offset start of renderbuffer with respect to start of framebuffer * \param pitch pixels per row */ driRenderbuffer * driNewRenderbuffer(gl_format format, GLvoid *addr, GLint cpp, GLint offset, GLint pitch, __DRIdrawablePrivate *dPriv) { driRenderbuffer *drb; assert(format == GL_RGBA || format == GL_RGB5 || format == GL_RGBA8 || format == GL_DEPTH_COMPONENT16 || format == GL_DEPTH_COMPONENT24 || format == GL_DEPTH_COMPONENT32 || format == GL_STENCIL_INDEX8_EXT); assert(cpp > 0); assert(pitch > 0); drb = _mesa_calloc(sizeof(driRenderbuffer)); if (drb) { const GLuint name = 0; _mesa_init_renderbuffer(&drb->Base, name); /* Make sure we're using a null-valued GetPointer routine */ assert(drb->Base.GetPointer(NULL, &drb->Base, 0, 0) == NULL); switch (format) { case MESA_FORMAT_ARGB8888: if (cpp == 2) { /* override format */ format = MESA_FORMAT_RGB565; } drb->Base.DataType = GL_UNSIGNED_BYTE; break; case MESA_FORMAT_Z16: /* Depth */ /* we always Get/Put 32-bit Z values */ drb->Base.DataType = GL_UNSIGNED_INT; assert(cpp == 2); break; case MESA_FORMAT_Z32: /* Depth */ /* we always Get/Put 32-bit Z values */ drb->Base.DataType = GL_UNSIGNED_INT; assert(cpp == 4); break; case MESA_FORMAT_Z24_S8: drb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; assert(cpp == 4); break; case MESA_FORMAT_S8_Z24: drb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; assert(cpp == 4); break; case MESA_FORMAT_S8: /* Stencil */ drb->Base.DataType = GL_UNSIGNED_BYTE; break; default: _mesa_problem(NULL, "Bad format 0x%x in driNewRenderbuffer", format); return NULL; } drb->Base.Format = format; drb->Base.InternalFormat = drb->Base._BaseFormat = _mesa_get_format_base_format(format); drb->Base.AllocStorage = driRenderbufferStorage; drb->Base.Delete = driDeleteRenderbuffer; drb->Base.Data = addr; /* DRI renderbuffer-specific fields: */ drb->dPriv = dPriv; drb->offset = offset; drb->pitch = pitch; drb->cpp = cpp; /* may be changed if page flipping is active: */ drb->flippedOffset = offset; drb->flippedPitch = pitch; drb->flippedData = addr; } return drb; }
static struct r300_vertex_program *build_program(GLcontext *ctx, struct r300_vertex_program_key *wanted_key, const struct gl_vertex_program *mesa_vp) { struct r300_vertex_program *vp; struct r300_vertex_program_compiler compiler; vp = _mesa_calloc(sizeof(*vp)); vp->Base = (struct gl_vertex_program *) _mesa_clone_program(ctx, &mesa_vp->Base); _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key)); rc_init(&compiler.Base); compiler.Base.Debug = (RADEON_DEBUG & RADEON_VERTS) ? GL_TRUE : GL_FALSE; compiler.code = &vp->code; compiler.RequiredOutputs = compute_required_outputs(vp->Base, vp->key.FpReads); compiler.SetHwInputOutput = &t_inputs_outputs; if (compiler.Base.Debug) { fprintf(stderr, "Initial vertex program:\n"); _mesa_print_program(&vp->Base->Base); fflush(stderr); } if (mesa_vp->IsPositionInvariant) { _mesa_insert_mvp_code(ctx, vp->Base); } radeon_mesa_to_rc_program(&compiler.Base, &vp->Base->Base); if (mesa_vp->IsNVProgram) initialize_NV_registers(&compiler.Base); rc_move_output(&compiler.Base, VERT_RESULT_PSIZ, VERT_RESULT_PSIZ, WRITEMASK_X); if (vp->key.WPosAttr != FRAG_ATTRIB_MAX) { rc_copy_output(&compiler.Base, VERT_RESULT_HPOS, vp->key.WPosAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0); } if (vp->key.FogAttr != FRAG_ATTRIB_MAX) { rc_move_output(&compiler.Base, VERT_RESULT_FOGC, vp->key.FogAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0, WRITEMASK_X); } r3xx_compile_vertex_program(&compiler); if (vp->code.constants.Count > ctx->Const.VertexProgram.MaxParameters) { rc_error(&compiler.Base, "Program exceeds constant buffer size limit\n"); } vp->error = compiler.Base.Error; vp->Base->Base.InputsRead = vp->code.InputsRead; vp->Base->Base.OutputsWritten = vp->code.OutputsWritten; rc_destroy(&compiler.Base); return vp; }