Esempio n. 1
0
static void viaRenderClippedLine(struct gl_context *ctx, GLuint ii, GLuint jj)
{
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    tnl->Driver.Render.Line(ctx, ii, jj);
}
Esempio n. 2
0
/* 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 );
   }
}
Esempio n. 3
0
/*
 * 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;
   }
}
Esempio n. 4
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;
}
Esempio n. 5
0
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;

}
Esempio n. 6
0
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;
}
Esempio n. 7
0
/**
 * 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;
}
Esempio n. 8
0
/**
 * 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 */
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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));
         }
      }
   }
}
Esempio n. 12
0
File: swrast.c Progetto: iquiw/xsrc
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;
}
Esempio n. 13
0
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;
   }
Esempio n. 14
0
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;
      }
   }
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
/* 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);
}
Esempio n. 17
0
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");
      }
   }
}
Esempio n. 18
0
/**
 * 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 );
   }
}
Esempio n. 19
0
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);
   }
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
/* 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 */
}
Esempio n. 22
0
/* 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 */
}
Esempio n. 23
0
/**
 * 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]);
      }
   }
}
Esempio n. 24
0
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));
    }
Esempio n. 25
0
void _tnl_EndList( GLcontext *ctx )
{
   (void) ctx;
   assert(TNL_CONTEXT(ctx)->save.vertex_size == 0);
}
Esempio n. 26
0
void _tnl_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   tnl->Driver.Render.Line( ctx, ii, jj );
}
Esempio n. 27
0
/* 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;
   }
}
Esempio n. 28
0
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 */
}
Esempio n. 29
0
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 );
   }
}
Esempio n. 30
0
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;
}