/**
 * Allocate space for and store data in a buffer object.  Any data that was
 * previously stored in the buffer object is lost.  If data is NULL,
 * memory will be allocated, but no copy will occur.
 * Called via glBufferDataARB().
 */
static void
st_bufferobj_data(GLcontext *ctx,
		  GLenum target,
		  GLsizeiptrARB size,
		  const GLvoid * data,
		  GLenum usage, 
		  struct gl_buffer_object *obj)
{
   struct st_context *st = st_context(ctx);
   struct pipe_context *pipe = st->pipe;
   struct st_buffer_object *st_obj = st_buffer_object(obj);
   unsigned buffer_usage;

   st_obj->Base.Size = size;
   st_obj->Base.Usage = usage;
   
   switch(target) {
   case GL_PIXEL_PACK_BUFFER_ARB:
   case GL_PIXEL_UNPACK_BUFFER_ARB:
      buffer_usage = PIPE_BUFFER_USAGE_PIXEL;
      break;
   case GL_ARRAY_BUFFER_ARB:
      buffer_usage = PIPE_BUFFER_USAGE_VERTEX;
      break;
   case GL_ELEMENT_ARRAY_BUFFER_ARB:
      buffer_usage = PIPE_BUFFER_USAGE_INDEX;
      break;
   default:
      buffer_usage = 0;
   }

   pipe_buffer_reference( &st_obj->buffer, NULL );

   st_obj->buffer = pipe_buffer_create( pipe->screen, 32, buffer_usage, size );

   if (!st_obj->buffer) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB");
      return;
   }

   st_obj->size = size;

   if (data)
      st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0,
				    size, data);
}
Exemple #2
0
/**
 * Pass the given program parameters to the graphics pipe as a
 * constant buffer.
 * \param id  either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT
 */
void st_upload_constants( struct st_context *st,
                          struct gl_program_parameter_list *params,
                          unsigned id)
{
   struct pipe_context *pipe = st->pipe;
   struct pipe_constant_buffer *cbuf = &st->state.constants[id];

   assert(id == PIPE_SHADER_VERTEX || id == PIPE_SHADER_FRAGMENT);

   /* update constants */
   if (params && params->NumParameters) {
      const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;

      _mesa_load_state_parameters(st->ctx, params);

      /* We always need to get a new buffer, to keep the drivers simple and
       * avoid gratuitous rendering synchronization.
       */
      pipe_buffer_reference(&cbuf->buffer, NULL );
      cbuf->buffer = pipe_buffer_create(pipe->screen, 16, PIPE_BUFFER_USAGE_CONSTANT,
					paramBytes );

      if (0)
      {
	 printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n", 
                __FUNCTION__, id, params->NumParameters, params->StateFlags);
         _mesa_print_parameter_list(params);
      }

      /* load Mesa constants into the constant buffer */
      if (cbuf->buffer)
         st_no_flush_pipe_buffer_write(st, cbuf->buffer,
				       0, paramBytes,
				       params->ParameterValues);

      st->pipe->set_constant_buffer(st->pipe, id, 0, cbuf);
   }
   else {
      st->constants.tracked_state[id].dirty.mesa = 0;
      //  st->pipe->set_constant_buffer(st->pipe, id, 0, NULL);
   }
}
void vg_validate_state(struct vg_context *ctx)
{
   vg_manager_validate_framebuffer(ctx);

   if ((ctx->state.dirty & BLEND_DIRTY)) {
      struct pipe_blend_state *blend = &ctx->state.g3d.blend;
      memset(blend, 0, sizeof(struct pipe_blend_state));
      blend->rt[0].blend_enable = 1;
      blend->rt[0].colormask = PIPE_MASK_RGBA;

      switch (ctx->state.vg.blend_mode) {
      case VG_BLEND_SRC:
         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
         blend->rt[0].blend_enable = 0;
         break;
      case VG_BLEND_SRC_OVER:
         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_SRC_ALPHA;
         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
         break;
      case VG_BLEND_DST_OVER:
         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_INV_DST_ALPHA;
         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_INV_DST_ALPHA;
         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_DST_ALPHA;
         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_DST_ALPHA;
         break;
      case VG_BLEND_SRC_IN:
         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_DST_ALPHA;
         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_DST_ALPHA;
         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
         break;
      case VG_BLEND_DST_IN:
         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ZERO;
         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_SRC_ALPHA;
         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
         break;
      case VG_BLEND_MULTIPLY:
      case VG_BLEND_SCREEN:
      case VG_BLEND_DARKEN:
      case VG_BLEND_LIGHTEN:
         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ZERO;
         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
         blend->rt[0].blend_enable = 0;
         break;
      case VG_BLEND_ADDITIVE:
         blend->rt[0].rgb_src_factor   = PIPE_BLENDFACTOR_ONE;
         blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
         blend->rt[0].rgb_dst_factor   = PIPE_BLENDFACTOR_ONE;
         blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
         break;
      default:
         assert(!"not implemented blend mode");
      }
      cso_set_blend(ctx->cso_context, &ctx->state.g3d.blend);
   }
   if ((ctx->state.dirty & RASTERIZER_DIRTY)) {
      struct pipe_rasterizer_state *raster = &ctx->state.g3d.rasterizer;
      memset(raster, 0, sizeof(struct pipe_rasterizer_state));
      raster->gl_rasterization_rules = 1;
      cso_set_rasterizer(ctx->cso_context, &ctx->state.g3d.rasterizer);
   }
   if ((ctx->state.dirty & VIEWPORT_DIRTY)) {
      struct pipe_framebuffer_state *fb = &ctx->state.g3d.fb;
      const VGint param_bytes = 8 * sizeof(VGfloat);
      VGfloat vs_consts[8] = {
         2.f/fb->width, 2.f/fb->height, 1, 1,
         -1, -1, 0, 0
      };
      struct pipe_resource **cbuf = &ctx->vs_const_buffer;

      vg_set_viewport(ctx, VEGA_Y0_BOTTOM);

      pipe_resource_reference(cbuf, NULL);
      *cbuf = pipe_buffer_create(ctx->pipe->screen, 
				 PIPE_BIND_CONSTANT_BUFFER,
				 param_bytes);

      if (*cbuf) {
         st_no_flush_pipe_buffer_write(ctx, *cbuf,
                                       0, param_bytes, vs_consts);
      }
      ctx->pipe->set_constant_buffer(ctx->pipe, PIPE_SHADER_VERTEX, 0, *cbuf);
   }
   if ((ctx->state.dirty & VS_DIRTY)) {
      cso_set_vertex_shader_handle(ctx->cso_context,
                                   vg_plain_vs(ctx));
   }

   /* must be last because it renders to the depth buffer*/
   if ((ctx->state.dirty & DEPTH_STENCIL_DIRTY)) {
      update_clip_state(ctx);
      cso_set_depth_stencil_alpha(ctx->cso_context, &ctx->state.g3d.dsa);
   }

   shader_set_masking(ctx->shader, ctx->state.vg.masking);
   shader_set_image_mode(ctx->shader, ctx->state.vg.image_mode);

   ctx->state.dirty = NONE_DIRTY;
}
Exemple #4
0
/**
 * Draw quad with texcoords and optional color.
 * Coords are window coords with y=0=bottom.
 * \param color  may be null
 * \param invertTex  if true, flip texcoords vertically
 */
static void
draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
          GLfloat x1, GLfloat y1, const GLfloat *color,
          GLboolean invertTex)
{
   struct st_context *st = ctx->st;
   struct pipe_context *pipe = ctx->st->pipe;
   GLfloat verts[4][3][4]; /* four verts, three attribs, XYZW */

   /* setup vertex data */
   {
      const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
      const GLfloat fb_width = (GLfloat) fb->Width;
      const GLfloat fb_height = (GLfloat) fb->Height;
      const GLfloat clip_x0 = x0 / fb_width * 2.0f - 1.0f;
      const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f;
      const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f;
      const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f;
      const GLfloat sLeft = 0.0f, sRight = 1.0f;
      const GLfloat tTop = invertTex, tBot = 1.0f - tTop;
      GLuint tex, i;

      /* upper-left */
      verts[0][0][0] = clip_x0;    /* v[0].attr[0].x */
      verts[0][0][1] = clip_y0;    /* v[0].attr[0].y */

      /* upper-right */
      verts[1][0][0] = clip_x1;
      verts[1][0][1] = clip_y0;

      /* lower-right */
      verts[2][0][0] = clip_x1;
      verts[2][0][1] = clip_y1;

      /* lower-left */
      verts[3][0][0] = clip_x0;
      verts[3][0][1] = clip_y1;

      tex = color ? 2 : 1;
      verts[0][tex][0] = sLeft; /* v[0].attr[tex].s */
      verts[0][tex][1] = tTop;  /* v[0].attr[tex].t */
      verts[1][tex][0] = sRight;
      verts[1][tex][1] = tTop;
      verts[2][tex][0] = sRight;
      verts[2][tex][1] = tBot;
      verts[3][tex][0] = sLeft;
      verts[3][tex][1] = tBot;

      /* same for all verts: */
      if (color) {
         for (i = 0; i < 4; i++) {
            verts[i][0][2] = z;   /*Z*/
            verts[i][0][3] = 1.0f; /*W*/
            verts[i][1][0] = color[0];
            verts[i][1][1] = color[1];
            verts[i][1][2] = color[2];
            verts[i][1][3] = color[3];
            verts[i][2][2] = 0.0f; /*R*/
            verts[i][2][3] = 1.0f; /*Q*/
         }
      }
      else {
         for (i = 0; i < 4; i++) {
            verts[i][0][2] = z;   /*Z*/
            verts[i][0][3] = 1.0f; /*W*/
            verts[i][1][2] = 0.0f; /*R*/
            verts[i][1][3] = 1.0f; /*Q*/
         }
      }
   }

   {
      struct pipe_buffer *buf;

      /* allocate/load buffer object with vertex data */
      buf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX,
                               sizeof(verts));
      st_no_flush_pipe_buffer_write(st, buf, 0, sizeof(verts), verts);

      util_draw_vertex_buffer(pipe, buf, 0,
                              PIPE_PRIM_QUADS,
                              4,  /* verts */
                              3); /* attribs/vert */
      pipe_buffer_reference(&buf, NULL);
   }
}