Exemplo n.º 1
0
/**
 * Called via ctx->Driver.NewProgram() to allocate a new vertex or
 * fragment program.
 */
static struct gl_program *
st_new_program(struct gl_context *ctx, GLenum target, GLuint id)
{
   switch (target) {
   case GL_VERTEX_PROGRAM_ARB: {
      struct st_vertex_program *prog = ST_CALLOC_STRUCT(st_vertex_program);
      return _mesa_init_vertex_program(ctx, &prog->Base, target, id);
   }

   case GL_FRAGMENT_PROGRAM_ARB:
   case GL_FRAGMENT_PROGRAM_NV: {
      struct st_fragment_program *prog = ST_CALLOC_STRUCT(st_fragment_program);
      return _mesa_init_fragment_program(ctx, &prog->Base, target, id);
   }

   case MESA_GEOMETRY_PROGRAM: {
      struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program);
      return _mesa_init_geometry_program(ctx, &prog->Base, target, id);
   }

   default:
      assert(0);
      return NULL;
   }
}
Exemplo n.º 2
0
/** called via ctx->Driver.NewTextureImage() */
static struct gl_texture_image *
st_NewTextureImage(struct gl_context * ctx)
{
   DBG("%s\n", __FUNCTION__);
   (void) ctx;
   return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image);
}
Exemplo n.º 3
0
/** called via ctx->Driver.NewTextureObject() */
static struct gl_texture_object *
st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
{
   struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);

   DBG("%s\n", __FUNCTION__);
   _mesa_initialize_texture_object(&obj->base, name, target);

   return &obj->base;
}
Exemplo n.º 4
0
/**
 * There is some duplication between mesa's bufferobjects and our
 * bufmgr buffers.  Both have an integer handle and a hashtable to
 * lookup an opaque structure.  It would be nice if the handles and
 * internal structure where somehow shared.
 */
static struct gl_buffer_object *
st_bufferobj_alloc(struct gl_context *ctx, GLuint name, GLenum target)
{
   struct st_buffer_object *st_obj = ST_CALLOC_STRUCT(st_buffer_object);

   if (!st_obj)
      return NULL;

   _mesa_initialize_buffer_object(ctx, &st_obj->Base, name, target);

   return &st_obj->Base;
}
Exemplo n.º 5
0
static struct gl_query_object *
st_NewQueryObject(GLcontext *ctx, GLuint id)
{
   struct st_query_object *stq = ST_CALLOC_STRUCT(st_query_object);
   if (stq) {
      stq->base.Id = id;
      stq->base.Ready = GL_TRUE;
      stq->pq = NULL;
      return &stq->base;
   }
   return NULL;
}
Exemplo n.º 6
0
/**
 * Called via ctx->Driver.NewProgram() to allocate a new vertex or
 * fragment program.
 */
static struct gl_program *
st_new_program(struct gl_context *ctx, GLenum target, GLuint id)
{
   switch (target) {
   case GL_VERTEX_PROGRAM_ARB: {
      struct st_vertex_program *prog = ST_CALLOC_STRUCT(st_vertex_program);
      return _mesa_init_gl_program(&prog->Base.Base, target, id);
   }
   case GL_FRAGMENT_PROGRAM_ARB: {
      struct st_fragment_program *prog = ST_CALLOC_STRUCT(st_fragment_program);
      return _mesa_init_gl_program(&prog->Base.Base, target, id);
   }
   case GL_GEOMETRY_PROGRAM_NV: {
      struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program);
      return _mesa_init_gl_program(&prog->Base.Base, target, id);
   }
   case GL_TESS_CONTROL_PROGRAM_NV: {
      struct st_tessctrl_program *prog = ST_CALLOC_STRUCT(st_tessctrl_program);
      return _mesa_init_gl_program(&prog->Base.Base, target, id);
   }
   case GL_TESS_EVALUATION_PROGRAM_NV: {
      struct st_tesseval_program *prog = ST_CALLOC_STRUCT(st_tesseval_program);
      return _mesa_init_gl_program(&prog->Base.Base, target, id);
   }
   case GL_COMPUTE_PROGRAM_NV: {
      struct st_compute_program *prog = ST_CALLOC_STRUCT(st_compute_program);
      return _mesa_init_gl_program(&prog->Base.Base, target, id);
   }
   default:
      assert(0);
      return NULL;
   }
}
Exemplo n.º 7
0
static struct gl_query_object *
st_NewQueryObject(struct gl_context *ctx, GLuint id)
{
   struct st_query_object *stq = ST_CALLOC_STRUCT(st_query_object);
   if (stq) {
      stq->base.Id = id;
      stq->base.Ready = GL_TRUE;
      stq->pq = NULL;
      stq->type = PIPE_QUERY_TYPES; /* an invalid value */
      return &stq->base;
   }
   return NULL;
}
Exemplo n.º 8
0
/**
 * Called via ctx->Driver.NewRenderbuffer()
 */
static struct gl_renderbuffer *
st_new_renderbuffer(struct gl_context *ctx, GLuint name)
{
   struct st_renderbuffer *strb = ST_CALLOC_STRUCT(st_renderbuffer);
   if (strb) {
      assert(name != 0);
      _mesa_init_renderbuffer(&strb->Base, name);
      strb->Base.Delete = st_renderbuffer_delete;
      strb->Base.AllocStorage = st_renderbuffer_alloc_storage;
      return &strb->Base;
   }
   return NULL;
}
Exemplo n.º 9
0
/** Per-context init */
void
st_init_bitmap(struct st_context *st)
{
   struct pipe_sampler_state *sampler = &st->bitmap.samplers[0];
   struct pipe_context *pipe = st->pipe;
   struct pipe_screen *screen = pipe->screen;

   /* init sampler state once */
   memset(sampler, 0, sizeof(*sampler));
   sampler->wrap_s = PIPE_TEX_WRAP_CLAMP;
   sampler->wrap_t = PIPE_TEX_WRAP_CLAMP;
   sampler->wrap_r = PIPE_TEX_WRAP_CLAMP;
   sampler->min_img_filter = PIPE_TEX_FILTER_NEAREST;
   sampler->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
   sampler->mag_img_filter = PIPE_TEX_FILTER_NEAREST;
   st->bitmap.samplers[1] = *sampler;
   st->bitmap.samplers[1].normalized_coords = 1;

   /* init baseline rasterizer state once */
   memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
   st->bitmap.rasterizer.half_pixel_center = 1;
   st->bitmap.rasterizer.bottom_edge_rule = 1;
   st->bitmap.rasterizer.depth_clip = 1;

   /* find a usable texture format */
   if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM,
                                   PIPE_TEXTURE_2D, 0,
                                   PIPE_BIND_SAMPLER_VIEW)) {
      st->bitmap.tex_format = PIPE_FORMAT_I8_UNORM;
   }
   else if (screen->is_format_supported(screen, PIPE_FORMAT_A8_UNORM,
                                        PIPE_TEXTURE_2D, 0,
                                        PIPE_BIND_SAMPLER_VIEW)) {
      st->bitmap.tex_format = PIPE_FORMAT_A8_UNORM;
   }
   else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM,
                                        PIPE_TEXTURE_2D, 0,
                                        PIPE_BIND_SAMPLER_VIEW)) {
      st->bitmap.tex_format = PIPE_FORMAT_L8_UNORM;
   }
   else {
      /* XXX support more formats */
      assert(0);
   }

   /* alloc bitmap cache object */
   st->bitmap.cache = ST_CALLOC_STRUCT(bitmap_cache);

   reset_cache(st);
}
Exemplo n.º 10
0
/**
 * Create GL selection mode drawing stage.
 */
static struct draw_stage *
draw_glselect_stage(struct gl_context *ctx, struct draw_context *draw)
{
   struct feedback_stage *fs = ST_CALLOC_STRUCT(feedback_stage);

   fs->stage.draw = draw;
   fs->stage.next = NULL;
   fs->stage.point = select_point;
   fs->stage.line = select_line;
   fs->stage.tri = select_tri;
   fs->stage.flush = select_flush;
   fs->stage.reset_stipple_counter = select_reset_stipple_counter;
   fs->stage.destroy = select_destroy;
   fs->ctx = ctx;

   return &fs->stage;
}
Exemplo n.º 11
0
/**
 * Create rasterpos "drawing" stage.
 */
static struct rastpos_stage *
new_draw_rastpos_stage(struct gl_context *ctx, struct draw_context *draw)
{
   struct rastpos_stage *rs = ST_CALLOC_STRUCT(rastpos_stage);
   GLuint i;

   rs->stage.draw = draw;
   rs->stage.next = NULL;
   rs->stage.point = rastpos_point;
   rs->stage.line = rastpos_line;
   rs->stage.tri = rastpos_tri;
   rs->stage.flush = rastpos_flush;
   rs->stage.destroy = rastpos_destroy;
   rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter;
   rs->stage.destroy = rastpos_destroy;
   rs->ctx = ctx;

   for (i = 0; i < ARRAY_SIZE(rs->array); i++) {
      rs->array[i].Size = 4;
      rs->array[i].Type = GL_FLOAT;
      rs->array[i].Format = GL_RGBA;
      rs->array[i].Stride = 0;
      rs->array[i].StrideB = 0;
      rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
      rs->array[i].Enabled = GL_TRUE;
      rs->array[i].Normalized = GL_TRUE;
      rs->array[i].BufferObj = NULL;
      rs->arrays[i] = &rs->array[i];
   }

   rs->prim.mode = GL_POINTS;
   rs->prim.indexed = 0;
   rs->prim.begin = 1;
   rs->prim.end = 1;
   rs->prim.weak = 0;
   rs->prim.start = 0;
   rs->prim.count = 1;

   return rs;
}
Exemplo n.º 12
0
static struct st_context *
st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
{
   uint i;
   struct st_context *st = ST_CALLOC_STRUCT( st_context );
   
   ctx->st = st;

   st->ctx = ctx;
   st->pipe = pipe;

   /* XXX: this is one-off, per-screen init: */
   st_debug_init();
   
   /* state tracker needs the VBO module */
   _vbo_CreateContext(ctx);

   st->dirty.mesa = ~0;
   st->dirty.st = ~0;

   st->cso_context = cso_create_context(pipe);

   st_init_atoms( st );
   st_init_bitmap(st);
   st_init_clear(st);
   st_init_draw( st );
   st_init_generate_mipmap(st);
   st_init_blit(st);

   if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES))
      st->internal_target = PIPE_TEXTURE_2D;
   else
      st->internal_target = PIPE_TEXTURE_RECT;

   for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
      st->state.sampler_list[i] = &st->state.samplers[i];

   for (i = 0; i < 3; i++) {
      memset(&st->velems_util_draw[i], 0, sizeof(struct pipe_vertex_element));
      st->velems_util_draw[i].src_offset = i * 4 * sizeof(float);
      st->velems_util_draw[i].instance_divisor = 0;
      st->velems_util_draw[i].vertex_buffer_index = 0;
      st->velems_util_draw[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
   }

   /* we want all vertex data to be placed in buffer objects */
   vbo_use_buffer_objects(ctx);

   /* Need these flags:
    */
   st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;

   st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;

   st->pixel_xfer.cache = _mesa_new_program_cache();

   st->force_msaa = st_get_msaa();

   /* GL limits and extensions */
   st_init_limits(st);
   st_init_extensions(st);

   return st;
}
Exemplo n.º 13
0
/**
 * Allocate a renderbuffer for a an on-screen window (not a user-created
 * renderbuffer).  The window system code determines the format.
 */
struct gl_renderbuffer *
st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw)
{
   struct st_renderbuffer *strb;

   strb = ST_CALLOC_STRUCT(st_renderbuffer);
   if (!strb) {
      _mesa_error(NULL, GL_OUT_OF_MEMORY, "creating renderbuffer");
      return NULL;
   }

   _mesa_init_renderbuffer(&strb->Base, 0);
   strb->Base.ClassID = 0x4242; /* just a unique value */
   strb->Base.NumSamples = samples;
   strb->Base.Format = st_pipe_format_to_mesa_format(format);
   strb->Base._BaseFormat = _mesa_get_format_base_format(strb->Base.Format);
   strb->software = sw;

   switch (format) {
   case PIPE_FORMAT_R8G8B8A8_UNORM:
   case PIPE_FORMAT_B8G8R8A8_UNORM:
   case PIPE_FORMAT_A8R8G8B8_UNORM:
      strb->Base.InternalFormat = GL_RGBA8;
      break;
   case PIPE_FORMAT_R8G8B8X8_UNORM:
   case PIPE_FORMAT_B8G8R8X8_UNORM:
   case PIPE_FORMAT_X8R8G8B8_UNORM:
      strb->Base.InternalFormat = GL_RGB8;
      break;
   case PIPE_FORMAT_R8G8B8A8_SRGB:
   case PIPE_FORMAT_B8G8R8A8_SRGB:
   case PIPE_FORMAT_A8R8G8B8_SRGB:
      strb->Base.InternalFormat = GL_SRGB8_ALPHA8;
      break;
   case PIPE_FORMAT_R8G8B8X8_SRGB:
   case PIPE_FORMAT_B8G8R8X8_SRGB:
   case PIPE_FORMAT_X8R8G8B8_SRGB:
      strb->Base.InternalFormat = GL_SRGB8;
      break;
   case PIPE_FORMAT_B5G5R5A1_UNORM:
      strb->Base.InternalFormat = GL_RGB5_A1;
      break;
   case PIPE_FORMAT_B4G4R4A4_UNORM:
      strb->Base.InternalFormat = GL_RGBA4;
      break;
   case PIPE_FORMAT_B5G6R5_UNORM:
      strb->Base.InternalFormat = GL_RGB565;
      break;
   case PIPE_FORMAT_Z16_UNORM:
      strb->Base.InternalFormat = GL_DEPTH_COMPONENT16;
      break;
   case PIPE_FORMAT_Z32_UNORM:
      strb->Base.InternalFormat = GL_DEPTH_COMPONENT32;
      break;
   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
   case PIPE_FORMAT_S8_UINT_Z24_UNORM:
      strb->Base.InternalFormat = GL_DEPTH24_STENCIL8_EXT;
      break;
   case PIPE_FORMAT_Z24X8_UNORM:
   case PIPE_FORMAT_X8Z24_UNORM:
      strb->Base.InternalFormat = GL_DEPTH_COMPONENT24;
      break;
   case PIPE_FORMAT_S8_UINT:
      strb->Base.InternalFormat = GL_STENCIL_INDEX8_EXT;
      break;
   case PIPE_FORMAT_R16G16B16A16_SNORM:
      /* accum buffer */
      strb->Base.InternalFormat = GL_RGBA16_SNORM;
      break;
   case PIPE_FORMAT_R16G16B16A16_UNORM:
      strb->Base.InternalFormat = GL_RGBA16;
      break;
   case PIPE_FORMAT_R8_UNORM:
      strb->Base.InternalFormat = GL_R8;
      break;
   case PIPE_FORMAT_R8G8_UNORM:
      strb->Base.InternalFormat = GL_RG8;
      break;
   case PIPE_FORMAT_R16_UNORM:
      strb->Base.InternalFormat = GL_R16;
      break;
   case PIPE_FORMAT_R16G16_UNORM:
      strb->Base.InternalFormat = GL_RG16;
      break;
   case PIPE_FORMAT_R32G32B32A32_FLOAT:
      strb->Base.InternalFormat = GL_RGBA32F;
      break;
   case PIPE_FORMAT_R16G16B16A16_FLOAT:
      strb->Base.InternalFormat = GL_RGBA16F;
      break;
   default:
      _mesa_problem(NULL,
		    "Unexpected format %s in st_new_renderbuffer_fb",
                    util_format_name(format));
      free(strb);
      return NULL;
   }

   /* st-specific methods */
   strb->Base.Delete = st_renderbuffer_delete;
   strb->Base.AllocStorage = st_renderbuffer_alloc_storage;

   /* surface is allocated in st_renderbuffer_alloc_storage() */
   strb->surface = NULL;

   return &strb->Base;
}
Exemplo n.º 14
0
/**
 * Find a translated vertex program that corresponds to stvp and
 * has outputs matched to stfp's inputs.
 * This performs vertex and fragment translation (to TGSI) when needed.
 */
static struct translated_vertex_program *
find_translated_vp(struct st_context *st,
                   struct st_vertex_program *stvp,
                   struct st_fragment_program *stfp)
{
   static const GLuint UNUSED = ~0;
   struct translated_vertex_program *xvp;
   const GLbitfield fragInputsRead = stfp->Base.Base.InputsRead;

   /*
    * Translate fragment program if needed.
    */
   if (!stfp->state.tokens) {
      GLuint inAttr, numIn = 0;

      for (inAttr = 0; inAttr < FRAG_ATTRIB_MAX; inAttr++) {
         if (fragInputsRead & (1 << inAttr)) {
            stfp->input_to_slot[inAttr] = numIn;
            numIn++;
         }
         else {
            stfp->input_to_slot[inAttr] = UNUSED;
         }
      }

      stfp->num_input_slots = numIn;

      assert(stfp->Base.Base.NumInstructions > 1);

      st_translate_fragment_program(st, stfp, stfp->input_to_slot);
   }


   /* See if we've got a translated vertex program whose outputs match
    * the fragment program's inputs.
    * XXX This could be a hash lookup, using InputsRead as the key.
    */
   for (xvp = stfp->vertex_programs; xvp; xvp = xvp->next) {
      if (xvp->master == stvp && xvp->frag_inputs == fragInputsRead) {
         break;
      }
   }

   /* No?  Allocate translated vp object now */
   if (!xvp) {
      xvp = ST_CALLOC_STRUCT(translated_vertex_program);
      xvp->frag_inputs = fragInputsRead;
      xvp->master = stvp;

      xvp->next = stfp->vertex_programs;
      stfp->vertex_programs = xvp;
   }

   /* See if we need to translate vertex program to TGSI form */
   if (xvp->serialNo != stvp->serialNo) {
      GLuint outAttr;
      const GLbitfield outputsWritten = stvp->Base.Base.OutputsWritten;
      GLuint numVpOuts = 0;
      GLboolean emitPntSize = GL_FALSE, emitBFC0 = GL_FALSE, emitBFC1 = GL_FALSE;
      GLbitfield usedGenerics = 0x0;
      GLbitfield usedOutputSlots = 0x0;

      /* Compute mapping of vertex program outputs to slots, which depends
       * on the fragment program's input->slot mapping.
       */
      for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
         /* set defaults: */
         xvp->output_to_slot[outAttr] = UNUSED;
         xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_COUNT;
         xvp->output_to_semantic_index[outAttr] = 99;

         if (outAttr == VERT_RESULT_HPOS) {
            /* always put xformed position into slot zero */
            GLuint slot = 0;
            xvp->output_to_slot[VERT_RESULT_HPOS] = slot;
            xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_POSITION;
            xvp->output_to_semantic_index[outAttr] = 0;
            numVpOuts++;
            usedOutputSlots |= (1 << slot);
         }
         else if (outputsWritten & (1 << outAttr)) {
            /* see if the frag prog wants this vert output */
            GLint fpInAttrib = vp_out_to_fp_in(outAttr);
            if (fpInAttrib >= 0) {
               GLuint fpInSlot = stfp->input_to_slot[fpInAttrib];
               if (fpInSlot != ~0) {
                  /* match this vp output to the fp input */
                  GLuint vpOutSlot = stfp->input_map[fpInSlot];
                  xvp->output_to_slot[outAttr] = vpOutSlot;
                  xvp->output_to_semantic_name[outAttr] = stfp->input_semantic_name[fpInSlot];
                  xvp->output_to_semantic_index[outAttr] = stfp->input_semantic_index[fpInSlot];
                  numVpOuts++;
                  usedOutputSlots |= (1 << vpOutSlot);
               }
               else {
#if 0 /*debug*/
                  printf("VP output %d not used by FP\n", outAttr);
#endif
               }
            }
            else if (outAttr == VERT_RESULT_PSIZ)
               emitPntSize = GL_TRUE;
            else if (outAttr == VERT_RESULT_BFC0)
               emitBFC0 = GL_TRUE;
            else if (outAttr == VERT_RESULT_BFC1)
               emitBFC1 = GL_TRUE;
         }
#if 0 /*debug*/
         printf("assign vp output_to_slot[%d] = %d\n", outAttr, 
                xvp->output_to_slot[outAttr]);
#endif
      }

      /* must do these last */
      if (emitPntSize) {
         GLuint slot = numVpOuts++;
         xvp->output_to_slot[VERT_RESULT_PSIZ] = slot;
         xvp->output_to_semantic_name[VERT_RESULT_PSIZ] = TGSI_SEMANTIC_PSIZE;
         xvp->output_to_semantic_index[VERT_RESULT_PSIZ] = 0;
         usedOutputSlots |= (1 << slot);
      }
      if (emitBFC0) {
         GLuint slot = numVpOuts++;
         xvp->output_to_slot[VERT_RESULT_BFC0] = slot;
         xvp->output_to_semantic_name[VERT_RESULT_BFC0] = TGSI_SEMANTIC_COLOR;
         xvp->output_to_semantic_index[VERT_RESULT_BFC0] = 0;
         usedOutputSlots |= (1 << slot);
      }
      if (emitBFC1) {
         GLuint slot = numVpOuts++;
         xvp->output_to_slot[VERT_RESULT_BFC1] = slot;
         xvp->output_to_semantic_name[VERT_RESULT_BFC1] = TGSI_SEMANTIC_COLOR;
         xvp->output_to_semantic_index[VERT_RESULT_BFC1] = 1;
         usedOutputSlots |= (1 << slot);
      }

      /* build usedGenerics mask */
      usedGenerics = 0x0;
      for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
         if (xvp->output_to_semantic_name[outAttr] == TGSI_SEMANTIC_GENERIC) {
            usedGenerics |= (1 << xvp->output_to_semantic_index[outAttr]);
         }
      }

      /* For each vertex program output that doesn't match up to a fragment
       * program input, map the vertex program output to a free slot and
       * free generic attribute.
       */
      for (outAttr = 0; outAttr < VERT_RESULT_MAX; outAttr++) {
         if (outputsWritten & (1 << outAttr)) {
            if (xvp->output_to_slot[outAttr] == UNUSED) {
               GLint freeGeneric = _mesa_ffs(~usedGenerics) - 1;
               GLint freeSlot = _mesa_ffs(~usedOutputSlots) - 1;
               usedGenerics |= (1 << freeGeneric);
               usedOutputSlots |= (1 << freeSlot);
               xvp->output_to_slot[outAttr] = freeSlot;
               xvp->output_to_semantic_name[outAttr] = TGSI_SEMANTIC_GENERIC;
               xvp->output_to_semantic_index[outAttr] = freeGeneric;
            }
         }

#if 0 /*debug*/
         printf("vp output_to_slot[%d] = %d\n", outAttr, 
                xvp->output_to_slot[outAttr]);
#endif
      }

      assert(stvp->Base.Base.NumInstructions > 1);

      st_translate_vertex_program(st, stvp, xvp->output_to_slot,
                                  xvp->output_to_semantic_name,
                                  xvp->output_to_semantic_index);

      xvp->vp = stvp;

      /* translated VP is up to date now */
      xvp->serialNo = stvp->serialNo;
   }

   return xvp;
}
Exemplo n.º 15
0
static struct st_context *
st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
		const struct st_config_options *options)
{
   struct pipe_screen *screen = pipe->screen;
   uint i;
   struct st_context *st = ST_CALLOC_STRUCT( st_context );
   
   st->options = *options;

   ctx->st = st;

   st->ctx = ctx;
   st->pipe = pipe;

   /* XXX: this is one-off, per-screen init: */
   st_debug_init();
   
   /* state tracker needs the VBO module */
   _vbo_CreateContext(ctx);

   st->dirty.mesa = ~0;
   st->dirty.st = ~0;

   /* Create upload manager for vertex data for glBitmap, glDrawPixels,
    * glClear, etc.
    */
   st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);

   if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) {
      st->indexbuf_uploader = u_upload_create(st->pipe, 128 * 1024, 4,
                                              PIPE_BIND_INDEX_BUFFER);
   }

   if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS)) {
      unsigned alignment =
         screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT);

      st->constbuf_uploader = u_upload_create(pipe, 128 * 1024, alignment,
                                              PIPE_BIND_CONSTANT_BUFFER);
   }

   st->cso_context = cso_create_context(pipe);

   st_init_atoms( st );
   st_init_bitmap(st);
   st_init_clear(st);
   st_init_draw( st );
   st_init_generate_mipmap(st);

   /* Choose texture target for glDrawPixels, glBitmap, renderbuffers */
   if (pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES))
      st->internal_target = PIPE_TEXTURE_2D;
   else
      st->internal_target = PIPE_TEXTURE_RECT;

   /* Vertex element objects used for drawing rectangles for glBitmap,
    * glDrawPixels, glClear, etc.
    */
   for (i = 0; i < Elements(st->velems_util_draw); i++) {
      memset(&st->velems_util_draw[i], 0, sizeof(struct pipe_vertex_element));
      st->velems_util_draw[i].src_offset = i * 4 * sizeof(float);
      st->velems_util_draw[i].instance_divisor = 0;
      st->velems_util_draw[i].vertex_buffer_index =
            cso_get_aux_vertex_buffer_slot(st->cso_context);
      st->velems_util_draw[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
   }

   /* we want all vertex data to be placed in buffer objects */
   vbo_use_buffer_objects(ctx);


   /* make sure that no VBOs are left mapped when we're drawing. */
   vbo_always_unmap_buffers(ctx);

   /* Need these flags:
    */
   st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;

   st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;

   st->pixel_xfer.cache = _mesa_new_program_cache();

   st->has_stencil_export =
      screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT);
   st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3);
   st->prefer_blit_based_texture_transfer = screen->get_param(screen,
                              PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER);

   st->needs_texcoord_semantic =
      screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD);
   st->apply_texture_swizzle_to_border_color =
      !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) &
         (PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 |
          PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600));

   /* GL limits and extensions */
   st_init_limits(st);
   st_init_extensions(st);

   _mesa_compute_version(ctx);

   _mesa_initialize_dispatch_tables(ctx);
   _mesa_initialize_vbo_vtxfmt(ctx);

   return st;
}
Exemplo n.º 16
0
/**
 * One-time init for drawing bitmaps.
 */
static void
init_bitmap_state(struct st_context *st)
{
    struct pipe_context *pipe = st->pipe;
    struct pipe_screen *screen = pipe->screen;

    /* This function should only be called once */
    assert(st->bitmap.cache == NULL);

    assert(st->internal_target == PIPE_TEXTURE_2D ||
           st->internal_target == PIPE_TEXTURE_RECT);

    /* alloc bitmap cache object */
    st->bitmap.cache = ST_CALLOC_STRUCT(bitmap_cache);

    /* init sampler state once */
    memset(&st->bitmap.sampler, 0, sizeof(st->bitmap.sampler));
    st->bitmap.sampler.wrap_s = PIPE_TEX_WRAP_CLAMP;
    st->bitmap.sampler.wrap_t = PIPE_TEX_WRAP_CLAMP;
    st->bitmap.sampler.wrap_r = PIPE_TEX_WRAP_CLAMP;
    st->bitmap.sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
    st->bitmap.sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
    st->bitmap.sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
    st->bitmap.sampler.normalized_coords = st->internal_target == PIPE_TEXTURE_2D;

    st->bitmap.atlas_sampler = st->bitmap.sampler;
    st->bitmap.atlas_sampler.normalized_coords = 0;

    /* init baseline rasterizer state once */
    memset(&st->bitmap.rasterizer, 0, sizeof(st->bitmap.rasterizer));
    st->bitmap.rasterizer.half_pixel_center = 1;
    st->bitmap.rasterizer.bottom_edge_rule = 1;
    st->bitmap.rasterizer.depth_clip = 1;

    /* find a usable texture format */
    if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM,
                                    st->internal_target, 0,
                                    PIPE_BIND_SAMPLER_VIEW)) {
        st->bitmap.tex_format = PIPE_FORMAT_I8_UNORM;
    }
    else if (screen->is_format_supported(screen, PIPE_FORMAT_A8_UNORM,
                                         st->internal_target, 0,
                                         PIPE_BIND_SAMPLER_VIEW)) {
        st->bitmap.tex_format = PIPE_FORMAT_A8_UNORM;
    }
    else if (screen->is_format_supported(screen, PIPE_FORMAT_L8_UNORM,
                                         st->internal_target, 0,
                                         PIPE_BIND_SAMPLER_VIEW)) {
        st->bitmap.tex_format = PIPE_FORMAT_L8_UNORM;
    }
    else {
        /* XXX support more formats */
        assert(0);
    }

    /* Create the vertex shader */
    {
        const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
                                        TGSI_SEMANTIC_COLOR,
                                        st->needs_texcoord_semantic ? TGSI_SEMANTIC_TEXCOORD :
                                        TGSI_SEMANTIC_GENERIC
                                      };
        const uint semantic_indexes[] = { 0, 0, 0 };
        st->bitmap.vs = util_make_vertex_passthrough_shader(st->pipe, 3,
                        semantic_names,
                        semantic_indexes,
                        FALSE);
    }

    reset_cache(st);
}
Exemplo n.º 17
0
static struct st_context *
st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe,
		const struct st_config_options *options)
{
   struct pipe_screen *screen = pipe->screen;
   uint i;
   struct st_context *st = ST_CALLOC_STRUCT( st_context );
   
   st->options = *options;

   ctx->st = st;

   st->ctx = ctx;
   st->pipe = pipe;

   /* XXX: this is one-off, per-screen init: */
   st_debug_init();
   
   /* state tracker needs the VBO module */
   _vbo_CreateContext(ctx);

   st->dirty.mesa = ~0;
   st->dirty.st = ~0;

   /* Create upload manager for vertex data for glBitmap, glDrawPixels,
    * glClear, etc.
    */
   st->uploader = u_upload_create(st->pipe, 65536, PIPE_BIND_VERTEX_BUFFER,
                                  PIPE_USAGE_STREAM);

   if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) {
      st->indexbuf_uploader = u_upload_create(st->pipe, 128 * 1024,
                                              PIPE_BIND_INDEX_BUFFER,
                                              PIPE_USAGE_STREAM);
   }

   if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS))
      st->constbuf_uploader = u_upload_create(pipe, 128 * 1024,
                                              PIPE_BIND_CONSTANT_BUFFER,
                                              PIPE_USAGE_STREAM);

   st->cso_context = cso_create_context(pipe);

   st_init_atoms( st );
   st_init_bitmap(st);
   st_init_clear(st);
   st_init_draw( st );

   /* Choose texture target for glDrawPixels, glBitmap, renderbuffers */
   if (pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES))
      st->internal_target = PIPE_TEXTURE_2D;
   else
      st->internal_target = PIPE_TEXTURE_RECT;

   /* Vertex element objects used for drawing rectangles for glBitmap,
    * glDrawPixels, glClear, etc.
    */
   for (i = 0; i < ARRAY_SIZE(st->velems_util_draw); i++) {
      memset(&st->velems_util_draw[i], 0, sizeof(struct pipe_vertex_element));
      st->velems_util_draw[i].src_offset = i * 4 * sizeof(float);
      st->velems_util_draw[i].instance_divisor = 0;
      st->velems_util_draw[i].vertex_buffer_index =
            cso_get_aux_vertex_buffer_slot(st->cso_context);
      st->velems_util_draw[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
   }

   /* we want all vertex data to be placed in buffer objects */
   vbo_use_buffer_objects(ctx);


   /* make sure that no VBOs are left mapped when we're drawing. */
   vbo_always_unmap_buffers(ctx);

   /* Need these flags:
    */
   st->ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;

   st->ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;

   st->has_stencil_export =
      screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT);
   st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3);
   st->has_etc1 = screen->is_format_supported(screen, PIPE_FORMAT_ETC1_RGB8,
                                              PIPE_TEXTURE_2D, 0,
                                              PIPE_BIND_SAMPLER_VIEW);
   st->has_etc2 = screen->is_format_supported(screen, PIPE_FORMAT_ETC2_RGB8,
                                              PIPE_TEXTURE_2D, 0,
                                              PIPE_BIND_SAMPLER_VIEW);
   st->prefer_blit_based_texture_transfer = screen->get_param(screen,
                              PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER);
   st->force_persample_in_shader =
      screen->get_param(screen, PIPE_CAP_SAMPLE_SHADING) &&
      !screen->get_param(screen, PIPE_CAP_FORCE_PERSAMPLE_INTERP);
   st->has_shareable_shaders = screen->get_param(screen,
                                                 PIPE_CAP_SHAREABLE_SHADERS);
   st->needs_texcoord_semantic =
      screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD);
   st->apply_texture_swizzle_to_border_color =
      !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) &
         (PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 |
          PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600));
   st->has_time_elapsed =
      screen->get_param(screen, PIPE_CAP_QUERY_TIME_ELAPSED);
   st->has_half_float_packing =
      screen->get_param(screen, PIPE_CAP_TGSI_PACK_HALF_FLOAT);
   st->has_multi_draw_indirect =
      screen->get_param(screen, PIPE_CAP_MULTI_DRAW_INDIRECT);

   /* GL limits and extensions */
   st_init_limits(st->pipe->screen, &ctx->Const, &ctx->Extensions);
   st_init_extensions(st->pipe->screen, &ctx->Const,
                      &ctx->Extensions, &st->options, ctx->Mesa_DXTn);

   if (st_have_perfmon(st)) {
      ctx->Extensions.AMD_performance_monitor = GL_TRUE;
   }

   /* Enable shader-based fallbacks for ARB_color_buffer_float if needed. */
   if (screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_UNCLAMPED)) {
      if (!screen->get_param(screen, PIPE_CAP_VERTEX_COLOR_CLAMPED)) {
         st->clamp_vert_color_in_shader = GL_TRUE;
      }

      if (!screen->get_param(screen, PIPE_CAP_FRAGMENT_COLOR_CLAMPED)) {
         st->clamp_frag_color_in_shader = GL_TRUE;
      }

      /* For drivers which cannot do color clamping, it's better to just
       * disable ARB_color_buffer_float in the core profile, because
       * the clamping is deprecated there anyway. */
      if (ctx->API == API_OPENGL_CORE &&
          (st->clamp_frag_color_in_shader || st->clamp_vert_color_in_shader)) {
         st->clamp_vert_color_in_shader = GL_FALSE;
         st->clamp_frag_color_in_shader = GL_FALSE;
         ctx->Extensions.ARB_color_buffer_float = GL_FALSE;
      }
   }

   /* called after _mesa_create_context/_mesa_init_point, fix default user
    * settable max point size up
    */
   st->ctx->Point.MaxSize = MAX2(ctx->Const.MaxPointSize,
                                 ctx->Const.MaxPointSizeAA);
   /* For vertex shaders, make sure not to emit saturate when SM 3.0 is not supported */
   ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].EmitNoSat = !st->has_shader_model3;

   if (!ctx->Extensions.ARB_gpu_shader5) {
      for (i = 0; i < MESA_SHADER_STAGES; i++)
         ctx->Const.ShaderCompilerOptions[i].EmitNoIndirectSampler = true;
   }

   /* Set which shader types can be compiled at link time. */
   st->shader_has_one_variant[MESA_SHADER_VERTEX] =
         st->has_shareable_shaders &&
         !st->clamp_vert_color_in_shader;

   st->shader_has_one_variant[MESA_SHADER_FRAGMENT] =
         st->has_shareable_shaders &&
         !st->clamp_frag_color_in_shader &&
         !st->force_persample_in_shader;

   st->shader_has_one_variant[MESA_SHADER_TESS_CTRL] = st->has_shareable_shaders;
   st->shader_has_one_variant[MESA_SHADER_TESS_EVAL] = st->has_shareable_shaders;
   st->shader_has_one_variant[MESA_SHADER_GEOMETRY] = st->has_shareable_shaders;

   _mesa_compute_version(ctx);

   if (ctx->Version == 0) {
      /* This can happen when a core profile was requested, but the driver
       * does not support some features of GL 3.1 or later.
       */
      st_destroy_context_priv(st);
      return NULL;
   }

   _mesa_initialize_dispatch_tables(ctx);
   _mesa_initialize_vbo_vtxfmt(ctx);

   return st;
}