/** * Find a good ALU instruction or pair of ALU instruction and emit it. * * Prefer emitting full ALU instructions, so that when we reach a point * where no full ALU instruction can be emitted, we have more candidates * for RGB/Alpha pairing. */ static void emit_alu(struct pair_state *s) { struct radeon_pair_instruction pair; if (s->ReadyFullALU || !(s->ReadyRGB && s->ReadyAlpha)) { int ip; if (s->ReadyFullALU) { ip = s->ReadyFullALU - s->Instructions; s->ReadyFullALU = s->ReadyFullALU->NextReady; } else if (s->ReadyRGB) { ip = s->ReadyRGB - s->Instructions; s->ReadyRGB = s->ReadyRGB->NextReady; } else { ip = s->ReadyAlpha - s->Instructions; s->ReadyAlpha = s->ReadyAlpha->NextReady; } _mesa_bzero(&pair, sizeof(pair)); fill_instruction_into_pair(s, &pair, ip); fill_dest_into_pair(s, &pair, ip); commit_instruction(s, ip); } else { struct pair_state_instruction **prgb; struct pair_state_instruction **palpha; /* Some pairings might fail because they require too * many source slots; try all possible pairings if necessary */ for(prgb = &s->ReadyRGB; *prgb; prgb = &(*prgb)->NextReady) { for(palpha = &s->ReadyAlpha; *palpha; palpha = &(*palpha)->NextReady) { int rgbip = *prgb - s->Instructions; int alphaip = *palpha - s->Instructions; _mesa_bzero(&pair, sizeof(pair)); fill_instruction_into_pair(s, &pair, rgbip); if (!fill_instruction_into_pair(s, &pair, alphaip)) continue; *prgb = (*prgb)->NextReady; *palpha = (*palpha)->NextReady; fill_dest_into_pair(s, &pair, rgbip); fill_dest_into_pair(s, &pair, alphaip); commit_instruction(s, rgbip); commit_instruction(s, alphaip); goto success; } } /* No success in pairing; just take the first RGB instruction */ int ip = s->ReadyRGB - s->Instructions; s->ReadyRGB = s->ReadyRGB->NextReady; _mesa_bzero(&pair, sizeof(pair)); fill_instruction_into_pair(s, &pair, ip); fill_dest_into_pair(s, &pair, ip); commit_instruction(s, ip); success: ; } if (s->Debug) radeonPrintPairInstruction(&pair); s->Error = s->Error || !s->Handler->EmitPaired(s->UserData, &pair); }
GLboolean r500FragmentProgramEmit(struct r500_fragment_program_compiler *compiler) { struct r500_fragment_program_code *code = compiler->code; _mesa_bzero(code, sizeof(*code)); code->max_temp_idx = 1; code->inst_offset = 0; code->inst_end = -1; if (!radeonPairProgram(compiler->r300->radeon.glCtx, compiler->program, &pair_handler, compiler)) return GL_FALSE; if ((code->inst[code->inst_end].inst0 & R500_INST_TYPE_MASK) != R500_INST_TYPE_OUT) { /* This may happen when dead-code elimination is disabled or * when most of the fragment program logic is leading to a KIL */ if (code->inst_end >= 511) { error("Introducing fake OUT: Too many instructions"); return GL_FALSE; } int ip = ++code->inst_end; code->inst[ip].inst0 = R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT; } return GL_TRUE; }
/** * Initialize a gl_framebuffer object. Typically used to initialize * window system-created framebuffers, not user-created framebuffers. * \sa _mesa_create_framebuffer */ void _mesa_initialize_framebuffer(struct gl_framebuffer *fb, const GLvisual *visual) { assert(fb); assert(visual); _mesa_bzero(fb, sizeof(struct gl_framebuffer)); _glthread_INIT_MUTEX(fb->Mutex); fb->RefCount = 1; /* save the visual */ fb->Visual = *visual; /* Init glRead/DrawBuffer state */ if (visual->doubleBufferMode) { fb->ColorDrawBuffer[0] = GL_BACK; fb->_ColorDrawBufferMask[0] = BUFFER_BIT_BACK_LEFT; fb->ColorReadBuffer = GL_BACK; fb->_ColorReadBufferIndex = BUFFER_BACK_LEFT; } else { fb->ColorDrawBuffer[0] = GL_FRONT; fb->_ColorDrawBufferMask[0] = BUFFER_BIT_FRONT_LEFT; fb->ColorReadBuffer = GL_FRONT; fb->_ColorReadBufferIndex = BUFFER_FRONT_LEFT; } fb->Delete = _mesa_destroy_framebuffer; fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT; compute_depth_max(fb); }
/** * Initialize a buffer object to default values. */ void _mesa_initialize_buffer_object( struct gl_buffer_object *obj, GLuint name, GLenum target ) { (void) target; _mesa_bzero(obj, sizeof(struct gl_buffer_object)); obj->RefCount = 1; obj->Name = name; obj->Usage = GL_STATIC_DRAW_ARB; obj->AccessFlags = DEFAULT_ACCESS; }
void radeonNqssaDce(GLcontext *ctx, struct gl_program *p, struct radeon_nqssadce_descr* descr) { struct nqssadce_state s; _mesa_bzero(&s, sizeof(s)); s.Ctx = ctx; s.Program = p; s.Descr = descr; s.Descr->Init(&s); s.IP = p->NumInstructions; while(s.IP > 0) { s.IP--; process_instruction(&s); } }
/** * Initialize a new texture object to default values. * \param obj the texture object * \param name the texture name * \param target the texture target */ void _mesa_initialize_texture_object( struct gl_texture_object *obj, GLuint name, GLenum target ) { ASSERT(target == 0 || target == GL_TEXTURE_1D || target == GL_TEXTURE_2D || target == GL_TEXTURE_3D || target == GL_TEXTURE_CUBE_MAP_ARB || target == GL_TEXTURE_RECTANGLE_NV); _mesa_bzero(obj, sizeof(*obj)); /* init the non-zero fields */ _glthread_INIT_MUTEX(obj->Mutex); obj->RefCount = 1; obj->Name = name; obj->Target = target; obj->Priority = 1.0F; if (target == GL_TEXTURE_RECTANGLE_NV) { obj->WrapS = GL_CLAMP_TO_EDGE; obj->WrapT = GL_CLAMP_TO_EDGE; obj->WrapR = GL_CLAMP_TO_EDGE; obj->MinFilter = GL_LINEAR; } else { obj->WrapS = GL_REPEAT; obj->WrapT = GL_REPEAT; obj->WrapR = GL_REPEAT; obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR; } obj->MagFilter = GL_LINEAR; obj->MinLod = -1000.0; obj->MaxLod = 1000.0; obj->LodBias = 0.0; obj->BaseLevel = 0; obj->MaxLevel = 1000; obj->MaxAnisotropy = 1.0; obj->CompareFlag = GL_FALSE; /* SGIX_shadow */ obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX; /* SGIX_shadow */ obj->CompareMode = GL_NONE; /* ARB_shadow */ obj->CompareFunc = GL_LEQUAL; /* ARB_shadow */ obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */ obj->ShadowAmbient = 0.0F; /* ARB/SGIX_shadow_ambient */ _mesa_init_colortable(&obj->Palette); }
/** * Collect all external state that is relevant for compiling the given * fragment program. */ static void build_state( r300ContextPtr r300, struct r300_fragment_program *fp, struct r300_fragment_program_external_state *state) { int unit; _mesa_bzero(state, sizeof(*state)); for(unit = 0; unit < 16; ++unit) { if (fp->mesa_program.Base.ShadowSamplers & (1 << unit)) { struct gl_texture_object* tex = r300->radeon.glCtx->Texture.Unit[unit]._Current; state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode); state->unit[unit].texture_compare_func = build_func(tex->CompareFunc); } } }
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; }
/** * Initialize the virtual fragment program machine state prior to running * fragment program on a fragment. This involves initializing the input * registers, condition codes, etc. * \param machine the virtual machine state to init * \param program the fragment program we're about to run * \param span the span of pixels we'll operate on * \param col which element (column) of the span we'll operate on */ static void init_machine(GLcontext *ctx, struct gl_program_machine *machine, const struct gl_fragment_program *program, const SWspan *span, GLuint col) { if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { /* Clear temporary registers (undefined for ARB_f_p) */ _mesa_bzero(machine->Temporaries, MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); } /* Setup pointer to input attributes */ machine->Attribs = span->array->attribs; machine->DerivX = (GLfloat (*)[4]) span->attrStepX; machine->DerivY = (GLfloat (*)[4]) span->attrStepY; machine->NumDeriv = FRAG_ATTRIB_MAX; machine->Samplers = program->Base.SamplerUnits; /* if running a GLSL program (not ARB_fragment_program) */ if (ctx->Shader.CurrentProgram) { /* Store front/back facing value in register FOGC.Y */ machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = 1.0 - span->facing; /* Note FOGC.ZW is gl_PointCoord if drawing a sprite */ } machine->CurElement = col; /* init condition codes */ machine->CondCodes[0] = COND_EQ; machine->CondCodes[1] = COND_EQ; machine->CondCodes[2] = COND_EQ; machine->CondCodes[3] = COND_EQ; /* init call stack */ machine->StackDepth = 0; machine->FetchTexelLod = fetch_texel_lod; machine->FetchTexelDeriv = fetch_texel_deriv; }
/** * Initialize a new vertex/fragment program object. */ static struct gl_program * _mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog, GLenum target, GLuint id) { (void) ctx; if (prog) { GLuint i; _mesa_bzero(prog, sizeof(*prog)); prog->Id = id; prog->Target = target; prog->Resident = GL_TRUE; prog->RefCount = 1; prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB; /* default mapping from samplers to texture units */ for (i = 0; i < MAX_SAMPLERS; i++) prog->SamplerUnits[i] = i; } return prog; }
/** * Plug in default functions for all pointers in the dd_function_table * structure. * Device drivers should call this function and then plug in any * functions which it wants to override. * Some functions (pointers) MUST be implemented by all drivers (REQUIRED). * * \param table the dd_function_table to initialize */ void _mesa_init_driver_functions(struct dd_function_table *driver) { _mesa_bzero(driver, sizeof(*driver)); driver->GetString = NULL; /* REQUIRED! */ driver->UpdateState = NULL; /* REQUIRED! */ driver->GetBufferSize = NULL; /* REQUIRED! */ driver->ResizeBuffers = _mesa_resize_framebuffer; driver->Error = NULL; driver->Finish = NULL; driver->Flush = NULL; /* framebuffer/image functions */ driver->Clear = _swrast_Clear; driver->Accum = _swrast_Accum; driver->DrawPixels = _swrast_DrawPixels; driver->ReadPixels = _swrast_ReadPixels; driver->CopyPixels = _swrast_CopyPixels; driver->Bitmap = _swrast_Bitmap; /* Texture functions */ driver->ChooseTextureFormat = _mesa_choose_tex_format; driver->TexImage1D = _mesa_store_teximage1d; driver->TexImage2D = _mesa_store_teximage2d; driver->TexImage3D = _mesa_store_teximage3d; driver->TexSubImage1D = _mesa_store_texsubimage1d; driver->TexSubImage2D = _mesa_store_texsubimage2d; driver->TexSubImage3D = _mesa_store_texsubimage3d; driver->GetTexImage = _mesa_get_teximage; driver->CopyTexImage1D = _swrast_copy_teximage1d; driver->CopyTexImage2D = _swrast_copy_teximage2d; driver->CopyTexSubImage1D = _swrast_copy_texsubimage1d; driver->CopyTexSubImage2D = _swrast_copy_texsubimage2d; driver->CopyTexSubImage3D = _swrast_copy_texsubimage3d; driver->TestProxyTexImage = _mesa_test_proxy_teximage; driver->CompressedTexImage1D = _mesa_store_compressed_teximage1d; driver->CompressedTexImage2D = _mesa_store_compressed_teximage2d; driver->CompressedTexImage3D = _mesa_store_compressed_teximage3d; driver->CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; driver->CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; driver->CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; driver->GetCompressedTexImage = _mesa_get_compressed_teximage; driver->CompressedTextureSize = _mesa_compressed_texture_size; driver->BindTexture = NULL; driver->NewTextureObject = _mesa_new_texture_object; driver->DeleteTexture = _mesa_delete_texture_object; driver->NewTextureImage = _mesa_new_texture_image; driver->FreeTexImageData = _mesa_free_texture_image_data; driver->MapTexture = NULL; driver->UnmapTexture = NULL; driver->TextureMemCpy = _mesa_memcpy; driver->IsTextureResident = NULL; driver->PrioritizeTexture = NULL; driver->ActiveTexture = NULL; driver->UpdateTexturePalette = NULL; /* imaging */ driver->CopyColorTable = _swrast_CopyColorTable; driver->CopyColorSubTable = _swrast_CopyColorSubTable; driver->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; driver->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; /* Vertex/fragment programs */ driver->BindProgram = NULL; driver->NewProgram = _mesa_new_program; driver->DeleteProgram = _mesa_delete_program; #if FEATURE_MESA_program_debug driver->GetProgramRegister = _mesa_get_program_register; #endif /* FEATURE_MESA_program_debug */ /* simple state commands */ driver->AlphaFunc = NULL; driver->BlendColor = NULL; driver->BlendEquationSeparate = NULL; driver->BlendFuncSeparate = NULL; driver->ClearColor = NULL; driver->ClearDepth = NULL; driver->ClearIndex = NULL; driver->ClearStencil = NULL; driver->ClipPlane = NULL; driver->ColorMask = NULL; driver->ColorMaterial = NULL; driver->CullFace = NULL; driver->DrawBuffer = NULL; driver->DrawBuffers = NULL; driver->FrontFace = NULL; driver->DepthFunc = NULL; driver->DepthMask = NULL; driver->DepthRange = NULL; driver->Enable = NULL; driver->Fogfv = NULL; driver->Hint = NULL; driver->IndexMask = NULL; driver->Lightfv = NULL; driver->LightModelfv = NULL; driver->LineStipple = NULL; driver->LineWidth = NULL; driver->LogicOpcode = NULL; driver->PointParameterfv = NULL; driver->PointSize = NULL; driver->PolygonMode = NULL; driver->PolygonOffset = NULL; driver->PolygonStipple = NULL; driver->ReadBuffer = NULL; driver->RenderMode = NULL; driver->Scissor = NULL; driver->ShadeModel = NULL; driver->StencilFuncSeparate = NULL; driver->StencilOpSeparate = NULL; driver->StencilMaskSeparate = NULL; driver->TexGen = NULL; driver->TexEnv = NULL; driver->TexParameter = NULL; driver->TextureMatrix = NULL; driver->Viewport = NULL; /* vertex arrays */ driver->VertexPointer = NULL; driver->NormalPointer = NULL; driver->ColorPointer = NULL; driver->FogCoordPointer = NULL; driver->IndexPointer = NULL; driver->SecondaryColorPointer = NULL; driver->TexCoordPointer = NULL; driver->EdgeFlagPointer = NULL; driver->VertexAttribPointer = NULL; driver->LockArraysEXT = NULL; driver->UnlockArraysEXT = NULL; /* state queries */ driver->GetBooleanv = NULL; driver->GetDoublev = NULL; driver->GetFloatv = NULL; driver->GetIntegerv = NULL; driver->GetPointerv = NULL; #if FEATURE_ARB_vertex_buffer_object driver->NewBufferObject = _mesa_new_buffer_object; driver->DeleteBuffer = _mesa_delete_buffer_object; driver->BindBuffer = NULL; driver->BufferData = _mesa_buffer_data; driver->BufferSubData = _mesa_buffer_subdata; driver->GetBufferSubData = _mesa_buffer_get_subdata; driver->MapBuffer = _mesa_buffer_map; driver->UnmapBuffer = _mesa_buffer_unmap; #endif #if FEATURE_EXT_framebuffer_object driver->NewFramebuffer = _mesa_new_framebuffer; driver->NewRenderbuffer = _mesa_new_soft_renderbuffer; driver->RenderTexture = _mesa_render_texture; driver->FinishRenderTexture = _mesa_finish_render_texture; driver->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer; #endif #if FEATURE_EXT_framebuffer_blit driver->BlitFramebuffer = _swrast_BlitFramebuffer; #endif /* query objects */ driver->NewQueryObject = _mesa_new_query_object; driver->BeginQuery = NULL; driver->EndQuery = NULL; /* APPLE_vertex_array_object */ driver->NewArrayObject = _mesa_new_array_object; driver->DeleteArrayObject = _mesa_delete_array_object; driver->BindArrayObject = NULL; /* T&L stuff */ driver->NeedValidate = GL_FALSE; driver->ValidateTnlModule = NULL; driver->CurrentExecPrimitive = 0; driver->CurrentSavePrimitive = 0; driver->NeedFlush = 0; driver->SaveNeedFlush = 0; driver->ProgramStringNotify = _tnl_program_string; driver->FlushVertices = NULL; driver->SaveFlushVertices = NULL; driver->NotifySaveBegin = NULL; driver->LightingSpaceChange = NULL; /* display list */ driver->NewList = NULL; driver->EndList = NULL; driver->BeginCallList = NULL; driver->EndCallList = NULL; /* XXX temporary here */ _mesa_init_glsl_driver_functions(driver); }
static void reset_srcreg(struct prog_src_register* reg) { _mesa_bzero(reg, sizeof(*reg)); reg->Swizzle = SWIZZLE_NOOP; }
/** * Parse/compile the 'str' returning the compiled 'program'. * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos * indicates the position of the error in 'str'. */ void _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, const GLubyte *str, GLsizei len, struct gl_fragment_program *program) { struct parse_state parseState; struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS]; struct prog_instruction *newInst; GLenum target; GLubyte *programString; /* Make a null-terminated copy of the program string */ programString = (GLubyte *) MALLOC(len + 1); if (!programString) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); return; } MEMCPY(programString, str, len); programString[len] = 0; /* Get ready to parse */ _mesa_bzero(&parseState, sizeof(struct parse_state)); parseState.ctx = ctx; parseState.start = programString; parseState.program = program; parseState.numInst = 0; parseState.curLine = programString; parseState.parameters = _mesa_new_parameter_list(); /* Reset error state */ _mesa_set_program_error(ctx, -1, NULL); /* check the program header */ if (_mesa_strncmp((const char *) programString, "!!FP1.0", 7) == 0) { target = GL_FRAGMENT_PROGRAM_NV; parseState.pos = programString + 7; } else if (_mesa_strncmp((const char *) programString, "!!FCP1.0", 8) == 0) { /* fragment / register combiner program - not supported */ _mesa_set_program_error(ctx, 0, "Invalid fragment program header"); _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); return; } else { /* invalid header */ _mesa_set_program_error(ctx, 0, "Invalid fragment program header"); _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); return; } /* make sure target and header match */ if (target != dstTarget) { _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target mismatch 0x%x != 0x%x)", target, dstTarget); return; } if (Parse_InstructionSequence(&parseState, instBuffer)) { GLuint u; /* successful parse! */ if (parseState.outputsWritten == 0) { /* must write at least one output! */ _mesa_error(ctx, GL_INVALID_OPERATION, "Invalid fragment program - no outputs written."); return; } /* copy the compiled instructions */ assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS); newInst = _mesa_alloc_instructions(parseState.numInst); if (!newInst) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); return; /* out of memory */ } _mesa_copy_instructions(newInst, instBuffer, parseState.numInst); /* install the program */ program->Base.Target = target; if (program->Base.String) { FREE(program->Base.String); } program->Base.String = programString; program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB; if (program->Base.Instructions) { _mesa_free(program->Base.Instructions); } program->Base.Instructions = newInst; program->Base.NumInstructions = parseState.numInst; program->Base.InputsRead = parseState.inputsRead; program->Base.OutputsWritten = parseState.outputsWritten; for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) program->Base.TexturesUsed[u] = parseState.texturesUsed[u]; /* save program parameters */ program->Base.Parameters = parseState.parameters; /* allocate registers for declared program parameters */ #if 00 _mesa_assign_program_registers(&(program->SymbolTable)); #endif #ifdef DEBUG_foo _mesa_printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id); _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0); _mesa_printf("----------------------------------\n"); #endif } else { /* Error! */ _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV"); /* NOTE: _mesa_set_program_error would have been called already */ } }
/** * The glGet queries of the framebuffer red/green/blue size, stencil size, * etc. are satisfied by the fields of ctx->DrawBuffer->Visual. These can * change depending on the renderbuffer bindings. This function updates * the given framebuffer's Visual from the current renderbuffer bindings. * * This may apply to user-created framebuffers or window system framebuffers. * * Also note: ctx->DrawBuffer->Visual.depthBits might not equal * ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer.DepthBits. * The former one is used to convert floating point depth values into * integer Z values. */ void _mesa_update_framebuffer_visual(struct gl_framebuffer *fb) { GLuint i; _mesa_bzero(&fb->Visual, sizeof(fb->Visual)); fb->Visual.rgbMode = GL_TRUE; /* assume this */ #if 0 /* this _might_ be needed */ if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { /* leave visual fields zero'd */ return; } #endif /* find first RGB or CI renderbuffer */ for (i = 0; i < BUFFER_COUNT; i++) { if (fb->Attachment[i].Renderbuffer) { const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer; if (rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB) { fb->Visual.redBits = rb->RedBits; fb->Visual.greenBits = rb->GreenBits; fb->Visual.blueBits = rb->BlueBits; fb->Visual.alphaBits = rb->AlphaBits; fb->Visual.rgbBits = fb->Visual.redBits + fb->Visual.greenBits + fb->Visual.blueBits; fb->Visual.floatMode = GL_FALSE; break; } else if (rb->_BaseFormat == GL_COLOR_INDEX) { fb->Visual.indexBits = rb->IndexBits; fb->Visual.rgbMode = GL_FALSE; break; } } } if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) { fb->Visual.haveDepthBuffer = GL_TRUE; fb->Visual.depthBits = fb->Attachment[BUFFER_DEPTH].Renderbuffer->DepthBits; } if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) { fb->Visual.haveStencilBuffer = GL_TRUE; fb->Visual.stencilBits = fb->Attachment[BUFFER_STENCIL].Renderbuffer->StencilBits; } if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) { fb->Visual.haveAccumBuffer = GL_TRUE; fb->Visual.accumRedBits = fb->Attachment[BUFFER_ACCUM].Renderbuffer->RedBits; fb->Visual.accumGreenBits = fb->Attachment[BUFFER_ACCUM].Renderbuffer->GreenBits; fb->Visual.accumBlueBits = fb->Attachment[BUFFER_ACCUM].Renderbuffer->BlueBits; fb->Visual.accumAlphaBits = fb->Attachment[BUFFER_ACCUM].Renderbuffer->AlphaBits; } compute_depth_max(fb); }