/** Undo surface-to-texture binding */ int st_release_teximage(struct st_framebuffer *stfb, uint surfIndex, int target, int format, int level) { GET_CURRENT_CONTEXT(ctx); struct st_context *st = ctx->st; struct st_renderbuffer *strb; assert(surfIndex <= ST_SURFACE_DEPTH); strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer); if (!strb->texture_save || !strb->surface_save) { /* Error! */ return 0; } st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); /* free tex surface, restore original */ pipe_surface_reference(&strb->surface, strb->surface_save); pipe_texture_reference(&strb->texture, strb->texture_save); pipe_surface_reference(&strb->surface_save, NULL); pipe_texture_reference(&strb->texture_save, NULL); st->dirty.st |= ST_NEW_FRAMEBUFFER; return 1; }
static void st_context_flush(struct st_context_iface *stctxi, unsigned flags, struct pipe_fence_handle **fence) { struct st_context *st = (struct st_context *) stctxi; st_flush(st, fence); if (flags & ST_FLUSH_FRONT) st_manager_flush_frontbuffer(st); }
GLboolean nouveau_context_unbind(__DRIcontextPrivate *driContextPriv) { struct nouveau_context *nv = driContextPriv->driverPrivate; (void)nv; st_flush(nv->st, 0, NULL); return GL_TRUE; }
void st_finish(struct vg_context *st) { struct pipe_fence_handle *fence = NULL; st_flush(st, PIPE_FLUSH_RENDER_CACHE, &fence); st->pipe->screen->fence_finish(st->pipe->screen, fence, 0); st->pipe->screen->fence_reference(st->pipe->screen, &fence, NULL); }
void st_notify_swapbuffers(struct st_framebuffer *stfb) { struct vg_context *ctx = vg_current_context(); if (ctx && ctx->draw_buffer == stfb) { st_flush(ctx, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME, NULL); } }
/** * Flush, and wait for completion. */ void st_finish( struct st_context *st ) { struct pipe_fence_handle *fence = NULL; st_flush(st, &fence, 0); if(fence) { st->pipe->screen->fence_finish(st->pipe->screen, fence, PIPE_TIMEOUT_INFINITE); st->pipe->screen->fence_reference(st->pipe->screen, &fence, NULL); } }
/** Redirect rendering into stfb's surface to a texture image */ int st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex, int target, int format, int level) { GET_CURRENT_CONTEXT(ctx); struct st_context *st = ctx->st; struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; const GLuint unit = ctx->Texture.CurrentUnit; struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; struct gl_texture_object *texObj; struct gl_texture_image *texImage; struct st_texture_image *stImage; struct st_renderbuffer *strb; GLint face = 0, slice = 0; assert(surfIndex <= ST_SURFACE_DEPTH); strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer); if (strb->texture_save || strb->surface_save) { /* Error! */ return 0; } if (target == ST_TEXTURE_2D) { texObj = texUnit->CurrentTex[TEXTURE_2D_INDEX]; texImage = _mesa_get_tex_image(ctx, texObj, GL_TEXTURE_2D, level); stImage = st_texture_image(texImage); } else { /* unsupported target */ return 0; } st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); /* save the renderbuffer's surface/texture info */ pipe_texture_reference(&strb->texture_save, strb->texture); pipe_surface_reference(&strb->surface_save, strb->surface); /* plug in new surface/texture info */ pipe_texture_reference(&strb->texture, stImage->pt); strb->surface = screen->get_tex_surface(screen, strb->texture, face, level, slice, (PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE)); st->dirty.st |= ST_NEW_FRAMEBUFFER; return 1; }
static void st_context_flush(struct st_context_iface *stctxi, unsigned flags, struct pipe_fence_handle **fence) { struct st_context *st = (struct st_context *) stctxi; unsigned pipe_flags = 0; if (flags & ST_FLUSH_END_OF_FRAME) { pipe_flags |= PIPE_FLUSH_END_OF_FRAME; } st_flush(st, fence, pipe_flags); if (flags & ST_FLUSH_FRONT) st_manager_flush_frontbuffer(st); }
/** * Called via ctx->Driver.Flush() */ static void st_glFlush(struct gl_context *ctx) { struct st_context *st = st_context(ctx); /* Don't call st_finish() here. It is not the state tracker's * responsibilty to inject sleeps in the hope of avoiding buffer * synchronization issues. Calling finish() here will just hide * problems that need to be fixed elsewhere. */ st_flush(st, NULL, 0); if (is_front_buffer_dirty(st)) { display_front_buffer(st); } }
static void st_Accum(GLcontext *ctx, GLenum op, GLfloat value) { struct st_context *st = ctx->st; struct st_renderbuffer *acc_strb = st_renderbuffer(ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); struct st_renderbuffer *color_strb = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); const GLint xpos = ctx->DrawBuffer->_Xmin; const GLint ypos = ctx->DrawBuffer->_Ymin; const GLint width = ctx->DrawBuffer->_Xmax - xpos; const GLint height = ctx->DrawBuffer->_Ymax - ypos; if(!acc_strb->data) return; /* make sure color bufs aren't cached */ st_flush( st, PIPE_FLUSH_RENDER_CACHE, NULL ); switch (op) { case GL_ADD: if (value != 0.0F) { accum_mad(ctx, 1.0, value, xpos, ypos, width, height, acc_strb); } break; case GL_MULT: if (value != 1.0F) { accum_mad(ctx, value, 0.0, xpos, ypos, width, height, acc_strb); } break; case GL_ACCUM: if (value != 0.0F) { accum_accum(st, value, xpos, ypos, width, height, acc_strb, color_strb); } break; case GL_LOAD: accum_load(st, value, xpos, ypos, width, height, acc_strb, color_strb); break; case GL_RETURN: accum_return(ctx, value, xpos, ypos, width, height, acc_strb, color_strb); break; default: assert(0); } }
static void st_vdpau_unmap_surface(struct gl_context *ctx, GLenum target, GLenum access, GLboolean output, struct gl_texture_object *texObj, struct gl_texture_image *texImage, const void *vdpSurface, GLuint index) { struct st_context *st = st_context(ctx); struct st_texture_object *stObj = st_texture_object(texObj); struct st_texture_image *stImage = st_texture_image(texImage); pipe_resource_reference(&stObj->pt, NULL); st_texture_release_all_sampler_views(st, stObj); pipe_resource_reference(&stImage->pt, NULL); _mesa_dirty_texobj(ctx, texObj); st_flush(st, NULL, 0); }
bool hsp_make_current(Bitmap *bitmap, uint64 ctxId) { TRACE("%s(bitmap: %p ctxId: %d)\n", __FUNCTION__, bitmap, ctxId); struct hsp_context *ctx = NULL; GET_CURRENT_CONTEXT(glcurctx); GLuint width = 0; GLuint height = 0; struct hsp_context *curctx; if (!hsp_dev) { TRACE("%s> there's no hsp_dev so nothing to do\n", __FUNCTION__); return false; } pipe_mutex_lock(hsp_dev->mutex); ctx = hsp_lookup_context(ctxId); pipe_mutex_unlock(hsp_dev->mutex); if (ctx == NULL) { TRACE("%s> context not found\n", __FUNCTION__); return false; } current_bitmap = bitmap; current_ctx_id = ctxId; if (glcurctx != NULL) { curctx = (struct hsp_context*) glcurctx->DriverCtx; if (curctx != ctx) st_flush(glcurctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); } if (!bitmap || ctxId == 0) { st_make_current(NULL, NULL, NULL); return true; } if (glcurctx != NULL) { struct hsp_context *curctx = (struct hsp_context*) glcurctx->DriverCtx; if (curctx != NULL && curctx == ctx && ctx->bitmap == bitmap) return true; } if (bitmap != NULL) { get_bitmap_size(bitmap, &width, &height); TRACE("%s> found bitmap: %p with size: %dx%d\n", __FUNCTION__, bitmap, width, height); } if (ctx != NULL && bitmap != NULL ) { GLvisual *visual = &ctx->st->ctx->Visual; if (ctx->draw == NULL) { ctx->draw = framebuffer_create(bitmap, visual, width /*+ 1*/, height /*+ 1*/); } if ((hsp_dev->options & BGL_DOUBLE) == BGL_DOUBLE && ctx->read == NULL) { ctx->read = framebuffer_create(bitmap, visual, width /*+ 1*/, height /*+ 1*/); } } if (ctx) { if (ctx->draw && ctx->read == NULL) { st_make_current(ctx->st, ctx->draw->stfb, ctx->draw->stfb); framebuffer_resize(ctx->draw, width /*+ 1*/, height /*+ 1*/); } else if (ctx && ctx->draw && ctx->read) { st_make_current(ctx->st, ctx->draw->stfb, ctx->read->stfb); framebuffer_resize(ctx->draw, width /*+ 1*/, height /*+ 1*/); framebuffer_resize(ctx->read, width /*+ 1*/, height /*+ 1*/); } ctx->bitmap = bitmap; ctx->st->pipe->priv = bitmap; } else { st_make_current(NULL, NULL, NULL); } return true; }