static void viaRenderClippedLine(struct gl_context *ctx, GLuint ii, GLuint jj) { TNLcontext *tnl = TNL_CONTEXT(ctx); tnl->Driver.Render.Line(ctx, ii, jj); }
/* Insert the active immediate struct onto the display list currently * being built. */ static void _save_compile_vertex_list( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct tnl_vertex_list *node; /* Allocate space for this structure in the display list currently * being compiled. */ node = (struct tnl_vertex_list *) _mesa_alloc_instruction(ctx, tnl->save.opcode_vertex_list, sizeof(*node)); if (!node) return; /* Duplicate our template, increment refcounts to the storage structs: */ _mesa_memcpy(node->attrsz, tnl->save.attrsz, sizeof(node->attrsz)); node->vertex_size = tnl->save.vertex_size; node->buffer = tnl->save.buffer; node->wrap_count = tnl->save.copied.nr; node->count = tnl->save.initial_counter - tnl->save.counter; node->prim = tnl->save.prim; node->prim_count = tnl->save.prim_count; node->vertex_store = tnl->save.vertex_store; node->prim_store = tnl->save.prim_store; node->dangling_attr_ref = tnl->save.dangling_attr_ref; node->normal_lengths = 0; node->vertex_store->refcount++; node->prim_store->refcount++; assert(node->attrsz[_TNL_ATTRIB_POS] != 0 || node->count == 0); /* Maybe calculate normal lengths: */ if (tnl->CalcDListNormalLengths && node->attrsz[_TNL_ATTRIB_NORMAL] == 3 && !node->dangling_attr_ref) build_normal_lengths( node ); tnl->save.vertex_store->used += tnl->save.vertex_size * node->count; tnl->save.prim_store->used += node->prim_count; /* Decide whether the storage structs are full, or can be used for * the next vertex lists as well. */ if (tnl->save.vertex_store->used > SAVE_BUFFER_SIZE - 16 * (tnl->save.vertex_size + 4)) { tnl->save.vertex_store->refcount--; assert(tnl->save.vertex_store->refcount != 0); tnl->save.vertex_store = alloc_vertex_store( ctx ); tnl->save.vbptr = tnl->save.vertex_store->buffer; } if (tnl->save.prim_store->used > SAVE_PRIM_SIZE - 6) { tnl->save.prim_store->refcount--; assert(tnl->save.prim_store->refcount != 0); tnl->save.prim_store = alloc_prim_store( ctx ); } /* Reset our structures for the next run of vertices: */ _save_reset_counters( ctx ); /* Copy duplicated vertices */ tnl->save.copied.nr = _save_copy_vertices( ctx, node ); /* Deal with GL_COMPILE_AND_EXECUTE: */ if (ctx->ExecuteFlag) { _tnl_playback_vertex_list( ctx, (void *) node ); } }
/* * NOTE: Old 'parity' issue is gone, but copying can still be * wrong-footed on replay. */ static GLuint _save_copy_vertices( GLcontext *ctx, const struct tnl_vertex_list *node ) { TNLcontext *tnl = TNL_CONTEXT( ctx ); const struct tnl_prim *prim = &node->prim[node->prim_count-1]; GLuint nr = prim->count; GLuint sz = tnl->save.vertex_size; const GLfloat *src = node->buffer + prim->start * sz; GLfloat *dst = tnl->save.copied.buffer; GLuint ovf, i; if (prim->mode & PRIM_END) return 0; switch( prim->mode & PRIM_MODE_MASK ) { case GL_POINTS: return 0; case GL_LINES: ovf = nr&1; for (i = 0 ; i < ovf ; i++) _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); return i; case GL_TRIANGLES: ovf = nr%3; for (i = 0 ; i < ovf ; i++) _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); return i; case GL_QUADS: ovf = nr&3; for (i = 0 ; i < ovf ; i++) _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); return i; case GL_LINE_STRIP: if (nr == 0) return 0; else { _mesa_memcpy( dst, src+(nr-1)*sz, sz*sizeof(GLfloat) ); return 1; } case GL_LINE_LOOP: case GL_TRIANGLE_FAN: case GL_POLYGON: if (nr == 0) return 0; else if (nr == 1) { _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) ); return 1; } else { _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) ); _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat) ); return 2; } case GL_TRIANGLE_STRIP: case GL_QUAD_STRIP: switch (nr) { case 0: ovf = 0; break; case 1: ovf = 1; break; default: ovf = 2 + (nr&1); break; } for (i = 0 ; i < ovf ; i++) _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); return i; default: assert(0); return 0; } }
bool brwCreateContext(int api, const struct gl_config *mesaVis, __DRIcontext *driContextPriv, unsigned major_version, unsigned minor_version, uint32_t flags, unsigned *error, void *sharedContextPrivate) { __DRIscreen *sPriv = driContextPriv->driScreenPriv; struct intel_screen *screen = sPriv->driverPrivate; struct dd_function_table functions; struct brw_context *brw = rzalloc(NULL, struct brw_context); if (!brw) { printf("%s: failed to alloc context\n", __FUNCTION__); *error = __DRI_CTX_ERROR_NO_MEMORY; return false; } /* brwInitVtbl needs to know the chipset generation so that it can set the * right pointers. */ brw->gen = screen->gen; brwInitVtbl( brw ); brwInitDriverFunctions(screen, &functions); struct gl_context *ctx = &brw->ctx; if (!intelInitContext( brw, api, major_version, minor_version, mesaVis, driContextPriv, sharedContextPrivate, &functions, error)) { ralloc_free(brw); return false; } brw_initialize_context_constants(brw); /* Reinitialize the context point state. It depends on ctx->Const values. */ _mesa_init_point(ctx); if (brw->gen >= 6) { /* Create a new hardware context. Using a hardware context means that * our GPU state will be saved/restored on context switch, allowing us * to assume that the GPU is in the same state we left it in. * * This is required for transform feedback buffer offsets, query objects, * and also allows us to reduce how much state we have to emit. */ brw->hw_ctx = drm_intel_gem_context_create(brw->bufmgr); if (!brw->hw_ctx) { fprintf(stderr, "Gen6+ requires Kernel 3.6 or later.\n"); ralloc_free(brw); return false; } } brw_init_surface_formats(brw); /* Initialize swrast, tnl driver tables: */ TNLcontext *tnl = TNL_CONTEXT(ctx); if (tnl) tnl->Driver.RunPipeline = _tnl_run_pipeline; ctx->DriverFlags.NewTransformFeedback = BRW_NEW_TRANSFORM_FEEDBACK; ctx->DriverFlags.NewRasterizerDiscard = BRW_NEW_RASTERIZER_DISCARD; ctx->DriverFlags.NewUniformBuffer = BRW_NEW_UNIFORM_BUFFER; if (brw->is_g4x || brw->gen >= 5) { brw->CMD_VF_STATISTICS = GM45_3DSTATE_VF_STATISTICS; brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_GM45; brw->has_surface_tile_offset = true; if (brw->gen < 6) brw->has_compr4 = true; brw->has_aa_line_parameters = true; brw->has_pln = true; } else { brw->CMD_VF_STATISTICS = GEN4_3DSTATE_VF_STATISTICS; brw->CMD_PIPELINE_SELECT = CMD_PIPELINE_SELECT_965; } /* WM maximum threads is number of EUs times number of threads per EU. */ assert(brw->gen <= 7); if (brw->is_haswell) { if (brw->gt == 1) { brw->max_wm_threads = 102; brw->max_vs_threads = 70; brw->urb.size = 128; brw->urb.max_vs_entries = 640; brw->urb.max_gs_entries = 256; } else if (brw->gt == 2) { brw->max_wm_threads = 204; brw->max_vs_threads = 280; brw->urb.size = 256; brw->urb.max_vs_entries = 1664; brw->urb.max_gs_entries = 640; } else if (brw->gt == 3) { brw->max_wm_threads = 408; brw->max_vs_threads = 280; brw->urb.size = 512; brw->urb.max_vs_entries = 1664; brw->urb.max_gs_entries = 640; } } else if (brw->gen == 7) { if (brw->gt == 1) { brw->max_wm_threads = 48; brw->max_vs_threads = 36; brw->max_gs_threads = 36; brw->urb.size = 128; brw->urb.max_vs_entries = 512; brw->urb.max_gs_entries = 192; } else if (brw->gt == 2) { brw->max_wm_threads = 172; brw->max_vs_threads = 128; brw->max_gs_threads = 128; brw->urb.size = 256; brw->urb.max_vs_entries = 704; brw->urb.max_gs_entries = 320; } else { assert(!"Unknown gen7 device."); } } else if (brw->gen == 6) { if (brw->gt == 2) { brw->max_wm_threads = 80; brw->max_vs_threads = 60; brw->max_gs_threads = 60; brw->urb.size = 64; /* volume 5c.5 section 5.1 */ brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */ brw->urb.max_gs_entries = 256; } else { brw->max_wm_threads = 40; brw->max_vs_threads = 24; brw->max_gs_threads = 21; /* conservative; 24 if rendering disabled */ brw->urb.size = 32; /* volume 5c.5 section 5.1 */ brw->urb.max_vs_entries = 256; /* volume 2a (see 3DSTATE_URB) */ brw->urb.max_gs_entries = 256; } brw->urb.gen6_gs_previously_active = false; } else if (brw->gen == 5) { brw->urb.size = 1024; brw->max_vs_threads = 72; brw->max_gs_threads = 32; brw->max_wm_threads = 12 * 6; } else if (brw->is_g4x) { brw->urb.size = 384; brw->max_vs_threads = 32; brw->max_gs_threads = 2; brw->max_wm_threads = 10 * 5; } else if (brw->gen < 6) { brw->urb.size = 256; brw->max_vs_threads = 16; brw->max_gs_threads = 2; brw->max_wm_threads = 8 * 4; brw->has_negative_rhw_bug = true; } if (brw->gen <= 7) { brw->needs_unlit_centroid_workaround = true; } brw->prim_restart.in_progress = false; brw->prim_restart.enable_cut_index = false; brw_init_state( brw ); brw->curbe.last_buf = calloc(1, 4096); brw->curbe.next_buf = calloc(1, 4096); brw->state.dirty.mesa = ~0; brw->state.dirty.brw = ~0; brw->emit_state_always = 0; brw->batch.need_workaround_flush = true; ctx->VertexProgram._MaintainTnlProgram = true; ctx->FragmentProgram._MaintainTexEnvProgram = true; brw_draw_init( brw ); brw->precompile = driQueryOptionb(&brw->optionCache, "shader_precompile"); ctx->Const.ContextFlags = 0; if ((flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) != 0) ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; if ((flags & __DRI_CTX_FLAG_DEBUG) != 0) { ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT; /* Turn on some extra GL_ARB_debug_output generation. */ brw->perf_debug = true; } brw_fs_alloc_reg_sets(brw); if (INTEL_DEBUG & DEBUG_SHADER_TIME) brw_init_shader_time(brw); _mesa_compute_version(ctx); _mesa_initialize_dispatch_tables(ctx); _mesa_initialize_vbo_vtxfmt(ctx); return true; }
static void _save_vtxfmt_init( GLcontext *ctx ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLvertexformat *vfmt = &tnl->save_vtxfmt; vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ vfmt->Begin = _save_Begin; vfmt->Color3f = _save_Color3f; vfmt->Color3fv = _save_Color3fv; vfmt->Color4f = _save_Color4f; vfmt->Color4fv = _save_Color4fv; vfmt->EdgeFlag = _save_EdgeFlag; vfmt->EdgeFlagv = _save_EdgeFlagv; vfmt->End = _save_End; vfmt->FogCoordfEXT = _save_FogCoordfEXT; vfmt->FogCoordfvEXT = _save_FogCoordfvEXT; vfmt->Indexf = _save_Indexf; vfmt->Indexfv = _save_Indexfv; vfmt->Materialfv = _save_Materialfv; vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f; vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv; vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f; vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv; vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f; vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv; vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f; vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv; vfmt->Normal3f = _save_Normal3f; vfmt->Normal3fv = _save_Normal3fv; vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT; vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT; vfmt->TexCoord1f = _save_TexCoord1f; vfmt->TexCoord1fv = _save_TexCoord1fv; vfmt->TexCoord2f = _save_TexCoord2f; vfmt->TexCoord2fv = _save_TexCoord2fv; vfmt->TexCoord3f = _save_TexCoord3f; vfmt->TexCoord3fv = _save_TexCoord3fv; vfmt->TexCoord4f = _save_TexCoord4f; vfmt->TexCoord4fv = _save_TexCoord4fv; vfmt->Vertex2f = _save_Vertex2f; vfmt->Vertex2fv = _save_Vertex2fv; vfmt->Vertex3f = _save_Vertex3f; vfmt->Vertex3fv = _save_Vertex3fv; vfmt->Vertex4f = _save_Vertex4f; vfmt->Vertex4fv = _save_Vertex4fv; vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV; vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV; vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV; vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV; vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV; vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV; vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV; vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV; vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB; vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB; vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB; vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB; vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB; vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB; vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB; vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB; /* This will all require us to fallback to saving the list as opcodes: */ vfmt->CallList = _save_CallList; /* inside begin/end */ vfmt->CallLists = _save_CallLists; /* inside begin/end */ vfmt->EvalCoord1f = _save_EvalCoord1f; vfmt->EvalCoord1fv = _save_EvalCoord1fv; vfmt->EvalCoord2f = _save_EvalCoord2f; vfmt->EvalCoord2fv = _save_EvalCoord2fv; vfmt->EvalPoint1 = _save_EvalPoint1; vfmt->EvalPoint2 = _save_EvalPoint2; /* These are all errors as we at least know we are in some sort of * begin/end pair: */ vfmt->EvalMesh1 = _save_EvalMesh1; vfmt->EvalMesh2 = _save_EvalMesh2; vfmt->Begin = _save_Begin; vfmt->Rectf = _save_Rectf; vfmt->DrawArrays = _save_DrawArrays; vfmt->DrawElements = _save_DrawElements; vfmt->DrawRangeElements = _save_DrawRangeElements; }
GLboolean brwCreateContext(gl_api api, const struct gl_config *mesaVis, __DRIcontext *driContextPriv, unsigned major_version, unsigned minor_version, uint32_t flags, bool notify_reset, unsigned *dri_ctx_error, void *sharedContextPrivate) { __DRIscreen *sPriv = driContextPriv->driScreenPriv; struct gl_context *shareCtx = (struct gl_context *) sharedContextPrivate; struct intel_screen *screen = sPriv->driverPrivate; const struct brw_device_info *devinfo = screen->devinfo; struct dd_function_table functions; /* Only allow the __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS flag if the kernel * provides us with context reset notifications. */ uint32_t allowed_flags = __DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE; if (screen->has_context_reset_notification) allowed_flags |= __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS; if (flags & ~allowed_flags) { *dri_ctx_error = __DRI_CTX_ERROR_UNKNOWN_FLAG; return false; } struct brw_context *brw = rzalloc(NULL, struct brw_context); if (!brw) { fprintf(stderr, "%s: failed to alloc context\n", __FUNCTION__); *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY; return false; } driContextPriv->driverPrivate = brw; brw->driContext = driContextPriv; brw->intelScreen = screen; brw->bufmgr = screen->bufmgr; brw->gen = devinfo->gen; brw->gt = devinfo->gt; brw->is_g4x = devinfo->is_g4x; brw->is_baytrail = devinfo->is_baytrail; brw->is_haswell = devinfo->is_haswell; brw->has_llc = devinfo->has_llc; brw->has_hiz = devinfo->has_hiz_and_separate_stencil; brw->has_separate_stencil = devinfo->has_hiz_and_separate_stencil; brw->has_pln = devinfo->has_pln; brw->has_compr4 = devinfo->has_compr4; brw->has_surface_tile_offset = devinfo->has_surface_tile_offset; brw->has_negative_rhw_bug = devinfo->has_negative_rhw_bug; brw->needs_unlit_centroid_workaround = devinfo->needs_unlit_centroid_workaround; brw->must_use_separate_stencil = screen->hw_must_use_separate_stencil; brw->has_swizzling = screen->hw_has_swizzling; brw->vs.base.stage = MESA_SHADER_VERTEX; brw->gs.base.stage = MESA_SHADER_GEOMETRY; brw->wm.base.stage = MESA_SHADER_FRAGMENT; if (brw->gen >= 8) { gen8_init_vtable_surface_functions(brw); gen7_init_vtable_sampler_functions(brw); brw->vtbl.emit_depth_stencil_hiz = gen8_emit_depth_stencil_hiz; } else if (brw->gen >= 7) { gen7_init_vtable_surface_functions(brw); gen7_init_vtable_sampler_functions(brw); brw->vtbl.emit_depth_stencil_hiz = gen7_emit_depth_stencil_hiz; } else { gen4_init_vtable_surface_functions(brw); gen4_init_vtable_sampler_functions(brw); brw->vtbl.emit_depth_stencil_hiz = brw_emit_depth_stencil_hiz; } brw_init_driver_functions(brw, &functions); if (notify_reset) functions.GetGraphicsResetStatus = brw_get_graphics_reset_status; struct gl_context *ctx = &brw->ctx; if (!_mesa_initialize_context(ctx, api, mesaVis, shareCtx, &functions)) { *dri_ctx_error = __DRI_CTX_ERROR_NO_MEMORY; fprintf(stderr, "%s: failed to init mesa context\n", __FUNCTION__); intelDestroyContext(driContextPriv); return false; } driContextSetFlags(ctx, flags); /* Initialize the software rasterizer and helper modules. * * As of GL 3.1 core, the gen4+ driver doesn't need the swrast context for * software fallbacks (which we have to support on legacy GL to do weird * glDrawPixels(), glBitmap(), and other functions). */ if (api != API_OPENGL_CORE && api != API_OPENGLES2) { _swrast_CreateContext(ctx); } _vbo_CreateContext(ctx); if (ctx->swrast_context) { _tnl_CreateContext(ctx); TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; _swsetup_CreateContext(ctx); /* Configure swrast to match hardware characteristics: */ _swrast_allow_pixel_fog(ctx, false); _swrast_allow_vertex_fog(ctx, true); } _mesa_meta_init(ctx); brw_process_driconf_options(brw); brw_process_intel_debug_variable(brw); brw_initialize_context_constants(brw); ctx->Const.ResetStrategy = notify_reset ? GL_LOSE_CONTEXT_ON_RESET_ARB : GL_NO_RESET_NOTIFICATION_ARB; /* Reinitialize the context point state. It depends on ctx->Const values. */ _mesa_init_point(ctx); intel_fbo_init(brw); intel_batchbuffer_init(brw); if (brw->gen >= 6) { /* Create a new hardware context. Using a hardware context means that * our GPU state will be saved/restored on context switch, allowing us * to assume that the GPU is in the same state we left it in. * * This is required for transform feedback buffer offsets, query objects, * and also allows us to reduce how much state we have to emit. */ brw->hw_ctx = drm_intel_gem_context_create(brw->bufmgr); if (!brw->hw_ctx) { fprintf(stderr, "Gen6+ requires Kernel 3.6 or later.\n"); intelDestroyContext(driContextPriv); return false; } } brw_init_state(brw); intelInitExtensions(ctx); brw_init_surface_formats(brw); brw->max_vs_threads = devinfo->max_vs_threads; brw->max_gs_threads = devinfo->max_gs_threads; brw->max_wm_threads = devinfo->max_wm_threads; brw->urb.size = devinfo->urb.size; brw->urb.min_vs_entries = devinfo->urb.min_vs_entries; brw->urb.max_vs_entries = devinfo->urb.max_vs_entries; brw->urb.max_gs_entries = devinfo->urb.max_gs_entries; /* Estimate the size of the mappable aperture into the GTT. There's an * ioctl to get the whole GTT size, but not one to get the mappable subset. * It turns out it's basically always 256MB, though some ancient hardware * was smaller. */ uint32_t gtt_size = 256 * 1024 * 1024; /* We don't want to map two objects such that a memcpy between them would * just fault one mapping in and then the other over and over forever. So * we would need to divide the GTT size by 2. Additionally, some GTT is * taken up by things like the framebuffer and the ringbuffer and such, so * be more conservative. */ brw->max_gtt_map_object_size = gtt_size / 4; if (brw->gen == 6) brw->urb.gen6_gs_previously_active = false; brw->prim_restart.in_progress = false; brw->prim_restart.enable_cut_index = false; brw->gs.enabled = false; if (brw->gen < 6) { brw->curbe.last_buf = calloc(1, 4096); brw->curbe.next_buf = calloc(1, 4096); } ctx->VertexProgram._MaintainTnlProgram = true; ctx->FragmentProgram._MaintainTexEnvProgram = true; brw_draw_init( brw ); if ((flags & __DRI_CTX_FLAG_DEBUG) != 0) { /* Turn on some extra GL_ARB_debug_output generation. */ brw->perf_debug = true; } if ((flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS) != 0) ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB; if (INTEL_DEBUG & DEBUG_SHADER_TIME) brw_init_shader_time(brw); _mesa_compute_version(ctx); _mesa_initialize_dispatch_tables(ctx); _mesa_initialize_vbo_vtxfmt(ctx); if (ctx->Extensions.AMD_performance_monitor) { brw_init_performance_monitors(brw); } vbo_use_buffer_objects(ctx); vbo_always_unmap_buffers(ctx); return true; }
/** * Predict total emit size for next rendering operation so there is no flush in middle of rendering * Prediction has to aim towards the best possible value that is worse than worst case scenario */ static GLuint radeonEnsureEmitSize( GLcontext * ctx , GLuint inputs ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint space_required; GLuint state_size; GLuint nr_aos = 1; /* radeonEmitArrays does always emit one */ int i; /* list of flags that are allocating aos object */ const GLuint flags_to_check[] = { VERT_BIT_NORMAL, VERT_BIT_COLOR0, VERT_BIT_COLOR1, VERT_BIT_FOG }; /* predict number of aos to emit */ for (i=0; i < sizeof(flags_to_check)/sizeof(flags_to_check[0]); ++i) { if (inputs & flags_to_check[i]) ++nr_aos; } for (i = 0; i < ctx->Const.MaxTextureUnits; ++i) { if (inputs & VERT_BIT_TEX(i)) ++nr_aos; } { /* count the prediction for state size */ space_required = 0; state_size = radeonCountStateEmitSize( &rmesa->radeon ); /* tcl may be changed in radeonEmitArrays so account for it if not dirty */ if (!rmesa->hw.tcl.dirty) state_size += rmesa->hw.tcl.check( rmesa->radeon.glCtx, &rmesa->hw.tcl ); /* predict size for elements */ for (i = 0; i < VB->PrimitiveCount; ++i) { if (!VB->Primitive[i].count) continue; /* If primitive.count is less than MAX_CONVERSION_SIZE rendering code may decide convert to elts. In that case we have to make pessimistic prediction. and use larger of 2 paths. */ const GLuint elts = ELTS_BUFSZ(nr_aos); const GLuint index = INDEX_BUFSZ; const GLuint vbuf = VBUF_BUFSZ; if ( (!VB->Elts && VB->Primitive[i].count >= MAX_CONVERSION_SIZE) || vbuf > index + elts) space_required += vbuf; else space_required += index + elts; space_required += VB->Primitive[i].count * 3; space_required += AOS_BUFSZ(nr_aos); } space_required += SCISSOR_BUFSZ; } /* flush the buffer in case we need more than is left. */ if (rcommonEnsureCmdBufSpace(&rmesa->radeon, space_required, __FUNCTION__)) return space_required + radeonCountStateEmitSize( &rmesa->radeon ); else return space_required + state_size; }
/** * Drivers call this function to tell the TCL module whether or not * it wants Normalized Device Coords (NDC) computed. I.e. whether * we should "Divide-by-W". Software renders will want that. */ void _tnl_need_projected_coords( GLcontext *ctx, GLboolean mode ) { TNLcontext *tnl = TNL_CONTEXT(ctx); tnl->NeedNdcCoords = mode; }
static GLboolean run_render( GLcontext *ctx, struct tnl_pipeline_stage *stage ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; tnl_render_func *tab; GLint pass = 0; /* Allow the drivers to lock before projected verts are built so * that window coordinates are guarenteed not to change before * rendering. */ ASSERT(tnl->Driver.Render.Start); tnl->Driver.Render.Start( ctx ); ASSERT(tnl->Driver.Render.BuildVertices); ASSERT(tnl->Driver.Render.PrimitiveNotify); ASSERT(tnl->Driver.Render.Points); ASSERT(tnl->Driver.Render.Line); ASSERT(tnl->Driver.Render.Triangle); ASSERT(tnl->Driver.Render.Quad); ASSERT(tnl->Driver.Render.ResetLineStipple); ASSERT(tnl->Driver.Render.Interp); ASSERT(tnl->Driver.Render.CopyPV); ASSERT(tnl->Driver.Render.ClippedLine); ASSERT(tnl->Driver.Render.ClippedPolygon); ASSERT(tnl->Driver.Render.Finish); tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 ); if (VB->ClipOrMask) { tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; } else { tab = (VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts); } do { GLuint i; for (i = 0 ; i < VB->PrimitiveCount ; i++) { GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; assert((prim & PRIM_MODE_MASK) <= GL_POLYGON); if (MESA_VERBOSE & VERBOSE_PRIMS) _mesa_debug(NULL, "MESA prim %s %d..%d\n", _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK), start, start+length); if (length) tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim ); } } while (tnl->Driver.Render.Multipass && tnl->Driver.Render.Multipass( ctx, ++pass )); tnl->Driver.Render.Finish( ctx ); return GL_FALSE; /* finished the pipe */ }
static GLboolean dri_create_context(gl_api api, const struct gl_config * visual, __DRIcontext * cPriv, void *sharedContextPrivate) { struct dri_context *ctx = NULL; struct dri_context *share = (struct dri_context *)sharedContextPrivate; struct gl_context *mesaCtx = NULL; struct gl_context *sharedCtx = NULL; struct dd_function_table functions; TRACE; ctx = CALLOC_STRUCT(dri_context); if (ctx == NULL) goto context_fail; cPriv->driverPrivate = ctx; ctx->cPriv = cPriv; /* build table of device driver functions */ _mesa_init_driver_functions(&functions); swrast_init_driver_functions(&functions); if (share) { sharedCtx = &share->Base; } mesaCtx = &ctx->Base; /* basic context setup */ if (!_mesa_initialize_context(mesaCtx, api, visual, sharedCtx, &functions, (void *) cPriv)) { goto context_fail; } /* do bounds checking to prevent segfaults and server crashes! */ mesaCtx->Const.CheckArrayBounds = GL_TRUE; /* create module contexts */ _swrast_CreateContext( mesaCtx ); _vbo_CreateContext( mesaCtx ); _tnl_CreateContext( mesaCtx ); _swsetup_CreateContext( mesaCtx ); _swsetup_Wakeup( mesaCtx ); /* use default TCL pipeline */ { TNLcontext *tnl = TNL_CONTEXT(mesaCtx); tnl->Driver.RunPipeline = _tnl_run_pipeline; } _mesa_meta_init(mesaCtx); _mesa_enable_sw_extensions(mesaCtx); switch (api) { case API_OPENGL: _mesa_enable_1_3_extensions(mesaCtx); _mesa_enable_1_4_extensions(mesaCtx); _mesa_enable_1_5_extensions(mesaCtx); _mesa_enable_2_0_extensions(mesaCtx); _mesa_enable_2_1_extensions(mesaCtx); break; case API_OPENGLES: _mesa_enable_1_3_extensions(mesaCtx); _mesa_enable_1_4_extensions(mesaCtx); _mesa_enable_1_5_extensions(mesaCtx); break; case API_OPENGLES2: InitExtensionsES2( mesaCtx); break; } return GL_TRUE; context_fail: FREE(ctx); return GL_FALSE; }
void _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) { TNLcontext *tnl = TNL_CONTEXT(ctx); const struct gl_vertex_program *vp = ctx->VertexProgram._Current; const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; if (new_state & (_NEW_HINT | _NEW_PROGRAM)) { ASSERT(tnl->AllowVertexFog || tnl->AllowPixelFog); tnl->_DoVertexFog = ((tnl->AllowVertexFog && (ctx->Hint.Fog != GL_NICEST)) || !tnl->AllowPixelFog) && !fp; } tnl->pipeline.new_state |= new_state; /* Calculate tnl->render_inputs. This bitmask indicates which vertex * attributes need to be emitted to the rasterizer. */ if (ctx->Visual.rgbMode) { GLuint i; RENDERINPUTS_ZERO( tnl->render_inputs_bitset ); RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POS ); if (!fp || (fp->Base.InputsRead & FRAG_BIT_COL0)) { RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0 ); } if (NEED_SECONDARY_COLOR(ctx)) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR1 ); for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { if (ctx->Texture._EnabledCoordUnits & (1 << i) || (fp && fp->Base.InputsRead & FRAG_BIT_TEX(i))) { RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) ); } } } else { RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POS ); RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR_INDEX ); } if (ctx->Fog.Enabled) { /* fixed-function fog */ RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); } else if (fp) { if (fp->FogOption != GL_NONE || (fp->Base.InputsRead & FRAG_BIT_FOGC)) { /* fragment program needs fog coord */ RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); } } if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_EDGEFLAG ); if (ctx->RenderMode == GL_FEEDBACK) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_TEX0 ); if (ctx->Point._Attenuated || (ctx->VertexProgram._Enabled && ctx->VertexProgram.PointSizeEnabled)) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE ); /* check for varying vars which are written by the vertex program */ if (vp) { GLuint i; for (i = 0; i < MAX_VARYING; i++) { if (vp->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_VAR0 + i)) { RENDERINPUTS_SET(tnl->render_inputs_bitset, _TNL_ATTRIB_GENERIC(i)); } } } }
static GLboolean dri_create_context(gl_api api, const struct gl_config * visual, __DRIcontext * cPriv, unsigned major_version, unsigned minor_version, uint32_t flags, bool notify_reset, unsigned *error, void *sharedContextPrivate) { struct dri_context *ctx = NULL; struct dri_context *share = (struct dri_context *)sharedContextPrivate; struct gl_context *mesaCtx = NULL; struct gl_context *sharedCtx = NULL; struct dd_function_table functions; TRACE; /* Flag filtering is handled in dri2CreateContextAttribs. */ (void) flags; ctx = CALLOC_STRUCT(dri_context); if (ctx == NULL) { *error = __DRI_CTX_ERROR_NO_MEMORY; goto context_fail; } cPriv->driverPrivate = ctx; ctx->cPriv = cPriv; /* build table of device driver functions */ _mesa_init_driver_functions(&functions); swrast_init_driver_functions(&functions); if (share) { sharedCtx = &share->Base; } mesaCtx = &ctx->Base; /* basic context setup */ if (!_mesa_initialize_context(mesaCtx, api, visual, sharedCtx, &functions)) { *error = __DRI_CTX_ERROR_NO_MEMORY; goto context_fail; } driContextSetFlags(mesaCtx, flags); /* do bounds checking to prevent segfaults and server crashes! */ mesaCtx->Const.CheckArrayBounds = GL_TRUE; /* create module contexts */ _swrast_CreateContext( mesaCtx ); _vbo_CreateContext( mesaCtx ); _tnl_CreateContext( mesaCtx ); _swsetup_CreateContext( mesaCtx ); _swsetup_Wakeup( mesaCtx ); /* use default TCL pipeline */ { TNLcontext *tnl = TNL_CONTEXT(mesaCtx); tnl->Driver.RunPipeline = _tnl_run_pipeline; } _mesa_meta_init(mesaCtx); _mesa_enable_sw_extensions(mesaCtx); _mesa_compute_version(mesaCtx); _mesa_initialize_dispatch_tables(mesaCtx); _mesa_initialize_vbo_vtxfmt(mesaCtx); *error = __DRI_CTX_ERROR_SUCCESS; return GL_TRUE; context_fail: free(ctx); return GL_FALSE; }
static void viaChooseVertexState( struct gl_context *ctx ) { struct via_context *vmesa = VIA_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); DECLARE_RENDERINPUTS(index_bitset); GLuint regCmdB = HC_HVPMSK_X | HC_HVPMSK_Y | HC_HVPMSK_Z; GLuint setupIndex = 0; RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset ); vmesa->vertex_attr_count = 0; /* EMIT_ATTR's must be in order as they tell t_vertex.c how to * build up a hardware vertex. */ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ) || RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) { EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VIA_EMIT_W, HC_HVPMSK_W ); vmesa->coloroffset = 4; } else { EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 0 ); vmesa->coloroffset = 3; } /* t_context.c always includes a diffuse color */ EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VIA_EMIT_RGBA, HC_HVPMSK_Cd ); vmesa->specoffset = 0; if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) || RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) { if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) { vmesa->specoffset = vmesa->coloroffset + 1; EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VIA_EMIT_SPEC, HC_HVPMSK_Cs ); } else EMIT_PAD( 3 ); if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, VIA_EMIT_FOG, HC_HVPMSK_Cs ); else EMIT_PAD( 1 ); } if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) { if (vmesa->ptexHack) EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_3F_XYW, VIA_EMIT_PTEX0, (HC_HVPMSK_S | HC_HVPMSK_T) ); else EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, VIA_EMIT_TEX0, (HC_HVPMSK_S | HC_HVPMSK_T) ); } if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) { EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, VIA_EMIT_TEX1, (HC_HVPMSK_S | HC_HVPMSK_T) ); } if (setupIndex != vmesa->setupIndex) { vmesa->vertexSize = _tnl_install_attrs( ctx, vmesa->vertex_attrs, vmesa->vertex_attr_count, vmesa->ViewportMatrix.m, 0 ); vmesa->vertexSize >>= 2; vmesa->setupIndex = setupIndex; vmesa->regCmdB &= ~HC_HVPMSK_MASK; vmesa->regCmdB |= regCmdB; if (vmesa->ptexHack) vmesa->hwVertexSize = vmesa->vertexSize - 1; else vmesa->hwVertexSize = vmesa->vertexSize; }
static void viaChooseRenderState(struct gl_context *ctx) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct via_context *vmesa = VIA_CONTEXT(ctx); GLuint flags = ctx->_TriangleCaps; GLuint index = 0; if (vmesa->ptexHack) { vmesa->drawPoint = via_ptex_point; vmesa->drawLine = via_ptex_line; vmesa->drawTri = via_ptex_tri; index |= VIA_FALLBACK_BIT; } else { vmesa->drawPoint = via_draw_point; vmesa->drawLine = via_draw_line; vmesa->drawTri = via_draw_triangle; } if (flags & (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)) { if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) index |= VIA_TWOSIDE_BIT; if (ctx->Polygon.FrontMode != GL_FILL || ctx->Polygon.BackMode != GL_FILL) index |= VIA_UNFILLED_BIT; if (flags & DD_TRI_OFFSET) index |= VIA_OFFSET_BIT; if (flags & ANY_FALLBACK_FLAGS) index |= VIA_FALLBACK_BIT; /* Hook in fallbacks for specific primitives. */ if (flags & POINT_FALLBACK) vmesa->drawPoint = via_fallback_point; if (flags & LINE_FALLBACK) vmesa->drawLine = via_fallback_line; if (flags & TRI_FALLBACK) vmesa->drawTri = via_fallback_tri; } if ((flags & DD_SEPARATE_SPECULAR) && ctx->Light.ShadeModel == GL_FLAT) index = VIA_MAX_TRIFUNC; /* flat specular */ if (vmesa->renderIndex != index) { vmesa->renderIndex = index; tnl->Driver.Render.Points = rast_tab[index].points; tnl->Driver.Render.Line = rast_tab[index].line; tnl->Driver.Render.Triangle = rast_tab[index].triangle; tnl->Driver.Render.Quad = rast_tab[index].quad; if (index == 0) { tnl->Driver.Render.PrimTabVerts = via_render_tab_verts; tnl->Driver.Render.PrimTabElts = via_render_tab_elts; tnl->Driver.Render.ClippedLine = line; /* from tritmp.h */ tnl->Driver.Render.ClippedPolygon = viaFastRenderClippedPoly; } else { tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; tnl->Driver.Render.ClippedLine = viaRenderClippedLine; tnl->Driver.Render.ClippedPolygon = viaRenderClippedPoly; } } }
GLboolean brwCreateContext( const __GLcontextModes *mesaVis, __DRIcontextPrivate *driContextPriv, void *sharedContextPrivate) { struct dd_function_table functions; struct brw_context *brw = (struct brw_context *) CALLOC_STRUCT(brw_context); struct intel_context *intel = &brw->intel; GLcontext *ctx = &intel->ctx; if (!brw) { _mesa_printf("%s: failed to alloc context\n", __FUNCTION__); return GL_FALSE; } brwInitVtbl( brw ); brwInitDriverFunctions( &functions ); if (!intelInitContext( intel, mesaVis, driContextPriv, sharedContextPrivate, &functions )) { _mesa_printf("%s: failed to init intel context\n", __FUNCTION__); FREE(brw); return GL_FALSE; } /* Initialize swrast, tnl driver tables: */ intelInitSpanFuncs(ctx); TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; ctx->Const.MaxDrawBuffers = BRW_MAX_DRAW_BUFFERS; ctx->Const.MaxTextureImageUnits = BRW_MAX_TEX_UNIT; ctx->Const.MaxTextureCoordUnits = 8; /* Mesa limit */ ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, ctx->Const.MaxTextureImageUnits); ctx->Const.MaxVertexTextureImageUnits = 0; /* no vertex shader textures */ /* Mesa limits textures to 4kx4k; it would be nice to fix that someday */ ctx->Const.MaxTextureLevels = 13; ctx->Const.Max3DTextureLevels = 9; ctx->Const.MaxCubeTextureLevels = 12; ctx->Const.MaxTextureRectSize = (1<<12); ctx->Const.MaxTextureMaxAnisotropy = 16.0; /* if conformance mode is set, swrast can handle any size AA point */ ctx->Const.MaxPointSizeAA = 255.0; /* We want the GLSL compiler to emit code that uses condition codes */ ctx->Shader.EmitCondCodes = GL_TRUE; ctx->Shader.EmitNVTempInitialization = GL_TRUE; ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024); ctx->Const.VertexProgram.MaxAluInstructions = 0; ctx->Const.VertexProgram.MaxTexInstructions = 0; ctx->Const.VertexProgram.MaxTexIndirections = 0; ctx->Const.VertexProgram.MaxNativeAluInstructions = 0; ctx->Const.VertexProgram.MaxNativeTexInstructions = 0; ctx->Const.VertexProgram.MaxNativeTexIndirections = 0; ctx->Const.VertexProgram.MaxNativeAttribs = 16; ctx->Const.VertexProgram.MaxNativeTemps = 256; ctx->Const.VertexProgram.MaxNativeAddressRegs = 1; ctx->Const.VertexProgram.MaxNativeParameters = 1024; ctx->Const.VertexProgram.MaxEnvParams = MIN2(ctx->Const.VertexProgram.MaxNativeParameters, ctx->Const.VertexProgram.MaxEnvParams); ctx->Const.FragmentProgram.MaxNativeInstructions = (16 * 1024); ctx->Const.FragmentProgram.MaxNativeAluInstructions = (16 * 1024); ctx->Const.FragmentProgram.MaxNativeTexInstructions = (16 * 1024); ctx->Const.FragmentProgram.MaxNativeTexIndirections = (16 * 1024); ctx->Const.FragmentProgram.MaxNativeAttribs = 12; ctx->Const.FragmentProgram.MaxNativeTemps = 256; ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; ctx->Const.FragmentProgram.MaxNativeParameters = 1024; ctx->Const.FragmentProgram.MaxEnvParams = MIN2(ctx->Const.FragmentProgram.MaxNativeParameters, ctx->Const.FragmentProgram.MaxEnvParams); brw_init_state( brw ); brw->state.dirty.mesa = ~0; brw->state.dirty.brw = ~0; brw->emit_state_always = 0; ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; make_empty_list(&brw->query.active_head); brw_draw_init( brw ); return GL_TRUE; }
/* Initialize the context's hardware state. */ void radeonInitState( r100ContextPtr rmesa ) { GLcontext *ctx = rmesa->radeon.glCtx; GLuint i; rmesa->radeon.state.color.clear = 0x00000000; switch ( ctx->Visual.depthBits ) { case 16: rmesa->radeon.state.depth.clear = 0x0000ffff; rmesa->radeon.state.stencil.clear = 0x00000000; break; case 24: rmesa->radeon.state.depth.clear = 0x00ffffff; rmesa->radeon.state.stencil.clear = 0xffff0000; break; default: break; } rmesa->radeon.Fallback = 0; rmesa->radeon.hw.max_state_size = 0; #define ALLOC_STATE_IDX( ATOM, CHK, SZ, NM, FLAG, IDX ) \ do { \ rmesa->hw.ATOM.cmd_size = SZ; \ rmesa->hw.ATOM.cmd = (GLuint *)CALLOC(SZ * sizeof(int)); \ rmesa->hw.ATOM.lastcmd = (GLuint *)CALLOC(SZ * sizeof(int)); \ rmesa->hw.ATOM.name = NM; \ rmesa->hw.ATOM.is_tcl = FLAG; \ rmesa->hw.ATOM.check = check_##CHK; \ rmesa->hw.ATOM.dirty = GL_TRUE; \ rmesa->hw.ATOM.idx = IDX; \ rmesa->radeon.hw.max_state_size += SZ * sizeof(int); \ } while (0) #define ALLOC_STATE( ATOM, CHK, SZ, NM, FLAG ) \ ALLOC_STATE_IDX(ATOM, CHK, SZ, NM, FLAG, 0) /* Allocate state buffers: */ ALLOC_STATE( ctx, always_add4, CTX_STATE_SIZE, "CTX/context", 0 ); if (rmesa->radeon.radeonScreen->kernel_mm) { rmesa->hw.ctx.emit = ctx_emit_cs; rmesa->hw.ctx.check = check_always_ctx; } else rmesa->hw.ctx.emit = ctx_emit; ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 ); ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 ); ALLOC_STATE( vpt, always, VPT_STATE_SIZE, "VPT/viewport", 0 ); ALLOC_STATE( set, always, SET_STATE_SIZE, "SET/setup", 0 ); ALLOC_STATE( msc, always, MSC_STATE_SIZE, "MSC/misc", 0 ); ALLOC_STATE( zbs, always, ZBS_STATE_SIZE, "ZBS/zbias", 0 ); ALLOC_STATE( tcl, always, TCL_STATE_SIZE, "TCL/tcl", 1 ); ALLOC_STATE( mtl, tcl_lighting, MTL_STATE_SIZE, "MTL/material", 1 ); if (rmesa->radeon.radeonScreen->kernel_mm) { ALLOC_STATE( grd, always_add2, GRD_STATE_SIZE, "GRD/guard-band", 1 ); ALLOC_STATE( fog, fog_add4, FOG_STATE_SIZE, "FOG/fog", 1 ); ALLOC_STATE( glt, tcl_lighting_add4, GLT_STATE_SIZE, "GLT/light-global", 1 ); ALLOC_STATE( eye, tcl_lighting_add4, EYE_STATE_SIZE, "EYE/eye-vector", 1 ); ALLOC_STATE_IDX( tex[0], tex0_mm, TEX_STATE_SIZE, "TEX/tex-0", 0, 0); ALLOC_STATE_IDX( tex[1], tex1_mm, TEX_STATE_SIZE, "TEX/tex-1", 0, 1); ALLOC_STATE_IDX( tex[2], tex2_mm, TEX_STATE_SIZE, "TEX/tex-2", 0, 2); ALLOC_STATE( mat[0], tcl_add4, MAT_STATE_SIZE, "MAT/modelproject", 1 ); ALLOC_STATE( mat[1], tcl_eyespace_or_fog_add4, MAT_STATE_SIZE, "MAT/modelview", 1 ); ALLOC_STATE( mat[2], tcl_eyespace_or_lighting_add4, MAT_STATE_SIZE, "MAT/it-modelview", 1 ); ALLOC_STATE( mat[3], tcl_tex0_add4, MAT_STATE_SIZE, "MAT/texmat0", 1 ); ALLOC_STATE( mat[4], tcl_tex1_add4, MAT_STATE_SIZE, "MAT/texmat1", 1 ); ALLOC_STATE( mat[5], tcl_tex2_add4, MAT_STATE_SIZE, "MAT/texmat2", 1 ); ALLOC_STATE( lit[0], tcl_lit0_add6, LIT_STATE_SIZE, "LIT/light-0", 1 ); ALLOC_STATE( lit[1], tcl_lit1_add6, LIT_STATE_SIZE, "LIT/light-1", 1 ); ALLOC_STATE( lit[2], tcl_lit2_add6, LIT_STATE_SIZE, "LIT/light-2", 1 ); ALLOC_STATE( lit[3], tcl_lit3_add6, LIT_STATE_SIZE, "LIT/light-3", 1 ); ALLOC_STATE( lit[4], tcl_lit4_add6, LIT_STATE_SIZE, "LIT/light-4", 1 ); ALLOC_STATE( lit[5], tcl_lit5_add6, LIT_STATE_SIZE, "LIT/light-5", 1 ); ALLOC_STATE( lit[6], tcl_lit6_add6, LIT_STATE_SIZE, "LIT/light-6", 1 ); ALLOC_STATE( lit[7], tcl_lit7_add6, LIT_STATE_SIZE, "LIT/light-7", 1 ); ALLOC_STATE( ucp[0], tcl_ucp0_add4, UCP_STATE_SIZE, "UCP/userclip-0", 1 ); ALLOC_STATE( ucp[1], tcl_ucp1_add4, UCP_STATE_SIZE, "UCP/userclip-1", 1 ); ALLOC_STATE( ucp[2], tcl_ucp2_add4, UCP_STATE_SIZE, "UCP/userclip-2", 1 ); ALLOC_STATE( ucp[3], tcl_ucp3_add4, UCP_STATE_SIZE, "UCP/userclip-3", 1 ); ALLOC_STATE( ucp[4], tcl_ucp4_add4, UCP_STATE_SIZE, "UCP/userclip-4", 1 ); ALLOC_STATE( ucp[5], tcl_ucp5_add4, UCP_STATE_SIZE, "UCP/userclip-5", 1 ); } else { ALLOC_STATE( grd, always, GRD_STATE_SIZE, "GRD/guard-band", 1 ); ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 1 ); ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 1 ); ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 1 ); ALLOC_STATE_IDX( tex[0], tex0, TEX_STATE_SIZE, "TEX/tex-0", 0, 0); ALLOC_STATE_IDX( tex[1], tex1, TEX_STATE_SIZE, "TEX/tex-1", 0, 1); ALLOC_STATE_IDX( tex[2], tex2, TEX_STATE_SIZE, "TEX/tex-2", 0, 2); ALLOC_STATE( mat[0], tcl, MAT_STATE_SIZE, "MAT/modelproject", 1 ); ALLOC_STATE( mat[1], tcl_eyespace_or_fog, MAT_STATE_SIZE, "MAT/modelview", 1 ); ALLOC_STATE( mat[2], tcl_eyespace_or_lighting, MAT_STATE_SIZE, "MAT/it-modelview", 1 ); ALLOC_STATE( mat[3], tcl_tex0, MAT_STATE_SIZE, "MAT/texmat0", 1 ); ALLOC_STATE( mat[4], tcl_tex1, MAT_STATE_SIZE, "MAT/texmat1", 1 ); ALLOC_STATE( mat[5], tcl_tex2, MAT_STATE_SIZE, "MAT/texmat2", 1 ); ALLOC_STATE( lit[0], tcl_lit0, LIT_STATE_SIZE, "LIT/light-0", 1 ); ALLOC_STATE( lit[1], tcl_lit1, LIT_STATE_SIZE, "LIT/light-1", 1 ); ALLOC_STATE( lit[2], tcl_lit2, LIT_STATE_SIZE, "LIT/light-2", 1 ); ALLOC_STATE( lit[3], tcl_lit3, LIT_STATE_SIZE, "LIT/light-3", 1 ); ALLOC_STATE( lit[4], tcl_lit4, LIT_STATE_SIZE, "LIT/light-4", 1 ); ALLOC_STATE( lit[5], tcl_lit5, LIT_STATE_SIZE, "LIT/light-5", 1 ); ALLOC_STATE( lit[6], tcl_lit6, LIT_STATE_SIZE, "LIT/light-6", 1 ); ALLOC_STATE( lit[7], tcl_lit7, LIT_STATE_SIZE, "LIT/light-7", 1 ); ALLOC_STATE( ucp[0], tcl_ucp0, UCP_STATE_SIZE, "UCP/userclip-0", 1 ); ALLOC_STATE( ucp[1], tcl_ucp1, UCP_STATE_SIZE, "UCP/userclip-1", 1 ); ALLOC_STATE( ucp[2], tcl_ucp2, UCP_STATE_SIZE, "UCP/userclip-2", 1 ); ALLOC_STATE( ucp[3], tcl_ucp3, UCP_STATE_SIZE, "UCP/userclip-3", 1 ); ALLOC_STATE( ucp[4], tcl_ucp4, UCP_STATE_SIZE, "UCP/userclip-4", 1 ); ALLOC_STATE( ucp[5], tcl_ucp5, UCP_STATE_SIZE, "UCP/userclip-5", 1 ); } if (rmesa->radeon.radeonScreen->kernel_mm) { ALLOC_STATE( stp, always, STP_STATE_SIZE, "STP/stp", 0 ); } for (i = 0; i < 3; i++) { if (rmesa->radeon.radeonScreen->kernel_mm) rmesa->hw.tex[i].emit = tex_emit_cs; else rmesa->hw.tex[i].emit = tex_emit; } if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR100) { if (rmesa->radeon.radeonScreen->kernel_mm) { ALLOC_STATE_IDX( cube[0], cube0_mm, CUBE_STATE_SIZE, "CUBE/cube-0", 0, 0 ); ALLOC_STATE_IDX( cube[1], cube1_mm, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 ); ALLOC_STATE_IDX( cube[2], cube2_mm, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 ); for (i = 0; i < 3; i++) rmesa->hw.cube[i].emit = cube_emit_cs; } else { ALLOC_STATE_IDX( cube[0], cube0, CUBE_STATE_SIZE, "CUBE/cube-0", 0, 0 ); ALLOC_STATE_IDX( cube[1], cube1, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 ); ALLOC_STATE_IDX( cube[2], cube2, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 ); for (i = 0; i < 3; i++) rmesa->hw.cube[i].emit = cube_emit; } } else { ALLOC_STATE_IDX( cube[0], never, CUBE_STATE_SIZE, "CUBE/cube-0", 0, 0 ); ALLOC_STATE_IDX( cube[1], never, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 ); ALLOC_STATE_IDX( cube[2], never, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 ); } ALLOC_STATE_IDX( txr[0], txr0, TXR_STATE_SIZE, "TXR/txr-0", 0, 0 ); ALLOC_STATE_IDX( txr[1], txr1, TXR_STATE_SIZE, "TXR/txr-1", 0, 1 ); ALLOC_STATE_IDX( txr[2], txr2, TXR_STATE_SIZE, "TXR/txr-2", 0, 2 ); radeonSetUpAtomList( rmesa ); /* Fill in the packet headers: */ rmesa->hw.ctx.cmd[CTX_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_MISC); rmesa->hw.ctx.cmd[CTX_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_CNTL); rmesa->hw.ctx.cmd[CTX_CMD_2] = cmdpkt(rmesa, RADEON_EMIT_RB3D_COLORPITCH); rmesa->hw.lin.cmd[LIN_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_RE_LINE_PATTERN); rmesa->hw.lin.cmd[LIN_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_SE_LINE_WIDTH); rmesa->hw.msk.cmd[MSK_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_RB3D_STENCILREFMASK); rmesa->hw.vpt.cmd[VPT_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_VPORT_XSCALE); rmesa->hw.set.cmd[SET_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_CNTL); rmesa->hw.set.cmd[SET_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_SE_CNTL_STATUS); rmesa->hw.msc.cmd[MSC_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_RE_MISC); rmesa->hw.tex[0].cmd[TEX_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TXFILTER_0); rmesa->hw.tex[0].cmd[TEX_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_BORDER_COLOR_0); rmesa->hw.tex[1].cmd[TEX_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TXFILTER_1); rmesa->hw.tex[1].cmd[TEX_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_BORDER_COLOR_1); rmesa->hw.tex[2].cmd[TEX_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TXFILTER_2); rmesa->hw.tex[2].cmd[TEX_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_BORDER_COLOR_2); rmesa->hw.cube[0].cmd[CUBE_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_FACES_0); rmesa->hw.cube[0].cmd[CUBE_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_OFFSETS_T0); rmesa->hw.cube[1].cmd[CUBE_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_FACES_1); rmesa->hw.cube[1].cmd[CUBE_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_OFFSETS_T1); rmesa->hw.cube[2].cmd[CUBE_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_FACES_2); rmesa->hw.cube[2].cmd[CUBE_CMD_1] = cmdpkt(rmesa, RADEON_EMIT_PP_CUBIC_OFFSETS_T2); rmesa->hw.zbs.cmd[ZBS_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_ZBIAS_FACTOR); rmesa->hw.tcl.cmd[TCL_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT); rmesa->hw.mtl.cmd[MTL_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED); rmesa->hw.txr[0].cmd[TXR_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TEX_SIZE_0); rmesa->hw.txr[1].cmd[TXR_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TEX_SIZE_1); rmesa->hw.txr[2].cmd[TXR_CMD_0] = cmdpkt(rmesa, RADEON_EMIT_PP_TEX_SIZE_2); rmesa->hw.grd.cmd[GRD_CMD_0] = cmdscl( RADEON_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 ); rmesa->hw.fog.cmd[FOG_CMD_0] = cmdvec( RADEON_VS_FOG_PARAM_ADDR, 1, 4 ); rmesa->hw.glt.cmd[GLT_CMD_0] = cmdvec( RADEON_VS_GLOBAL_AMBIENT_ADDR, 1, 4 ); rmesa->hw.eye.cmd[EYE_CMD_0] = cmdvec( RADEON_VS_EYE_VECTOR_ADDR, 1, 4 ); for (i = 0 ; i < 6; i++) { rmesa->hw.mat[i].cmd[MAT_CMD_0] = cmdvec( RADEON_VS_MATRIX_0_ADDR + i*4, 1, 16); } for (i = 0 ; i < 8; i++) { rmesa->hw.lit[i].cmd[LIT_CMD_0] = cmdvec( RADEON_VS_LIGHT_AMBIENT_ADDR + i, 8, 24 ); rmesa->hw.lit[i].cmd[LIT_CMD_1] = cmdscl( RADEON_SS_LIGHT_DCD_ADDR + i, 8, 6 ); } for (i = 0 ; i < 6; i++) { rmesa->hw.ucp[i].cmd[UCP_CMD_0] = cmdvec( RADEON_VS_UCP_ADDR + i, 1, 4 ); } if (rmesa->radeon.radeonScreen->kernel_mm) { rmesa->hw.stp.cmd[STP_CMD_0] = CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0); rmesa->hw.stp.cmd[STP_DATA_0] = 0; rmesa->hw.stp.cmd[STP_CMD_1] = CP_PACKET0_ONE(RADEON_RE_STIPPLE_DATA, 31); rmesa->hw.grd.emit = scl_emit; rmesa->hw.fog.emit = vec_emit; rmesa->hw.glt.emit = vec_emit; rmesa->hw.eye.emit = vec_emit; for (i = 0; i < 6; i++) rmesa->hw.mat[i].emit = vec_emit; for (i = 0; i < 8; i++) rmesa->hw.lit[i].emit = lit_emit; for (i = 0; i < 6; i++) rmesa->hw.ucp[i].emit = vec_emit; } rmesa->last_ReallyEnabled = -1; /* Initial Harware state: */ rmesa->hw.ctx.cmd[CTX_PP_MISC] = (RADEON_ALPHA_TEST_PASS | RADEON_CHROMA_FUNC_FAIL | RADEON_CHROMA_KEY_NEAREST | RADEON_SHADOW_FUNC_EQUAL | RADEON_SHADOW_PASS_1 /*| RADEON_RIGHT_HAND_CUBE_OGL */); rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] = (RADEON_FOG_VERTEX | /* this bit unused for vertex fog */ RADEON_FOG_USE_DEPTH); rmesa->hw.ctx.cmd[CTX_RE_SOLID_COLOR] = 0x00000000; rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = (RADEON_COMB_FCN_ADD_CLAMP | RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ZERO ); rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] = (RADEON_Z_TEST_LESS | RADEON_STENCIL_TEST_ALWAYS | RADEON_STENCIL_FAIL_KEEP | RADEON_STENCIL_ZPASS_KEEP | RADEON_STENCIL_ZFAIL_KEEP | RADEON_Z_WRITE_ENABLE); if (rmesa->using_hyperz) { rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_COMPRESSION_ENABLE | RADEON_Z_DECOMPRESSION_ENABLE; if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { /* works for q3, but slight rendering errors with glxgears ? */ /* rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_Z_HIERARCHY_ENABLE;*/ /* need this otherwise get lots of lockups with q3 ??? */ rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] |= RADEON_FORCE_Z_DIRTY; } } rmesa->hw.ctx.cmd[CTX_PP_CNTL] = (RADEON_SCISSOR_ENABLE | RADEON_ANTI_ALIAS_NONE); rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] = (RADEON_PLANE_MASK_ENABLE | RADEON_ZBLOCK16); switch ( driQueryOptioni( &rmesa->radeon.optionCache, "dither_mode" ) ) { case DRI_CONF_DITHER_XERRORDIFFRESET: rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_INIT; break; case DRI_CONF_DITHER_ORDERED: rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_SCALE_DITHER_ENABLE; break; } if ( driQueryOptioni( &rmesa->radeon.optionCache, "round_mode" ) == DRI_CONF_ROUND_ROUND ) rmesa->radeon.state.color.roundEnable = RADEON_ROUND_ENABLE; else rmesa->radeon.state.color.roundEnable = 0; if ( driQueryOptioni (&rmesa->radeon.optionCache, "color_reduction" ) == DRI_CONF_COLOR_REDUCTION_DITHER ) rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_DITHER_ENABLE; else rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= rmesa->radeon.state.color.roundEnable; rmesa->hw.set.cmd[SET_SE_CNTL] = (RADEON_FFACE_CULL_CCW | RADEON_BFACE_SOLID | RADEON_FFACE_SOLID | /* RADEON_BADVTX_CULL_DISABLE | */ RADEON_FLAT_SHADE_VTX_LAST | RADEON_DIFFUSE_SHADE_GOURAUD | RADEON_ALPHA_SHADE_GOURAUD | RADEON_SPECULAR_SHADE_GOURAUD | RADEON_FOG_SHADE_GOURAUD | RADEON_VPORT_XY_XFORM_ENABLE | RADEON_VPORT_Z_XFORM_ENABLE | RADEON_VTX_PIX_CENTER_OGL | RADEON_ROUND_MODE_TRUNC | RADEON_ROUND_PREC_8TH_PIX); rmesa->hw.set.cmd[SET_SE_CNTL_STATUS] = #ifdef MESA_BIG_ENDIAN RADEON_VC_32BIT_SWAP; #else RADEON_VC_NO_SWAP; #endif if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) { rmesa->hw.set.cmd[SET_SE_CNTL_STATUS] |= RADEON_TCL_BYPASS; } rmesa->hw.set.cmd[SET_SE_COORDFMT] = ( RADEON_VTX_W0_IS_NOT_1_OVER_W0 | RADEON_TEX1_W_ROUTING_USE_Q1); rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = ((1 << 16) | 0xffff); rmesa->hw.lin.cmd[LIN_RE_LINE_STATE] = ((0 << RADEON_LINE_CURRENT_PTR_SHIFT) | (1 << RADEON_LINE_CURRENT_COUNT_SHIFT)); rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] = (1 << 4); rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] = ((0x00 << RADEON_STENCIL_REF_SHIFT) | (0xff << RADEON_STENCIL_MASK_SHIFT) | (0xff << RADEON_STENCIL_WRITEMASK_SHIFT)); rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = RADEON_ROP_COPY; rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] = 0xffffffff; rmesa->hw.msc.cmd[MSC_RE_MISC] = ((0 << RADEON_STIPPLE_X_OFFSET_SHIFT) | (0 << RADEON_STIPPLE_Y_OFFSET_SHIFT) | RADEON_STIPPLE_BIG_BIT_ORDER); rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = 0x00000000; rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = 0x00000000; rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = 0x00000000; rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = 0x00000000; rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = 0x00000000; rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = 0x00000000; for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] = RADEON_BORDER_MODE_OGL; rmesa->hw.tex[i].cmd[TEX_PP_TXFORMAT] = (RADEON_TXFORMAT_ENDIAN_NO_SWAP | RADEON_TXFORMAT_PERSPECTIVE_ENABLE | (i << 24) | /* This is one of RADEON_TXFORMAT_ST_ROUTE_STQ[012] */ (2 << RADEON_TXFORMAT_WIDTH_SHIFT) | (2 << RADEON_TXFORMAT_HEIGHT_SHIFT)); /* Initialize the texture offset to the start of the card texture heap */ // rmesa->hw.tex[i].cmd[TEX_PP_TXOFFSET] = // rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; rmesa->hw.tex[i].cmd[TEX_PP_BORDER_COLOR] = 0; rmesa->hw.tex[i].cmd[TEX_PP_TXCBLEND] = (RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD | RADEON_SCALE_1X | RADEON_CLAMP_TX); rmesa->hw.tex[i].cmd[TEX_PP_TXABLEND] = (RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD | RADEON_SCALE_1X | RADEON_CLAMP_TX); rmesa->hw.tex[i].cmd[TEX_PP_TFACTOR] = 0; rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_FACES] = 0; rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_0] = rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_1] = rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_2] = rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_3] = rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; rmesa->hw.cube[i].cmd[CUBE_PP_CUBIC_OFFSET_4] = rmesa->radeon.radeonScreen->texOffset[RADEON_LOCAL_TEX_HEAP]; } /* Can only add ST1 at the time of doing some multitex but can keep * it after that. Errors if DIFFUSE is missing. */ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = (RADEON_TCL_VTX_Z0 | RADEON_TCL_VTX_W0 | RADEON_TCL_VTX_PK_DIFFUSE ); /* need to keep this uptodate */ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = ( RADEON_TCL_COMPUTE_XYZW | (RADEON_TCL_TEX_INPUT_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) | (RADEON_TCL_TEX_INPUT_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) | (RADEON_TCL_TEX_INPUT_TEX_2 << RADEON_TCL_TEX_2_OUTPUT_SHIFT)); /* XXX */ rmesa->hw.tcl.cmd[TCL_MATRIX_SELECT_0] = ((MODEL << RADEON_MODELVIEW_0_SHIFT) | (MODEL_IT << RADEON_IT_MODELVIEW_0_SHIFT)); rmesa->hw.tcl.cmd[TCL_MATRIX_SELECT_1] = ((MODEL_PROJ << RADEON_MODELPROJECT_0_SHIFT) | (TEXMAT_0 << RADEON_TEXMAT_0_SHIFT) | (TEXMAT_1 << RADEON_TEXMAT_1_SHIFT) | (TEXMAT_2 << RADEON_TEXMAT_2_SHIFT)); rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] = (RADEON_UCP_IN_CLIP_SPACE | RADEON_CULL_FRONT_IS_CCW); rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = 0; rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = (RADEON_SPECULAR_LIGHTS | RADEON_DIFFUSE_SPECULAR_COMBINE | RADEON_LOCAL_LIGHT_VEC_GL | (RADEON_LM_SOURCE_STATE_MULT << RADEON_EMISSIVE_SOURCE_SHIFT) | (RADEON_LM_SOURCE_STATE_MULT << RADEON_AMBIENT_SOURCE_SHIFT) | (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) | (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT)); for (i = 0 ; i < 8; i++) { struct gl_light *l = &ctx->Light.Light[i]; GLenum p = GL_LIGHT0 + i; *(float *)&(rmesa->hw.lit[i].cmd[LIT_RANGE_CUTOFF]) = FLT_MAX; ctx->Driver.Lightfv( ctx, p, GL_AMBIENT, l->Ambient ); ctx->Driver.Lightfv( ctx, p, GL_DIFFUSE, l->Diffuse ); ctx->Driver.Lightfv( ctx, p, GL_SPECULAR, l->Specular ); ctx->Driver.Lightfv( ctx, p, GL_POSITION, NULL ); ctx->Driver.Lightfv( ctx, p, GL_SPOT_DIRECTION, NULL ); ctx->Driver.Lightfv( ctx, p, GL_SPOT_EXPONENT, &l->SpotExponent ); ctx->Driver.Lightfv( ctx, p, GL_SPOT_CUTOFF, &l->SpotCutoff ); ctx->Driver.Lightfv( ctx, p, GL_CONSTANT_ATTENUATION, &l->ConstantAttenuation ); ctx->Driver.Lightfv( ctx, p, GL_LINEAR_ATTENUATION, &l->LinearAttenuation ); ctx->Driver.Lightfv( ctx, p, GL_QUADRATIC_ATTENUATION, &l->QuadraticAttenuation ); *(float *)&(rmesa->hw.lit[i].cmd[LIT_ATTEN_XXX]) = 0.0; } ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_AMBIENT, ctx->Light.Model.Ambient ); TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx ); for (i = 0 ; i < 6; i++) { ctx->Driver.ClipPlane( ctx, GL_CLIP_PLANE0 + i, NULL ); } ctx->Driver.Fogfv( ctx, GL_FOG_MODE, NULL ); ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); ctx->Driver.Fogfv( ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL ); rmesa->hw.grd.cmd[GRD_VERT_GUARD_CLIP_ADJ] = IEEE_ONE; rmesa->hw.grd.cmd[GRD_VERT_GUARD_DISCARD_ADJ] = IEEE_ONE; rmesa->hw.grd.cmd[GRD_HORZ_GUARD_CLIP_ADJ] = IEEE_ONE; rmesa->hw.grd.cmd[GRD_HORZ_GUARD_DISCARD_ADJ] = IEEE_ONE; rmesa->hw.eye.cmd[EYE_X] = 0; rmesa->hw.eye.cmd[EYE_Y] = 0; rmesa->hw.eye.cmd[EYE_Z] = IEEE_ONE; rmesa->hw.eye.cmd[EYE_RESCALE_FACTOR] = IEEE_ONE; if (rmesa->radeon.radeonScreen->kernel_mm) { radeon_init_query_stateobj(&rmesa->radeon, R100_QUERYOBJ_CMDSIZE); rmesa->radeon.query.queryobj.cmd[R100_QUERYOBJ_CMD_0] = CP_PACKET0(RADEON_RB3D_ZPASS_DATA, 0); rmesa->radeon.query.queryobj.cmd[R100_QUERYOBJ_DATA_0] = 0; } rmesa->radeon.hw.all_dirty = GL_TRUE; rcommonInitCmdBuf(&rmesa->radeon); }
static void texgen( GLcontext *ctx, struct texgen_stage_data *store, GLuint unit ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLvector4f *in = VB->AttribPtr[VERT_ATTRIB_TEX0 + unit]; GLvector4f *out = &store->texcoord[unit]; const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; const GLvector4f *obj = VB->AttribPtr[_TNL_ATTRIB_POS]; const GLvector4f *eye = VB->EyePtr; const GLvector4f *normal = VB->AttribPtr[_TNL_ATTRIB_NORMAL]; const GLfloat *m = store->tmp_m; const GLuint count = VB->Count; GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->data; GLfloat (*f)[3] = store->tmp_f; GLuint copy; if (texUnit->_GenFlags & TEXGEN_NEED_M) { build_m_tab[eye->size]( store->tmp_f, store->tmp_m, normal, eye ); } else if (texUnit->_GenFlags & TEXGEN_NEED_F) { build_f_tab[eye->size]( (GLfloat *)store->tmp_f, 3, normal, eye ); } out->size = MAX2(in->size, store->TexgenSize[unit]); out->flags |= (in->flags & VEC_SIZE_FLAGS) | texUnit->TexGenEnabled; out->count = count; copy = (all_bits[in->size] & ~texUnit->TexGenEnabled); if (copy) _mesa_copy_tab[copy]( out, in ); if (texUnit->TexGenEnabled & S_BIT) { GLuint i; switch (texUnit->GenS.Mode) { case GL_OBJECT_LINEAR: _mesa_dotprod_tab[obj->size]( (GLfloat *)out->data, sizeof(out->data[0]), obj, texUnit->GenS.ObjectPlane ); break; case GL_EYE_LINEAR: _mesa_dotprod_tab[eye->size]( (GLfloat *)out->data, sizeof(out->data[0]), eye, texUnit->GenS.EyePlane ); break; case GL_SPHERE_MAP: for (i = 0; i < count; i++) texcoord[i][0] = f[i][0] * m[i] + 0.5F; break; case GL_REFLECTION_MAP_NV: for (i=0;i<count;i++) texcoord[i][0] = f[i][0]; break; case GL_NORMAL_MAP_NV: { const GLfloat *norm = normal->start; for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) { texcoord[i][0] = norm[0]; } break; } default: _mesa_problem(ctx, "Bad S texgen"); } } if (texUnit->TexGenEnabled & T_BIT) { GLuint i; switch (texUnit->GenT.Mode) { case GL_OBJECT_LINEAR: _mesa_dotprod_tab[obj->size]( &(out->data[0][1]), sizeof(out->data[0]), obj, texUnit->GenT.ObjectPlane ); break; case GL_EYE_LINEAR: _mesa_dotprod_tab[eye->size]( &(out->data[0][1]), sizeof(out->data[0]), eye, texUnit->GenT.EyePlane ); break; case GL_SPHERE_MAP: for (i = 0; i < count; i++) texcoord[i][1] = f[i][1] * m[i] + 0.5F; break; case GL_REFLECTION_MAP_NV: for (i=0;i<count;i++) texcoord[i][1] = f[i][1]; break; case GL_NORMAL_MAP_NV: { const GLfloat *norm = normal->start; for (i=0;i<count;i++, STRIDE_F(norm, normal->stride)) { texcoord[i][1] = norm[1]; } break; } default: _mesa_problem(ctx, "Bad T texgen"); } } if (texUnit->TexGenEnabled & R_BIT) { GLuint i; switch (texUnit->GenR.Mode) { case GL_OBJECT_LINEAR: _mesa_dotprod_tab[obj->size]( &(out->data[0][2]), sizeof(out->data[0]), obj, texUnit->GenR.ObjectPlane ); break; case GL_EYE_LINEAR: _mesa_dotprod_tab[eye->size]( &(out->data[0][2]), sizeof(out->data[0]), eye, texUnit->GenR.EyePlane ); break; case GL_REFLECTION_MAP_NV: for (i=0;i<count;i++) texcoord[i][2] = f[i][2]; break; case GL_NORMAL_MAP_NV: { const GLfloat *norm = normal->start; for (i=0;i<count;i++,STRIDE_F(norm, normal->stride)) { texcoord[i][2] = norm[2]; } break; } default: _mesa_problem(ctx, "Bad R texgen"); } } if (texUnit->TexGenEnabled & Q_BIT) { switch (texUnit->GenQ.Mode) { case GL_OBJECT_LINEAR: _mesa_dotprod_tab[obj->size]( &(out->data[0][3]), sizeof(out->data[0]), obj, texUnit->GenQ.ObjectPlane ); break; case GL_EYE_LINEAR: _mesa_dotprod_tab[eye->size]( &(out->data[0][3]), sizeof(out->data[0]), eye, texUnit->GenQ.EyePlane ); break; default: _mesa_problem(ctx, "Bad Q texgen"); } } }
/** * Tell the tnl module how to build SWvertex objects for swrast. * We'll build the map[] array with that info and pass it to * _tnl_install_attrs(). */ static void setup_vertex_format(GLcontext *ctx) { TNLcontext *tnl = TNL_CONTEXT(ctx); SScontext *swsetup = SWSETUP_CONTEXT(ctx); GLboolean intColors = !ctx->FragmentProgram._Current && !ctx->ATIFragmentShader._Enabled && ctx->RenderMode == GL_RENDER && CHAN_TYPE != GL_FLOAT; if (intColors != swsetup->intColors || !RENDERINPUTS_EQUAL(tnl->render_inputs_bitset, swsetup->last_index_bitset)) { DECLARE_RENDERINPUTS(index_bitset); struct tnl_attr_map map[_TNL_ATTRIB_MAX]; unsigned int i, e = 0; swsetup->intColors = intColors; RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset ); EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, attrib[FRAG_ATTRIB_WPOS] ); if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR0 )) { if (swsetup->intColors) EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color ); else EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F, attrib[FRAG_ATTRIB_COL0]); } if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) { EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F, attrib[FRAG_ATTRIB_COL1]); } if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) { const GLint emit = ctx->FragmentProgram._Current ? EMIT_4F : EMIT_1F; EMIT_ATTR( _TNL_ATTRIB_FOG, emit, attrib[FRAG_ATTRIB_FOGC]); } if (RENDERINPUTS_TEST_RANGE(index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX)) { for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) { EMIT_ATTR( _TNL_ATTRIB_TEX(i), EMIT_4F, attrib[FRAG_ATTRIB_TEX0 + i] ); } } } /* shader varying vars */ if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_GENERIC, _TNL_LAST_GENERIC )) { for (i = 0; i < ctx->Const.MaxVarying; i++) { if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_GENERIC(i) )) { EMIT_ATTR( _TNL_ATTRIB_GENERIC(i), VARYING_EMIT_STYLE, attrib[FRAG_ATTRIB_VAR0 + i] ); } } } if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, pointSize ); _tnl_install_attrs( ctx, map, e, ctx->Viewport._WindowMap.m, sizeof(SWvertex) ); RENDERINPUTS_COPY( swsetup->last_index_bitset, index_bitset ); } }
static void radeonSetVertexFormat( struct gl_context *ctx ) { r100ContextPtr rmesa = R100_CONTEXT( ctx ); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLbitfield64 index_bitset = tnl->render_inputs_bitset; int fmt_0 = 0; int offset = 0; /* Important: */ if ( VB->NdcPtr != NULL ) { VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; } else { VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr; } assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL ); rmesa->radeon.swtcl.vertex_attr_count = 0; /* EMIT_ATTR's must be in order as they tell t_vertex.c how to * build up a hardware vertex. */ if ( !rmesa->swtcl.needproj || (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX))) { /* for projtex */ EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F, RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_Z | RADEON_CP_VC_FRMT_W0 ); offset = 4; } else { EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F, RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_Z ); offset = 3; } rmesa->swtcl.coloroffset = offset; #if MESA_LITTLE_ENDIAN EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA, RADEON_CP_VC_FRMT_PKCOLOR ); #else EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR, RADEON_CP_VC_FRMT_PKCOLOR ); #endif offset += 1; rmesa->swtcl.specoffset = 0; if (index_bitset & (BITFIELD64_BIT(_TNL_ATTRIB_COLOR1) | BITFIELD64_BIT(_TNL_ATTRIB_FOG))) { #if MESA_LITTLE_ENDIAN if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) { rmesa->swtcl.specoffset = offset; EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB, RADEON_CP_VC_FRMT_PKSPEC ); } else { EMIT_PAD( 3 ); } if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) { EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, RADEON_CP_VC_FRMT_PKSPEC ); } else { EMIT_PAD( 1 ); } #else if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) { EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, RADEON_CP_VC_FRMT_PKSPEC ); } else { EMIT_PAD( 1 ); } if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) { rmesa->swtcl.specoffset = offset; EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, RADEON_CP_VC_FRMT_PKSPEC ); } else { EMIT_PAD( 3 ); } #endif } if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) { int i; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_TEX(i))) { GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size; switch (sz) { case 1: case 2: EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_2F, radeon_cp_vc_frmts[i][0] ); break; case 3: if (ctx->Texture.Unit[i]._Current && ctx->Texture.Unit[i]._Current->Target == GL_TEXTURE_CUBE_MAP) { EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_3F, radeon_cp_vc_frmts[i][1] ); } else { EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_2F, radeon_cp_vc_frmts[i][0] ); } break; case 4: if (ctx->Texture.Unit[i]._Current && ctx->Texture.Unit[i]._Current->Target == GL_TEXTURE_CUBE_MAP) { EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_3F, radeon_cp_vc_frmts[i][1] ); } else { EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_3F_XYW, radeon_cp_vc_frmts[i][1] ); } break; default: continue; }; } } } if (rmesa->radeon.tnl_index_bitset != index_bitset || fmt_0 != rmesa->swtcl.vertex_format) { RADEON_NEWPRIM(rmesa); rmesa->swtcl.vertex_format = fmt_0; rmesa->radeon.swtcl.vertex_size = _tnl_install_attrs( ctx, rmesa->radeon.swtcl.vertex_attrs, rmesa->radeon.swtcl.vertex_attr_count, NULL, 0 ); rmesa->radeon.swtcl.vertex_size /= 4; rmesa->radeon.tnl_index_bitset = index_bitset; radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s: vertex_size= %d floats\n", __func__, rmesa->radeon.swtcl.vertex_size); } }
GLboolean i830CreateContext(const __GLcontextModes * mesaVis, __DRIcontext * driContextPriv, void *sharedContextPrivate) { struct dd_function_table functions; struct i830_context *i830 = CALLOC_STRUCT(i830_context); struct intel_context *intel = &i830->intel; GLcontext *ctx = &intel->ctx; if (!i830) return GL_FALSE; i830InitVtbl(i830); i830InitDriverFunctions(&functions); if (!intelInitContext(intel, mesaVis, driContextPriv, sharedContextPrivate, &functions)) { FREE(i830); return GL_FALSE; } _math_matrix_ctr(&intel->ViewportMatrix); /* Initialize swrast, tnl driver tables: */ intelInitSpanFuncs(ctx); intelInitTriFuncs(ctx); /* Install the customized pipeline: */ _tnl_destroy_pipeline(ctx); _tnl_install_pipeline(ctx, intel_pipeline); if (intel->no_rast) FALLBACK(intel, INTEL_FALLBACK_USER, 1); intel->ctx.Const.MaxTextureUnits = I830_TEX_UNITS; intel->ctx.Const.MaxTextureImageUnits = I830_TEX_UNITS; intel->ctx.Const.MaxTextureCoordUnits = I830_TEX_UNITS; /* Advertise the full hardware capabilities. The new memory * manager should cope much better with overload situations: */ ctx->Const.MaxTextureLevels = 12; ctx->Const.Max3DTextureLevels = 9; ctx->Const.MaxCubeTextureLevels = 11; ctx->Const.MaxTextureRectSize = (1 << 11); ctx->Const.MaxTextureUnits = I830_TEX_UNITS; ctx->Const.MaxTextureMaxAnisotropy = 2.0; ctx->Const.MaxDrawBuffers = 1; _tnl_init_vertices(ctx, ctx->Const.MaxArrayLockSize + 12, 18 * sizeof(GLfloat)); intel->verts = TNL_CONTEXT(ctx)->clipspace.vertex_buf; i830InitState(i830); _tnl_allow_vertex_fog(ctx, 1); _tnl_allow_pixel_fog(ctx, 0); return GL_TRUE; }
/* TCL render. */ static GLboolean radeon_run_tcl_render( GLcontext *ctx, struct tnl_pipeline_stage *stage ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint inputs = VERT_BIT_POS | VERT_BIT_COLOR0; GLuint i; /* TODO: separate this from the swtnl pipeline */ if (rmesa->radeon.TclFallback) return GL_TRUE; /* fallback to software t&l */ if (VB->Count == 0) return GL_FALSE; /* NOTE: inputs != tnl->render_inputs - these are the untransformed * inputs. */ if (ctx->Light.Enabled) { inputs |= VERT_BIT_NORMAL; } if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { inputs |= VERT_BIT_COLOR1; } if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) { inputs |= VERT_BIT_FOG; } for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { /* TODO: probably should not emit texture coords when texgen is enabled */ if (rmesa->TexGenNeedNormals[i]) { inputs |= VERT_BIT_NORMAL; } inputs |= VERT_BIT_TEX(i); } } radeonReleaseArrays( ctx, ~0 ); GLuint emit_end = radeonEnsureEmitSize( ctx, inputs ) + rmesa->radeon.cmdbuf.cs->cdw; radeonEmitArrays( ctx, inputs ); rmesa->tcl.Elts = VB->Elts; for (i = 0 ; i < VB->PrimitiveCount ; i++) { GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; if (!length) continue; if (rmesa->tcl.Elts) radeonEmitEltPrimitive( ctx, start, start+length, prim ); else radeonEmitPrimitive( ctx, start, start+length, prim ); } if (emit_end < rmesa->radeon.cmdbuf.cs->cdw) WARN_ONCE("Rendering was %d commands larger than predicted size." " We might overflow command buffer.\n", rmesa->radeon.cmdbuf.cs->cdw - emit_end); return GL_FALSE; /* finished the pipe */ }
/* TCL render. */ static GLboolean r200_run_tcl_render( GLcontext *ctx, struct tnl_pipeline_stage *stage ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint i; GLubyte *vimap_rev; /* use hw fixed order for simplicity, pos 0, weight 1, normal 2, fog 3, color0 - color3 4-7, texcoord0 - texcoord5 8-13, pos 1 14. Must not use more than 12 of those at the same time. */ GLubyte map_rev_fixed[15] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; /* TODO: separate this from the swtnl pipeline */ if (rmesa->radeon.TclFallback) return GL_TRUE; /* fallback to software t&l */ radeon_print(RADEON_RENDER, RADEON_NORMAL, "%s\n", __FUNCTION__); if (VB->Count == 0) return GL_FALSE; /* Validate state: */ if (rmesa->radeon.NewGLState) if (!r200ValidateState( ctx )) return GL_TRUE; /* fallback to sw t&l */ if (!ctx->VertexProgram._Enabled) { /* NOTE: inputs != tnl->render_inputs - these are the untransformed * inputs. */ map_rev_fixed[0] = VERT_ATTRIB_POS; /* technically there is no reason we always need VA_COLOR0. In theory could disable it depending on lighting, color materials, texturing... */ map_rev_fixed[4] = VERT_ATTRIB_COLOR0; if (ctx->Light.Enabled) { map_rev_fixed[2] = VERT_ATTRIB_NORMAL; } /* this also enables VA_COLOR1 when using separate specular lighting model, which is unnecessary. FIXME: OTOH, we're missing the case where a ATI_fragment_shader accesses the secondary color (if lighting is disabled). The chip seems misconfigured for that though elsewhere (tcl output, might lock up) */ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { map_rev_fixed[5] = VERT_ATTRIB_COLOR1; } if ( (ctx->Fog.FogCoordinateSource == GL_FOG_COORD) && ctx->Fog.Enabled ) { map_rev_fixed[3] = VERT_ATTRIB_FOG; } for (i = 0 ; i < ctx->Const.MaxTextureUnits; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled) { if (rmesa->TexGenNeedNormals[i]) { map_rev_fixed[2] = VERT_ATTRIB_NORMAL; } map_rev_fixed[8 + i] = VERT_ATTRIB_TEX0 + i; } } vimap_rev = &map_rev_fixed[0]; } else { /* vtx_tcl_output_vtxfmt_0/1 need to match configuration of "fragment part", since using some vertex interpolator later which is not in out_vtxfmt0/1 will lock up. It seems to be ok to write in vertex prog to a not enabled output however, so just don't mess with it. We only need to change compsel. */ GLuint out_compsel = 0; const GLbitfield64 vp_out = rmesa->curr_vp_hw->mesa_program.Base.OutputsWritten; vimap_rev = &rmesa->curr_vp_hw->inputmap_rev[0]; assert(vp_out & BITFIELD64_BIT(VERT_RESULT_HPOS)); out_compsel = R200_OUTPUT_XYZW; if (vp_out & BITFIELD64_BIT(VERT_RESULT_COL0)) { out_compsel |= R200_OUTPUT_COLOR_0; } if (vp_out & BITFIELD64_BIT(VERT_RESULT_COL1)) { out_compsel |= R200_OUTPUT_COLOR_1; } if (vp_out & BITFIELD64_BIT(VERT_RESULT_FOGC)) { out_compsel |= R200_OUTPUT_DISCRETE_FOG; } if (vp_out & BITFIELD64_BIT(VERT_RESULT_PSIZ)) { out_compsel |= R200_OUTPUT_PT_SIZE; } for (i = VERT_RESULT_TEX0; i < VERT_RESULT_TEX6; i++) { if (vp_out & BITFIELD64_BIT(i)) { out_compsel |= R200_OUTPUT_TEX_0 << (i - VERT_RESULT_TEX0); } } if (rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] != out_compsel) { R200_STATECHANGE( rmesa, vtx ); rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] = out_compsel; } } /* Do the actual work: */ radeonReleaseArrays( ctx, ~0 /* stage->changed_inputs */ ); GLuint emit_end = r200EnsureEmitSize( ctx, vimap_rev ) + rmesa->radeon.cmdbuf.cs->cdw; r200EmitArrays( ctx, vimap_rev ); for (i = 0 ; i < VB->PrimitiveCount ; i++) { GLuint prim = _tnl_translate_prim(&VB->Primitive[i]); GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; if (!length) continue; if (VB->Elts) r200EmitEltPrimitive( ctx, start, start+length, prim ); else r200EmitPrimitive( ctx, start, start+length, prim ); } if ( emit_end < rmesa->radeon.cmdbuf.cs->cdw ) WARN_ONCE("Rendering was %d commands larger than predicted size." " We might overflow command buffer.\n", rmesa->radeon.cmdbuf.cs->cdw - emit_end); return GL_FALSE; /* finished the pipe */ }
/** * This is where the vertex data is transfered from the 'struct immediate * into the 'struct vertex_buffer'. * * Note: The 'start' member of the GLvector structs is now redundant * because we always re-transform copied vertices, and the vectors * below are set up so that the first copied vertex (if any) appears * at position zero. */ static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; struct vertex_arrays *tmp = &tnl->imm_inputs; GLuint inputs = tnl->pipeline.inputs; /* for copy-to-current */ const GLuint start = IM->CopyStart; const GLuint count = IM->Count - start; /* TODO: optimize the case where nothing has changed. (Just bind * tmp to vb). */ /* Setup constant data in the VB. */ VB->Count = count; VB->FirstClipped = IMM_MAXDATA - IM->CopyStart; VB->import_data = NULL; VB->importable_data = 0; /* Need an IM->FirstPrimitive? */ VB->Primitive = IM->Primitive + IM->CopyStart; VB->PrimitiveLength = IM->PrimitiveLength + IM->CopyStart; VB->FirstPrimitive = 0; VB->Flag = IM->Flag + start; /* TexCoordPtr's are zeroed in loop below. */ VB->NormalPtr = NULL; VB->NormalLengthPtr = NULL; VB->EdgeFlag = NULL; VB->IndexPtr[0] = NULL; VB->IndexPtr[1] = NULL; VB->ColorPtr[0] = NULL; VB->ColorPtr[1] = NULL; VB->SecondaryColorPtr[0] = NULL; VB->SecondaryColorPtr[1] = NULL; VB->Elts = NULL; VB->MaterialMask = NULL; VB->Material = NULL; /* _tnl_print_vert_flags("copy-orflag", IM->CopyOrFlag); */ /* _tnl_print_vert_flags("orflag", IM->OrFlag); */ /* _tnl_print_vert_flags("inputs", inputs); */ /* Setup the initial values of array pointers in the vb. */ if (inputs & VERT_BIT_POS) { tmp->Obj.data = IM->Attrib[VERT_ATTRIB_POS] + start; tmp->Obj.start = (GLfloat *)(IM->Attrib[VERT_ATTRIB_POS] + start); tmp->Obj.count = count; VB->ObjPtr = &tmp->Obj; if ((IM->CopyOrFlag & VERT_BITS_OBJ_234) == VERT_BITS_OBJ_234) tmp->Obj.size = 4; else if ((IM->CopyOrFlag & VERT_BITS_OBJ_234) == VERT_BITS_OBJ_23) tmp->Obj.size = 3; else tmp->Obj.size = 2; } if (inputs & VERT_BIT_NORMAL) { tmp->Normal.data = IM->Attrib[VERT_ATTRIB_NORMAL] + start; tmp->Normal.start = (GLfloat *) (IM->Attrib[VERT_ATTRIB_NORMAL] + start); tmp->Normal.count = count; tmp->Normal.size = 3; /* just to be safe */ VB->NormalPtr = &tmp->Normal; if (IM->NormalLengthPtr) VB->NormalLengthPtr = IM->NormalLengthPtr + start; } if (inputs & VERT_BIT_INDEX) { tmp->Index.count = count; tmp->Index.data = IM->Index + start; tmp->Index.start = IM->Index + start; VB->IndexPtr[0] = &tmp->Index; } if (inputs & VERT_BIT_FOG) { tmp->FogCoord.data = IM->Attrib[VERT_ATTRIB_FOG] + start; tmp->FogCoord.start = (GLfloat *) (IM->Attrib[VERT_ATTRIB_FOG] + start); tmp->FogCoord.count = count; VB->FogCoordPtr = &tmp->FogCoord; } if (inputs & VERT_BIT_COLOR1) { tmp->SecondaryColor.Ptr = IM->Attrib[VERT_ATTRIB_COLOR1] + start; VB->SecondaryColorPtr[0] = &tmp->SecondaryColor; } if (inputs & VERT_BIT_EDGEFLAG) { VB->EdgeFlag = IM->EdgeFlag + start; } if (inputs & VERT_BIT_COLOR0) { if (IM->CopyOrFlag & VERT_BIT_COLOR0) { tmp->Color.Ptr = IM->Attrib[VERT_ATTRIB_COLOR0] + start; tmp->Color.StrideB = 4 * sizeof(GLfloat); tmp->Color.Flags = 0; } else { tmp->Color.Ptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; tmp->Color.StrideB = 0; tmp->Color.Flags = CA_CLIENT_DATA; /* hack */ VB->import_source = IM; VB->importable_data |= VERT_BIT_COLOR0; VB->import_data = _tnl_upgrade_current_data; } VB->ColorPtr[0] = &tmp->Color; } if (inputs & VERT_BITS_TEX_ANY) { GLuint i; for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { VB->TexCoordPtr[i] = NULL; if (inputs & VERT_BIT_TEX(i)) { tmp->TexCoord[i].count = count; tmp->TexCoord[i].data = IM->Attrib[VERT_ATTRIB_TEX0 + i] + start; tmp->TexCoord[i].start = (GLfloat *)(IM->Attrib[VERT_ATTRIB_TEX0 + i] + start); tmp->TexCoord[i].size = 2; if (IM->TexSize & TEX_SIZE_3(i)) { tmp->TexCoord[i].size = 3; if (IM->TexSize & TEX_SIZE_4(i)) tmp->TexCoord[i].size = 4; } VB->TexCoordPtr[i] = &tmp->TexCoord[i]; } } } if ((inputs & IM->OrFlag & VERT_BIT_MATERIAL) && IM->Material) { VB->MaterialMask = IM->MaterialMask + start; VB->Material = IM->Material + start; } /* GL_NV_vertex_program */ if (ctx->VertexProgram.Enabled) { GLuint attr; for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { tmp->Attribs[attr].count = count; tmp->Attribs[attr].data = IM->Attrib[attr] + start; tmp->Attribs[attr].start = (GLfloat *) (IM->Attrib[attr] + start); tmp->Attribs[attr].size = 4; VB->AttribPtr[attr] = &(tmp->Attribs[attr]); } } }
static void i830_render_start(struct intel_context *intel) { struct gl_context *ctx = &intel->ctx; struct i830_context *i830 = i830_context(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLbitfield64 index_bitset = tnl->render_inputs_bitset; GLuint v0 = _3DSTATE_VFT0_CMD; GLuint v2 = _3DSTATE_VFT1_CMD; GLuint mcsb1 = 0; /* Important: */ VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; intel->vertex_attr_count = 0; /* EMIT_ATTR's must be in order as they tell t_vertex.c how to * build up a hardware vertex. */ if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) { EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, VFT0_XYZW); intel->coloroffset = 4; } else { EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, VFT0_XYZ); intel->coloroffset = 3; } if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE)) { EMIT_ATTR(_TNL_ATTRIB_POINTSIZE, EMIT_1F, VFT0_POINT_WIDTH); } EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA, VFT0_DIFFUSE); intel->specoffset = 0; if (index_bitset & (BITFIELD64_BIT(_TNL_ATTRIB_COLOR1) | BITFIELD64_BIT(_TNL_ATTRIB_FOG))) { if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) { intel->specoffset = intel->coloroffset + 1; EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, VFT0_SPEC); } else EMIT_PAD(3); if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F, VFT0_SPEC); else EMIT_PAD(1); } if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) { int i, count = 0; for (i = 0; i < I830_TEX_UNITS; i++) { if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_TEX(i))) { GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size; GLuint emit; GLuint mcs = (i830->state.Tex[i][I830_TEXREG_MCS] & ~TEXCOORDTYPE_MASK); switch (sz) { case 1: case 2: emit = EMIT_2F; sz = 2; mcs |= TEXCOORDTYPE_CARTESIAN; break; case 3: emit = EMIT_3F; sz = 3; mcs |= TEXCOORDTYPE_VECTOR; break; case 4: emit = EMIT_3F_XYW; sz = 3; mcs |= TEXCOORDTYPE_HOMOGENEOUS; break; default: continue; }; EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, emit, 0); v2 |= VRTX_TEX_SET_FMT(count, SZ_TO_HW(sz)); mcsb1 |= (count + 8) << (i * 4); if (mcs != i830->state.Tex[i][I830_TEXREG_MCS]) { I830_STATECHANGE(i830, I830_UPLOAD_TEX(i)); i830->state.Tex[i][I830_TEXREG_MCS] = mcs; } count++; } } v0 |= VFT0_TEX_COUNT(count); } /* Only need to change the vertex emit code if there has been a * statechange to a new hardware vertex format: */ if (v0 != i830->state.Ctx[I830_CTXREG_VF] || v2 != i830->state.Ctx[I830_CTXREG_VF2] || mcsb1 != i830->state.Ctx[I830_CTXREG_MCSB1] || index_bitset != i830->last_index_bitset) { I830_STATECHANGE(i830, I830_UPLOAD_CTX); /* Must do this *after* statechange, so as not to affect * buffered vertices reliant on the old state: */ intel->vertex_size = _tnl_install_attrs(ctx, intel->vertex_attrs, intel->vertex_attr_count, intel->ViewportMatrix.m, 0); intel->vertex_size >>= 2; i830->state.Ctx[I830_CTXREG_VF] = v0; i830->state.Ctx[I830_CTXREG_VF2] = v2; i830->state.Ctx[I830_CTXREG_MCSB1] = mcsb1; i830->last_index_bitset = index_bitset; assert(i830_check_vertex_size(intel, intel->vertex_size)); }
void _tnl_EndList( GLcontext *ctx ) { (void) ctx; assert(TNL_CONTEXT(ctx)->save.vertex_size == 0); }
void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) { TNLcontext *tnl = TNL_CONTEXT(ctx); tnl->Driver.Render.Line( ctx, ii, jj ); }
/* Flush existing data, set new attrib size, replay copied vertices. */ static void _save_upgrade_vertex( GLcontext *ctx, GLuint attr, GLuint newsz ) { TNLcontext *tnl = TNL_CONTEXT(ctx); GLuint oldsz; GLuint i; GLfloat *tmp; /* Store the current run of vertices, and emit a GL_END. Emit a * BEGIN in the new buffer. */ if (tnl->save.initial_counter != tnl->save.counter) _save_wrap_buffers( ctx ); else assert( tnl->save.copied.nr == 0 ); /* Do a COPY_TO_CURRENT to ensure back-copying works for the case * when the attribute already exists in the vertex and is having * its size increased. */ _save_copy_to_current( ctx ); /* Fix up sizes: */ oldsz = tnl->save.attrsz[attr]; tnl->save.attrsz[attr] = newsz; tnl->save.vertex_size += newsz - oldsz; tnl->save.counter = ((SAVE_BUFFER_SIZE - tnl->save.vertex_store->used) / tnl->save.vertex_size); if (tnl->save.counter > ctx->Const.MaxArrayLockSize ) tnl->save.counter = ctx->Const.MaxArrayLockSize; tnl->save.initial_counter = tnl->save.counter; /* Recalculate all the attrptr[] values: */ for (i = 0, tmp = tnl->save.vertex ; i < _TNL_ATTRIB_MAX ; i++) { if (tnl->save.attrsz[i]) { tnl->save.attrptr[i] = tmp; tmp += tnl->save.attrsz[i]; } else tnl->save.attrptr[i] = 0; /* will not be dereferenced. */ } /* Copy from current to repopulate the vertex with correct values. */ _save_copy_from_current( ctx ); /* Replay stored vertices to translate them to new format here. * * If there are copied vertices and the new (upgraded) attribute * has not been defined before, this list is somewhat degenerate, * and will need fixup at runtime. */ if (tnl->save.copied.nr) { GLfloat *data = tnl->save.copied.buffer; GLfloat *dest = tnl->save.buffer; GLuint j; /* Need to note this and fix up at runtime (or loopback): */ if (tnl->save.currentsz[attr][0] == 0) { assert(oldsz == 0); tnl->save.dangling_attr_ref = GL_TRUE; _mesa_debug(0, "_save_upgrade_vertex: dangling reference attr %d\n", attr); #if 0 /* The current strategy is to punt these degenerate cases * through _tnl_loopback_vertex_list(), a lower-performance * option. To minimize the impact of this, artificially * reduce the size of this vertex_list. */ if (t->save.counter > 10) { t->save.initial_counter = 10; t->save.counter = 10; } #endif } for (i = 0 ; i < tnl->save.copied.nr ; i++) { for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { if (tnl->save.attrsz[j]) { if (j == attr) { if (oldsz) { ASSIGN_4V( dest, 0, 0, 0, 1 ); COPY_SZ_4V( dest, oldsz, data ); data += oldsz; dest += newsz; } else { COPY_SZ_4V( dest, newsz, tnl->save.current[attr] ); dest += newsz; } } else { GLint sz = tnl->save.attrsz[j]; COPY_SZ_4V( dest, sz, data ); data += sz; dest += sz; } } } } tnl->save.vbptr = dest; tnl->save.counter -= tnl->save.copied.nr; } }
static GLboolean run_render( GLcontext *ctx, struct gl_pipeline_stage *stage ) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLuint new_inputs = stage->changed_inputs; render_func *tab; GLint pass = 0; /* Allow the drivers to lock before projected verts are built so * that window coordinates are guarenteed not to change before * rendering. */ ASSERT(tnl->Driver.Render.Start); tnl->Driver.Render.Start( ctx ); ASSERT(tnl->Driver.Render.BuildVertices); ASSERT(tnl->Driver.Render.PrimitiveNotify); ASSERT(tnl->Driver.Render.Points); ASSERT(tnl->Driver.Render.Line); ASSERT(tnl->Driver.Render.Triangle); ASSERT(tnl->Driver.Render.Quad); ASSERT(tnl->Driver.Render.ResetLineStipple); ASSERT(tnl->Driver.Render.Interp); ASSERT(tnl->Driver.Render.CopyPV); ASSERT(tnl->Driver.Render.ClippedLine); ASSERT(tnl->Driver.Render.ClippedPolygon); ASSERT(tnl->Driver.Render.Finish); tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, new_inputs ); if (VB->ClipOrMask) { tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; } else { tab = (VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts); } do { GLuint i, length, flags = 0; for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length) { flags = VB->Primitive[i]; length= VB->PrimitiveLength[i]; ASSERT(length || (flags & PRIM_LAST)); ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); if (MESA_VERBOSE & VERBOSE_PRIMS) fprintf(stderr, "MESA prim %s %d..%d\n", _mesa_lookup_enum_by_nr(flags & PRIM_MODE_MASK), i, i+length); if (length) tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); } } while (tnl->Driver.Render.Multipass && tnl->Driver.Render.Multipass( ctx, ++pass )); tnl->Driver.Render.Finish( ctx ); /* _swrast_flush(ctx); */ /* usleep(1000000); */ return GL_FALSE; /* finished the pipe */ }
static void _tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct immediate *IM = TNL_CURRENT_IM(ctx); GLuint count = IM->Count; struct gl_material *mat; GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, "Materialfv"); if (bitmask == 0) return; if (MESA_VERBOSE & VERBOSE_API) fprintf(stderr, "_tnl_Materialfv\n"); if (tnl->IsolateMaterials && !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */ { _tnl_flush_immediate( IM ); IM = TNL_CURRENT_IM(ctx); count = IM->Count; } if (!(IM->Flag[count] & VERT_MATERIAL)) { if (!IM->Material) { IM->Material = (GLmaterial (*)[2]) MALLOC( sizeof(GLmaterial) * IMM_SIZE * 2 ); IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE ); IM->MaterialMask[IM->LastMaterial] = 0; } else if (IM->MaterialOrMask & ~bitmask) { _mesa_copy_material_pairs( IM->Material[count], IM->Material[IM->LastMaterial], IM->MaterialOrMask & ~bitmask ); } IM->Flag[count] |= VERT_MATERIAL; IM->MaterialMask[count] = 0; IM->MaterialAndMask &= IM->MaterialMask[IM->LastMaterial]; IM->LastMaterial = count; } IM->MaterialOrMask |= bitmask; IM->MaterialMask[count] |= bitmask; mat = IM->Material[count]; if (bitmask & FRONT_AMBIENT_BIT) { COPY_4FV( mat[0].Ambient, params ); } if (bitmask & BACK_AMBIENT_BIT) { COPY_4FV( mat[1].Ambient, params ); } if (bitmask & FRONT_DIFFUSE_BIT) { COPY_4FV( mat[0].Diffuse, params ); } if (bitmask & BACK_DIFFUSE_BIT) { COPY_4FV( mat[1].Diffuse, params ); } if (bitmask & FRONT_SPECULAR_BIT) { COPY_4FV( mat[0].Specular, params ); } if (bitmask & BACK_SPECULAR_BIT) { COPY_4FV( mat[1].Specular, params ); } if (bitmask & FRONT_EMISSION_BIT) { COPY_4FV( mat[0].Emission, params ); } if (bitmask & BACK_EMISSION_BIT) { COPY_4FV( mat[1].Emission, params ); } if (bitmask & FRONT_SHININESS_BIT) { GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F ); mat[0].Shininess = shininess; } if (bitmask & BACK_SHININESS_BIT) { GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F ); mat[1].Shininess = shininess; } if (bitmask & FRONT_INDEXES_BIT) { mat[0].AmbientIndex = params[0]; mat[0].DiffuseIndex = params[1]; mat[0].SpecularIndex = params[2]; } if (bitmask & BACK_INDEXES_BIT) { mat[1].AmbientIndex = params[0]; mat[1].DiffuseIndex = params[1]; mat[1].SpecularIndex = params[2]; } if (tnl->IsolateMaterials && !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */ { _tnl_flush_immediate( IM ); } }
static GLboolean run_lighting( GLcontext *ctx, struct tnl_pipeline_stage *stage ) { struct light_stage_data *store = LIGHT_STAGE_DATA(stage); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr; GLuint idx; if (ctx->ShaderObjects._VertexShaderPresent) return GL_TRUE; if (!ctx->Light.Enabled || ctx->VertexProgram._Enabled) return GL_TRUE; /* Make sure we can talk about position x,y and z: */ if (input->size <= 2 && input == VB->ObjPtr) { _math_trans_4f( store->Input.data, VB->ObjPtr->data, VB->ObjPtr->stride, GL_FLOAT, VB->ObjPtr->size, 0, VB->Count ); if (input->size <= 2) { /* Clean z. */ _mesa_vector4f_clean_elem(&store->Input, VB->Count, 2); } if (input->size <= 1) { /* Clean y. */ _mesa_vector4f_clean_elem(&store->Input, VB->Count, 1); } input = &store->Input; } idx = 0; if (prepare_materials( ctx, VB, store )) idx |= LIGHT_MATERIAL; if (ctx->Light.Model.TwoSide) idx |= LIGHT_TWOSIDE; /* The individual functions know about replaying side-effects * vs. full re-execution. */ store->light_func_tab[idx]( ctx, VB, stage, input ); VB->AttribPtr[_TNL_ATTRIB_COLOR0] = VB->ColorPtr[0]; VB->AttribPtr[_TNL_ATTRIB_COLOR1] = VB->SecondaryColorPtr[0]; VB->AttribPtr[_TNL_ATTRIB_INDEX] = VB->IndexPtr[0]; return GL_TRUE; }