Ejemplo n.º 1
0
static __DRIimage *
dri2_create_image_from_renderbuffer(__DRIcontext *context,
				    int renderbuffer, void *loaderPrivate)
{
   struct dri_context *ctx = dri_context(context);

   if (!ctx->st->get_resource_for_egl_image)
      return NULL;

   /* TODO */
   return NULL;
}
Ejemplo n.º 2
0
static void
dri2_invalidate_drawable(__DRIdrawable *dPriv)
{
   struct dri_drawable *drawable = dri_drawable(dPriv);
   struct dri_context *ctx = dri_context(dPriv->driContextPriv);

   dri2InvalidateDrawable(dPriv);
   drawable->dPriv->lastStamp = *drawable->dPriv->pStamp;

   if (ctx)
      ctx->st->notify_invalid_framebuffer(ctx->st, &drawable->base);
}
Ejemplo n.º 3
0
static GLboolean
dri_make_current(__DRIcontext * cPriv,
		 __DRIdrawable * driDrawPriv,
		 __DRIdrawable * driReadPriv)
{
    struct gl_context *mesaCtx;
    struct gl_framebuffer *mesaDraw;
    struct gl_framebuffer *mesaRead;
    TRACE;

    if (cPriv) {
	struct dri_context *ctx = dri_context(cPriv);
	struct dri_drawable *draw;
	struct dri_drawable *read;

	if (!driDrawPriv || !driReadPriv)
	    return GL_FALSE;

	draw = dri_drawable(driDrawPriv);
	read = dri_drawable(driReadPriv);
	mesaCtx = &ctx->Base;
	mesaDraw = &draw->Base;
	mesaRead = &read->Base;

	/* check for same context and buffer */
	if (mesaCtx == _mesa_get_current_context()
	    && mesaCtx->DrawBuffer == mesaDraw
	    && mesaCtx->ReadBuffer == mesaRead) {
	    return GL_TRUE;
	}

	_glapi_check_multithread();

	swrast_check_and_update_window_size(mesaCtx, mesaDraw);
	if (mesaRead != mesaDraw)
	    swrast_check_and_update_window_size(mesaCtx, mesaRead);

	_mesa_make_current( mesaCtx,
			    mesaDraw,
			    mesaRead );
    }
    else {
	/* unbind */
	_mesa_make_current( NULL, NULL, NULL );
    }

    return GL_TRUE;
}
Ejemplo n.º 4
0
static void
dri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src,
                int dstx0, int dsty0, int dstwidth, int dstheight,
                int srcx0, int srcy0, int srcwidth, int srcheight,
                int flush_flag)
{
   struct dri_context *ctx = dri_context(context);
   struct pipe_context *pipe = ctx->st->pipe;
   struct pipe_screen *screen;
   struct pipe_fence_handle *fence;
   struct pipe_blit_info blit;

   if (!dst || !src)
      return;

   memset(&blit, 0, sizeof(blit));
   blit.dst.resource = dst->texture;
   blit.dst.box.x = dstx0;
   blit.dst.box.y = dsty0;
   blit.dst.box.width = dstwidth;
   blit.dst.box.height = dstheight;
   blit.dst.box.depth = 1;
   blit.dst.format = dst->texture->format;
   blit.src.resource = src->texture;
   blit.src.box.x = srcx0;
   blit.src.box.y = srcy0;
   blit.src.box.width = srcwidth;
   blit.src.box.height = srcheight;
   blit.src.box.depth = 1;
   blit.src.format = src->texture->format;
   blit.mask = PIPE_MASK_RGBA;
   blit.filter = PIPE_TEX_FILTER_NEAREST;

   pipe->blit(pipe, &blit);

   if (flush_flag == __BLIT_FLAG_FLUSH) {
      pipe->flush_resource(pipe, dst->texture);
      ctx->st->flush(ctx->st, 0, NULL);
   } else if (flush_flag == __BLIT_FLAG_FINISH) {
      screen = dri_screen(ctx->sPriv)->base.screen;
      pipe->flush_resource(pipe, dst->texture);
      ctx->st->flush(ctx->st, 0, &fence);
      (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
      screen->fence_reference(screen, &fence, NULL);
   }
}
Ejemplo n.º 5
0
static void
dri_destroy_context(__DRIcontext * cPriv)
{
    TRACE;

    if (cPriv) {
	struct dri_context *ctx = dri_context(cPriv);
	struct gl_context *mesaCtx;

	mesaCtx = &ctx->Base;

        _mesa_meta_free(mesaCtx);
	_swsetup_DestroyContext( mesaCtx );
	_swrast_DestroyContext( mesaCtx );
	_tnl_DestroyContext( mesaCtx );
	_vbo_DestroyContext( mesaCtx );
	_mesa_destroy_context( mesaCtx );
    }
}
Ejemplo n.º 6
0
static void *
dri2_create_fence(__DRIcontext *_ctx)
{
   struct pipe_context *ctx = dri_context(_ctx)->st->pipe;
   struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);

   if (!fence)
      return NULL;

   ctx->flush(ctx, &fence->pipe_fence, 0);

   if (!fence->pipe_fence) {
      FREE(fence);
      return NULL;
   }

   fence->driscreen = dri_screen(_ctx->driScreenPriv);
   return fence;
}
GLboolean
dri_make_current(__DRIcontext * cPriv,
		 __DRIdrawable * driDrawPriv,
		 __DRIdrawable * driReadPriv)
{
   /* dri_util.c ensures cPriv is not null */
   struct dri_context *ctx = dri_context(cPriv);
   struct dri_drawable *draw = dri_drawable(driDrawPriv);
   struct dri_drawable *read = dri_drawable(driReadPriv);
   struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi);

   /* Flush the old context here so we don't have to flush on unbind() */
   if (old_st && old_st != ctx->st)
      old_st->flush(old_st, ST_FLUSH_FRONT, NULL);

   ++ctx->bind_count;

   if (!driDrawPriv && !driReadPriv)
      return ctx->stapi->make_current(ctx->stapi, ctx->st, NULL, NULL);
   else if (!driDrawPriv || !driReadPriv)
      return GL_FALSE;

   if (ctx->dPriv != driDrawPriv) {
      ctx->dPriv = driDrawPriv;
      draw->texture_stamp = driDrawPriv->lastStamp - 1;
   }
   if (ctx->rPriv != driReadPriv) {
      ctx->rPriv = driReadPriv;
      read->texture_stamp = driReadPriv->lastStamp - 1;
   }

   ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base);

   // This is ok to call here. If they are already init, it's a no-op.
   if (draw->textures[ST_ATTACHMENT_BACK_LEFT] && draw->textures[ST_ATTACHMENT_DEPTH_STENCIL]
      && ctx->pp)
         pp_init_fbos(ctx->pp, draw->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
            draw->textures[ST_ATTACHMENT_BACK_LEFT]->height0);

   return GL_TRUE;
}
Ejemplo n.º 8
0
/**
 * These are used for GLX_EXT_texture_from_pixmap
 */
static void
dri_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
                    GLint format, __DRIdrawable *dPriv)
{
   struct dri_context *ctx = dri_context(pDRICtx);
   struct st_context_iface *st = ctx->st;
   struct dri_drawable *drawable = dri_drawable(dPriv);
   struct pipe_resource *pt;

   if (st->thread_finish)
      st->thread_finish(st);

   dri_drawable_validate_att(ctx, drawable, ST_ATTACHMENT_FRONT_LEFT);

   /* Use the pipe resource associated with the X drawable */
   pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];

   if (pt) {
      enum pipe_format internal_format = pt->format;

      if (format == __DRI_TEXTURE_FORMAT_RGB)  {
         /* only need to cover the formats recognized by dri_fill_st_visual */
         switch (internal_format) {
         case PIPE_FORMAT_BGRA8888_UNORM:
            internal_format = PIPE_FORMAT_BGRX8888_UNORM;
            break;
         case PIPE_FORMAT_ARGB8888_UNORM:
            internal_format = PIPE_FORMAT_XRGB8888_UNORM;
            break;
         default:
            break;
         }
      }

      drawable->update_tex_buffer(drawable, ctx, pt);

      ctx->st->teximage(ctx->st,
            (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT,
            0, internal_format, pt, FALSE);
   }
}
GLboolean
dri_unbind_context(__DRIcontext * cPriv)
{
   /* dri_util.c ensures cPriv is not null */
   struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
   struct dri_context *ctx = dri_context(cPriv);
   struct st_api *stapi = screen->st_api;

   if (--ctx->bind_count == 0) {
      if (ctx->st == ctx->stapi->get_current(ctx->stapi)) {
         /* For conformance, unbind is supposed to flush the context.
          * However, if we do it here we might end up flushing a partially
          * destroyed context. Instead, we flush in dri_make_current and
          * in dri_destroy_context which should cover all the cases.
          */
         stapi->make_current(stapi, NULL, NULL, NULL);
      }
   }

   return GL_TRUE;
}
void
dri_destroy_context(__DRIcontext * cPriv)
{
   struct dri_context *ctx = dri_context(cPriv);

   if (ctx->hud) {
      hud_destroy(ctx->hud);
   }

   /* No particular reason to wait for command completion before
    * destroying a context, but we flush the context here
    * to avoid having to add code elsewhere to cope with flushing a
    * partially destroyed context.
    */
   ctx->st->flush(ctx->st, 0, NULL);
   ctx->st->destroy(ctx->st);

   if (ctx->pp)
      pp_free(ctx->pp);

   free(ctx);
}
void
dri_destroy_context(__DRIcontext * cPriv)
{
   struct dri_context *ctx = dri_context(cPriv);

   /* note: we are freeing values and nothing more because
    * driParseConfigFiles allocated values only - the rest
    * is owned by screen optionCache.
    */
   FREE(ctx->optionCache.values);

   /* No particular reason to wait for command completion before
    * destroying a context, but we flush the context here
    * to avoid having to add code elsewhere to cope with flushing a
    * partially destroyed context.
    */
   ctx->st->flush(ctx->st, 0, NULL);
   ctx->st->destroy(ctx->st);

   if (ctx->pp) pp_free(ctx->pp);

   FREE(ctx);
}
Ejemplo n.º 12
0
static __DRIimage *
dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
                         int depth, int level, unsigned *error,
                         void *loaderPrivate)
{
   __DRIimage *img;
   struct gl_context *ctx = ((struct st_context *)dri_context(context)->st)->ctx;
   struct gl_texture_object *obj;
   struct pipe_resource *tex;
   GLuint face = 0;

   obj = _mesa_lookup_texture(ctx, texture);
   if (!obj || obj->Target != target) {
      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
      return NULL;
   }

   tex = st_get_texobj_resource(obj);
   if (!tex) {
      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
      return NULL;
   }

   if (target == GL_TEXTURE_CUBE_MAP)
      face = depth;

   _mesa_test_texobj_completeness(ctx, obj);
   if (!obj->_BaseComplete || (level > 0 && !obj->_MipmapComplete)) {
      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
      return NULL;
   }

   if (level < obj->BaseLevel || level > obj->_MaxLevel) {
      *error = __DRI_IMAGE_ERROR_BAD_MATCH;
      return NULL;
   }

   if (target == GL_TEXTURE_3D && obj->Image[face][level]->Depth < depth) {
      *error = __DRI_IMAGE_ERROR_BAD_MATCH;
      return NULL;
   }

   img = CALLOC_STRUCT(__DRIimageRec);
   if (!img) {
      *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
      return NULL;
   }

   img->level = level;
   img->layer = depth;
   img->dri_format = driGLFormatToImageFormat(obj->Image[face][level]->TexFormat);

   img->loader_private = loaderPrivate;

   if (img->dri_format == __DRI_IMAGE_FORMAT_NONE) {
      *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
      free(img);
      return NULL;
   }

   pipe_resource_reference(&img->texture, tex);

   *error = __DRI_IMAGE_ERROR_SUCCESS;
   return img;
}
Ejemplo n.º 13
0
/**
 * DRI2 flush extension, the flush_with_flags function.
 *
 * \param context           the context
 * \param drawable          the drawable to flush
 * \param flags             a combination of _DRI2_FLUSH_xxx flags
 * \param throttle_reason   the reason for throttling, 0 = no throttling
 */
void
dri_flush(__DRIcontext *cPriv,
          __DRIdrawable *dPriv,
          unsigned flags,
          enum __DRI2throttleReason reason)
{
   struct dri_context *ctx = dri_context(cPriv);
   struct dri_drawable *drawable = dri_drawable(dPriv);
   unsigned flush_flags;
   boolean swap_msaa_buffers = FALSE;

   if (!ctx) {
      assert(0);
      return;
   }

   if (drawable) {
      /* prevent recursion */
      if (drawable->flushing)
         return;

      drawable->flushing = TRUE;
   }
   else {
      flags &= ~__DRI2_FLUSH_DRAWABLE;
   }

   /* Flush the drawable. */
   if ((flags & __DRI2_FLUSH_DRAWABLE) &&
       drawable->textures[ST_ATTACHMENT_BACK_LEFT]) {
      struct pipe_context *pipe = ctx->st->pipe;

      if (drawable->stvis.samples > 1 &&
          reason == __DRI2_THROTTLE_SWAPBUFFER) {
         /* Resolve the MSAA back buffer. */
         dri_pipe_blit(ctx->st->pipe,
                       drawable->textures[ST_ATTACHMENT_BACK_LEFT],
                       drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]);

         if (drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT] &&
             drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]) {
            swap_msaa_buffers = TRUE;
         }

         /* FRONT_LEFT is resolved in drawable->flush_frontbuffer. */
      }

      dri_postprocessing(ctx, drawable, ST_ATTACHMENT_BACK_LEFT);

      if (ctx->hud) {
         hud_draw(ctx->hud, drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
      }

      pipe->flush_resource(pipe, drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
   }

   flush_flags = 0;
   if (flags & __DRI2_FLUSH_CONTEXT)
      flush_flags |= ST_FLUSH_FRONT;
   if (reason == __DRI2_THROTTLE_SWAPBUFFER)
      flush_flags |= ST_FLUSH_END_OF_FRAME;

   /* Flush the context and throttle if needed. */
   if (dri_screen(ctx->sPriv)->throttling_enabled &&
       drawable &&
       (reason == __DRI2_THROTTLE_SWAPBUFFER ||
        reason == __DRI2_THROTTLE_FLUSHFRONT)) {
      /* Throttle.
       *
       * This pulls a fence off the throttling queue and waits for it if the
       * number of fences on the throttling queue has reached the desired
       * number.
       *
       * Then flushes to insert a fence at the current rendering position, and
       * pushes that fence on the queue. This requires that the st_context_iface
       * flush method returns a fence even if there are no commands to flush.
       */
      struct pipe_screen *screen = drawable->screen->base.screen;
      struct pipe_fence_handle *fence;

      fence = swap_fences_pop_front(drawable);
      if (fence) {
         (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
         screen->fence_reference(screen, &fence, NULL);
      }

      ctx->st->flush(ctx->st, flush_flags, &fence);

      if (fence) {
         swap_fences_push_back(drawable, fence);
         screen->fence_reference(screen, &fence, NULL);
      }
   }
   else if (flags & (__DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT)) {
      ctx->st->flush(ctx->st, flush_flags, NULL);
   }

   if (drawable) {
      drawable->flushing = FALSE;
   }

   /* Swap the MSAA front and back buffers, so that reading
    * from the front buffer after SwapBuffers returns what was
    * in the back buffer.
    */
   if (swap_msaa_buffers) {
      struct pipe_resource *tmp =
         drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT];

      drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT] =
         drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT];
      drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT] = tmp;

      /* Now that we have swapped the buffers, this tells the state
       * tracker to revalidate the framebuffer.
       */
      p_atomic_inc(&drawable->base.stamp);
   }
}