Example #1
0
status_t
GalliumContext::SetCurrentContext(Bitmap *bitmap, context_id contextID)
{
	CALLED();

	if (contextID < 0 || contextID > CONTEXT_MAX) {
		ERROR("%s: Invalid context ID range!\n", __func__);
		return B_ERROR;
	}

	Lock();
	context_id oldContextID = fCurrentContext;
	struct hgl_context* context = fContext[contextID];
	Unlock();

	if (!context) {
		ERROR("%s: Invalid context provided (#%" B_PRIu64 ")!\n",
			__func__, contextID);
		return B_ERROR;
	}

	struct st_api* api = context->api;

	if (!bitmap) {
		api->make_current(context->api, NULL, NULL, NULL);
		return B_OK;
	}

	// Everything seems valid, lets set the new context.
	fCurrentContext = contextID;

	if (oldContextID > 0 && oldContextID != contextID) {
		fContext[oldContextID]->st->flush(fContext[oldContextID]->st,
			ST_FLUSH_FRONT, NULL);
	}

	// We need to lock and unlock framebuffers before accessing them
	context->draw->Lock();
	context->read->Lock();
	api->make_current(context->api, context->st, context->draw->fBuffer,
		context->read->fBuffer);
	context->draw->Unlock();
	context->read->Unlock();

	if (context->textures[ST_ATTACHMENT_BACK_LEFT]
		&& context->textures[ST_ATTACHMENT_DEPTH_STENCIL]
		&& context->postProcess) {
		TRACE("Postprocessing textures...\n");
		pp_init_fbos(context->postProcess,
			context->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
			context->textures[ST_ATTACHMENT_BACK_LEFT]->height0);
	}

	context->bitmap = bitmap;
	//context->st->pipe->priv = context;

	return B_OK;
}
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;
}
Example #3
0
/**
 * Bind an OSMesaContext to an image buffer.  The image buffer is just a
 * block of memory which the client provides.  Its size must be at least
 * as large as width*height*pixelSize.  Its address should be a multiple
 * of 4 if using RGBA mode.
 *
 * By default, image data is stored in the order of glDrawPixels: row-major
 * order with the lower-left image pixel stored in the first array position
 * (ie. bottom-to-top).
 *
 * If the context's viewport hasn't been initialized yet, it will now be
 * initialized to (0,0,width,height).
 *
 * Input:  osmesa - the rendering context
 *         buffer - the image buffer memory
 *         type - data type for pixel components
 *                GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT
 *                or GL_FLOAT.
 *         width, height - size of image buffer in pixels, at least 1
 * Return:  GL_TRUE if success, GL_FALSE if error because of invalid osmesa,
 *          invalid type, invalid size, etc.
 */
GLAPI GLboolean GLAPIENTRY
OSMesaMakeCurrent(OSMesaContext osmesa, void *buffer, GLenum type,
                  GLsizei width, GLsizei height)
{
    struct st_api *stapi = get_st_api();
    struct osmesa_buffer *osbuffer;
    enum pipe_format color_format;

    if (!osmesa || !buffer || width < 1 || height < 1) {
        return GL_FALSE;
    }

    if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) {
        return GL_FALSE;
    }

    color_format = osmesa_choose_format(osmesa->format, type);
    if (color_format == PIPE_FORMAT_NONE) {
        fprintf(stderr, "OSMesaMakeCurrent(unsupported format/type)\n");
        return GL_FALSE;
    }

    /* See if we already have a buffer that uses these pixel formats */
    osbuffer = osmesa_find_buffer(color_format,
                                  osmesa->depth_stencil_format,
                                  osmesa->accum_format, width, height);
    if (!osbuffer) {
        /* Existing buffer found, create new buffer */
        osbuffer = osmesa_create_buffer(color_format,
                                        osmesa->depth_stencil_format,
                                        osmesa->accum_format);
    }

    osbuffer->width = width;
    osbuffer->height = height;
    osbuffer->map = buffer;

    /* XXX unused for now */
    (void) osmesa_destroy_buffer;

    osmesa->current_buffer = osbuffer;
    osmesa->type = type;

    stapi->make_current(stapi, osmesa->stctx, osbuffer->stfb, osbuffer->stfb);

    if (!osmesa->ever_used) {
        /* one-time init, just postprocessing for now */
        boolean any_pp_enabled = FALSE;
        unsigned i;

        for (i = 0; i < ARRAY_SIZE(osmesa->pp_enabled); i++) {
            if (osmesa->pp_enabled[i]) {
                any_pp_enabled = TRUE;
                break;
            }
        }

        if (any_pp_enabled) {
            osmesa->pp = pp_init(osmesa->stctx->pipe,
                                 osmesa->pp_enabled,
                                 osmesa->stctx->cso_context);

            pp_init_fbos(osmesa->pp, width, height);
        }

        osmesa->ever_used = TRUE;
    }

    return GL_TRUE;
}
/**
*	Main run function of the PP queue. Called on swapbuffers/flush.
*
*	Runs all requested filters in order and handles shuffling the temp
*	buffers in between.
*/
void
pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
       struct pipe_resource *out, struct pipe_resource *indepth)
{
   struct pipe_resource *refin = NULL, *refout = NULL;
   unsigned int i;

   if (in->width0 != ppq->p->framebuffer.width ||
       in->height0 != ppq->p->framebuffer.height) {
      pp_debug("Resizing the temp pp buffers\n");
      pp_free_fbos(ppq);
      pp_init_fbos(ppq, in->width0, in->height0);
   }

   if (in == out && ppq->n_filters == 1) {
      /* Make a copy of in to tmp[0] in this case. */
      unsigned int w = ppq->p->framebuffer.width;
      unsigned int h = ppq->p->framebuffer.height;

      util_blit_pixels(ppq->p->blitctx, in, 0, 0, 0,
                       w, h, 0, ppq->tmps[0],
                       0, 0, w, h, 0, PIPE_TEX_MIPFILTER_NEAREST,
                       TGSI_WRITEMASK_XYZW, 0);

      in = ppq->tmp[0];
   }

   // Kept only for this frame.
   pipe_resource_reference(&ppq->depth, indepth);
   pipe_resource_reference(&refin, in);
   pipe_resource_reference(&refout, out);

   switch (ppq->n_filters) {
   case 1:                     /* No temp buf */
      ppq->pp_queue[0] (ppq, in, out, 0);
      break;
   case 2:                     /* One temp buf */

      ppq->pp_queue[0] (ppq, in, ppq->tmp[0], 0);
      ppq->pp_queue[1] (ppq, ppq->tmp[0], out, 1);

      break;
   default:                    /* Two temp bufs */
      ppq->pp_queue[0] (ppq, in, ppq->tmp[0], 0);

      for (i = 1; i < (ppq->n_filters - 1); i++) {
         if (i % 2 == 0)
            ppq->pp_queue[i] (ppq, ppq->tmp[1], ppq->tmp[0], i);

         else
            ppq->pp_queue[i] (ppq, ppq->tmp[0], ppq->tmp[1], i);
      }

      if (i % 2 == 0)
         ppq->pp_queue[i] (ppq, ppq->tmp[1], out, i);

      else
         ppq->pp_queue[i] (ppq, ppq->tmp[0], out, i);

      break;
   }

   pipe_resource_reference(&ppq->depth, NULL);
   pipe_resource_reference(&refin, NULL);
   pipe_resource_reference(&refout, NULL);
}
Example #5
0
/**
*	Main run function of the PP queue. Called on swapbuffers/flush.
*
*	Runs all requested filters in order and handles shuffling the temp
*	buffers in between.
*/
void
pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
       struct pipe_resource *out, struct pipe_resource *indepth)
{
   struct pipe_resource *refin = NULL, *refout = NULL;
   unsigned int i;
   struct cso_context *cso = ppq->p->cso;

   if (ppq->n_filters == 0)
      return;

   assert(ppq->pp_queue);
   assert(ppq->tmp[0]);

   if (in->width0 != ppq->p->framebuffer.width ||
       in->height0 != ppq->p->framebuffer.height) {
      pp_debug("Resizing the temp pp buffers\n");
      pp_free_fbos(ppq);
      pp_init_fbos(ppq, in->width0, in->height0);
   }

   if (in == out && ppq->n_filters == 1) {
      /* Make a copy of in to tmp[0] in this case. */
      unsigned int w = ppq->p->framebuffer.width;
      unsigned int h = ppq->p->framebuffer.height;


      pp_blit(ppq->p->pipe, in, 0, 0,
              w, h, 0, ppq->tmps[0],
              0, 0, w, h);

      in = ppq->tmp[0];
   }

   /* save state (restored below) */
   cso_save_state(cso, (CSO_BIT_BLEND |
                        CSO_BIT_DEPTH_STENCIL_ALPHA |
                        CSO_BIT_FRAGMENT_SHADER |
                        CSO_BIT_FRAMEBUFFER |
                        CSO_BIT_TESSCTRL_SHADER |
                        CSO_BIT_TESSEVAL_SHADER |
                        CSO_BIT_GEOMETRY_SHADER |
                        CSO_BIT_RASTERIZER |
                        CSO_BIT_SAMPLE_MASK |
                        CSO_BIT_MIN_SAMPLES |
                        CSO_BIT_FRAGMENT_SAMPLERS |
                        CSO_BIT_FRAGMENT_SAMPLER_VIEWS |
                        CSO_BIT_STENCIL_REF |
                        CSO_BIT_STREAM_OUTPUTS |
                        CSO_BIT_VERTEX_ELEMENTS |
                        CSO_BIT_VERTEX_SHADER |
                        CSO_BIT_VIEWPORT |
                        CSO_BIT_AUX_VERTEX_BUFFER_SLOT |
                        CSO_BIT_PAUSE_QUERIES |
                        CSO_BIT_RENDER_CONDITION));
   cso_save_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
   cso_save_constant_buffer_slot0(cso, PIPE_SHADER_FRAGMENT);

   /* set default state */
   cso_set_sample_mask(cso, ~0);
   cso_set_min_samples(cso, 1);
   cso_set_stream_outputs(cso, 0, NULL, NULL);
   cso_set_tessctrl_shader_handle(cso, NULL);
   cso_set_tesseval_shader_handle(cso, NULL);
   cso_set_geometry_shader_handle(cso, NULL);
   cso_set_render_condition(cso, NULL, FALSE, 0);

   // Kept only for this frame.
   pipe_resource_reference(&ppq->depth, indepth);
   pipe_resource_reference(&refin, in);
   pipe_resource_reference(&refout, out);

   switch (ppq->n_filters) {
   case 0:
      /* Failsafe, but never reached. */
      break;
   case 1:                     /* No temp buf */
      ppq->pp_queue[0] (ppq, in, out, 0);
      break;
   case 2:                     /* One temp buf */

      ppq->pp_queue[0] (ppq, in, ppq->tmp[0], 0);
      ppq->pp_queue[1] (ppq, ppq->tmp[0], out, 1);

      break;
   default:                    /* Two temp bufs */
      assert(ppq->tmp[1]);
      ppq->pp_queue[0] (ppq, in, ppq->tmp[0], 0);

      for (i = 1; i < (ppq->n_filters - 1); i++) {
         if (i % 2 == 0)
            ppq->pp_queue[i] (ppq, ppq->tmp[1], ppq->tmp[0], i);

         else
            ppq->pp_queue[i] (ppq, ppq->tmp[0], ppq->tmp[1], i);
      }

      if (i % 2 == 0)
         ppq->pp_queue[i] (ppq, ppq->tmp[1], out, i);

      else
         ppq->pp_queue[i] (ppq, ppq->tmp[0], out, i);

      break;
   }

   /* restore state we changed */
   cso_restore_state(cso);
   cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
   cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_FRAGMENT);

   pipe_resource_reference(&ppq->depth, NULL);
   pipe_resource_reference(&refin, NULL);
   pipe_resource_reference(&refout, NULL);
}
Example #6
0
/**
*	Main run function of the PP queue. Called on swapbuffers/flush.
*
*	Runs all requested filters in order and handles shuffling the temp
*	buffers in between.
*/
void
pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
       struct pipe_resource *out, struct pipe_resource *indepth)
{
   struct pipe_resource *refin = NULL, *refout = NULL;
   unsigned int i;
   struct cso_context *cso = ppq->p->cso;

   if (in->width0 != ppq->p->framebuffer.width ||
       in->height0 != ppq->p->framebuffer.height) {
      pp_debug("Resizing the temp pp buffers\n");
      pp_free_fbos(ppq);
      pp_init_fbos(ppq, in->width0, in->height0);
   }

   if (in == out && ppq->n_filters == 1) {
      /* Make a copy of in to tmp[0] in this case. */
      unsigned int w = ppq->p->framebuffer.width;
      unsigned int h = ppq->p->framebuffer.height;

      util_blit_pixels(ppq->p->blitctx, in, 0, 0, 0,
                       w, h, 0, ppq->tmps[0],
                       0, 0, w, h, 0, PIPE_TEX_MIPFILTER_NEAREST,
                       TGSI_WRITEMASK_XYZW, 0);

      in = ppq->tmp[0];
   }

   /* save state (restored below) */
   cso_save_blend(cso);
   cso_save_depth_stencil_alpha(cso);
   cso_save_fragment_shader(cso);
   cso_save_framebuffer(cso);
   cso_save_geometry_shader(cso);
   cso_save_rasterizer(cso);
   cso_save_sample_mask(cso);
   cso_save_samplers(cso, PIPE_SHADER_FRAGMENT);
   cso_save_sampler_views(cso, PIPE_SHADER_FRAGMENT);
   cso_save_stencil_ref(cso);
   cso_save_stream_outputs(cso);
   cso_save_vertex_elements(cso);
   cso_save_vertex_shader(cso);
   cso_save_viewport(cso);
   cso_save_aux_vertex_buffer_slot(cso);
   cso_save_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
   cso_save_constant_buffer_slot0(cso, PIPE_SHADER_FRAGMENT);
   cso_save_render_condition(cso);

   /* set default state */
   cso_set_sample_mask(cso, ~0);
   cso_set_stream_outputs(cso, 0, NULL, 0);
   cso_set_geometry_shader_handle(cso, NULL);
   cso_set_render_condition(cso, NULL, 0);

   // Kept only for this frame.
   pipe_resource_reference(&ppq->depth, indepth);
   pipe_resource_reference(&refin, in);
   pipe_resource_reference(&refout, out);

   switch (ppq->n_filters) {
   case 1:                     /* No temp buf */
      ppq->pp_queue[0] (ppq, in, out, 0);
      break;
   case 2:                     /* One temp buf */

      ppq->pp_queue[0] (ppq, in, ppq->tmp[0], 0);
      ppq->pp_queue[1] (ppq, ppq->tmp[0], out, 1);

      break;
   default:                    /* Two temp bufs */
      ppq->pp_queue[0] (ppq, in, ppq->tmp[0], 0);

      for (i = 1; i < (ppq->n_filters - 1); i++) {
         if (i % 2 == 0)
            ppq->pp_queue[i] (ppq, ppq->tmp[1], ppq->tmp[0], i);

         else
            ppq->pp_queue[i] (ppq, ppq->tmp[0], ppq->tmp[1], i);
      }

      if (i % 2 == 0)
         ppq->pp_queue[i] (ppq, ppq->tmp[1], out, i);

      else
         ppq->pp_queue[i] (ppq, ppq->tmp[0], out, i);

      break;
   }

   /* restore state we changed */
   cso_restore_blend(cso);
   cso_restore_depth_stencil_alpha(cso);
   cso_restore_fragment_shader(cso);
   cso_restore_framebuffer(cso);
   cso_restore_geometry_shader(cso);
   cso_restore_rasterizer(cso);
   cso_restore_sample_mask(cso);
   cso_restore_samplers(cso, PIPE_SHADER_FRAGMENT);
   cso_restore_sampler_views(cso, PIPE_SHADER_FRAGMENT);
   cso_restore_stencil_ref(cso);
   cso_restore_stream_outputs(cso);
   cso_restore_vertex_elements(cso);
   cso_restore_vertex_shader(cso);
   cso_restore_viewport(cso);
   cso_restore_aux_vertex_buffer_slot(cso);
   cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
   cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_FRAGMENT);
   cso_restore_render_condition(cso);

   pipe_resource_reference(&ppq->depth, NULL);
   pipe_resource_reference(&refin, NULL);
   pipe_resource_reference(&refout, NULL);
}