frontend/dri: inline __DRIcontext in dri_context, make __DRIcontext opaque

This cleanup removes the dri_util structure __DRIcontext(Rec) that is
difficult to follow, and switches all code to using dri_context directly.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19741>
This commit is contained in:
Marek Olšák 2022-11-15 01:49:27 -05:00 committed by Marge Bot
parent c65bde7b1e
commit 0a622f61ea
10 changed files with 154 additions and 198 deletions

View file

@ -75,7 +75,8 @@ dri2_flush_drawable(__DRIdrawable *dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
dri_flush(drawable->driContextPriv, dPriv, __DRI2_FLUSH_DRAWABLE, -1);
dri_flush(opaque_dri_context(drawable->ctx), dPriv, __DRI2_FLUSH_DRAWABLE,
-1);
}
/**
@ -444,9 +445,8 @@ dri2_set_in_fence_fd(__DRIimage *img, int fd)
}
static void
handle_in_fence(__DRIcontext *context, __DRIimage *img)
handle_in_fence(struct dri_context *ctx, __DRIimage *img)
{
struct dri_context *ctx = dri_context(context);
struct pipe_context *pipe = ctx->st->pipe;
struct pipe_fence_handle *fence;
int fd = img->in_fence_fd;
@ -576,7 +576,7 @@ dri2_allocate_textures(struct dri_context *ctx,
drawable->h = texture->height0;
pipe_resource_reference(buf, texture);
handle_in_fence(ctx->cPriv, images.front);
handle_in_fence(ctx, images.front);
}
if (images.image_mask & __DRI_IMAGE_BUFFER_BACK) {
@ -588,7 +588,7 @@ dri2_allocate_textures(struct dri_context *ctx,
drawable->h = texture->height0;
pipe_resource_reference(buf, texture);
handle_in_fence(ctx->cPriv, images.back);
handle_in_fence(ctx, images.back);
}
if (images.image_mask & __DRI_IMAGE_BUFFER_SHARED) {
@ -600,7 +600,7 @@ dri2_allocate_textures(struct dri_context *ctx,
drawable->h = texture->height0;
pipe_resource_reference(buf, texture);
handle_in_fence(ctx->cPriv, images.back);
handle_in_fence(ctx, images.back);
ctx->is_shared_buffer_bound = true;
} else {
@ -1812,7 +1812,7 @@ dri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src,
if (ctx->st->thread_finish)
ctx->st->thread_finish(ctx->st);
handle_in_fence(context, dst);
handle_in_fence(ctx, dst);
memset(&blit, 0, sizeof(blit));
blit.dst.resource = dst->texture;
@ -1838,7 +1838,7 @@ dri2_blit_image(__DRIcontext *context, __DRIimage *dst, __DRIimage *src,
pipe->flush_resource(pipe, dst->texture);
ctx->st->flush(ctx->st, 0, NULL, NULL, NULL);
} else if (flush_flag == __BLIT_FLAG_FINISH) {
screen = dri_screen(ctx->sPriv)->base.screen;
screen = ctx->screen->base.screen;
pipe->flush_resource(pipe, dst->texture);
ctx->st->flush(ctx->st, 0, &fence, NULL, NULL);
(void) screen->fence_finish(screen, NULL, fence, PIPE_TIMEOUT_INFINITE);
@ -1870,7 +1870,7 @@ dri2_map_image(__DRIcontext *context, __DRIimage *image,
if (ctx->st->thread_finish)
ctx->st->thread_finish(ctx->st);
handle_in_fence(context, image);
handle_in_fence(ctx, image);
struct pipe_resource *resource = image->texture;
while (plane--)

View file

@ -41,15 +41,14 @@
#include "util/u_memory.h"
#include "util/u_debug.h"
GLboolean
dri_create_context(gl_api api, const struct gl_config * visual,
__DRIcontext * cPriv,
struct dri_context *
dri_create_context(struct dri_screen *screen,
gl_api api, const struct gl_config *visual,
const struct __DriverContextConfig *ctx_config,
unsigned *error,
void *sharedContextPrivate)
struct dri_context *sharedContextPrivate,
void *loaderPrivate)
{
__DRIscreen *sPriv = cPriv->driScreenPriv;
struct dri_screen *screen = dri_screen(sPriv);
struct dri_context *ctx = NULL;
struct st_context_iface *st_share = NULL;
struct st_context_attribs attribs;
@ -155,9 +154,8 @@ dri_create_context(gl_api api, const struct gl_config * visual,
goto fail;
}
cPriv->driverPrivate = ctx;
ctx->cPriv = cPriv;
ctx->sPriv = sPriv;
ctx->screen = screen;
ctx->loaderPrivate = loaderPrivate;
/* KHR_no_error is likely to crash, overflow memory, etc if an application
* has errors so don't enable it for setuid processes.
@ -217,7 +215,7 @@ dri_create_context(gl_api api, const struct gl_config * visual,
if (backgroundCallable &&
backgroundCallable->base.version >= 2 &&
backgroundCallable->isThreadSafe &&
!backgroundCallable->isThreadSafe(cPriv->loaderPrivate))
!backgroundCallable->isThreadSafe(loaderPrivate))
safe = false;
if (safe)
@ -225,21 +223,19 @@ dri_create_context(gl_api api, const struct gl_config * visual,
}
*error = __DRI_CTX_ERROR_SUCCESS;
return GL_TRUE;
return ctx;
fail:
if (ctx && ctx->st)
ctx->st->destroy(ctx->st);
free(ctx);
return GL_FALSE;
return NULL;
}
void
dri_destroy_context(__DRIcontext * cPriv)
dri_destroy_context(struct dri_context *ctx)
{
struct dri_context *ctx = dri_context(cPriv);
/* Wait for glthread to finish because we can't use pipe_context from
* multiple threads.
*/
@ -265,10 +261,9 @@ dri_destroy_context(__DRIcontext * cPriv)
/* This is called inside MakeCurrent to unbind the context. */
GLboolean
dri_unbind_context(__DRIcontext * cPriv)
dri_unbind_context(struct dri_context *ctx)
{
/* dri_util.c ensures cPriv is not null */
struct dri_context *ctx = dri_context(cPriv);
struct st_context_iface *st = ctx->st;
if (st == st_api_get_current()) {
@ -281,19 +276,52 @@ dri_unbind_context(__DRIcontext * cPriv)
st_api_make_current(NULL, NULL, NULL);
}
ctx->draw = NULL;
ctx->read = NULL;
if (ctx->draw || ctx->read) {
assert(ctx->draw);
if (ctx->draw->refcount == 0) {
/* ERROR!!! */
return GL_FALSE;
}
dri_put_drawable(ctx->draw);
if (ctx->read != ctx->draw) {
if (ctx->read->refcount == 0) {
/* ERROR!!! */
return GL_FALSE;
}
dri_put_drawable(ctx->read);
}
ctx->draw = NULL;
ctx->read = NULL;
}
return GL_TRUE;
}
GLboolean
dri_make_current(__DRIcontext * cPriv,
dri_make_current(struct dri_context *ctx,
struct dri_drawable *draw,
struct dri_drawable *read)
{
/* dri_util.c ensures cPriv is not null */
struct dri_context *ctx = dri_context(cPriv);
struct dri_drawable *old_draw = ctx->draw;
struct dri_drawable *old_read = ctx->read;
/* Bind the drawable to the context */
ctx->draw = draw;
ctx->read = read;
if (draw) {
draw->ctx = ctx;
dri_get_drawable(draw);
}
if (read && draw != read)
dri_get_drawable(read);
/* Wait for glthread to finish because we can't use st_context from
* multiple threads.
@ -306,14 +334,10 @@ dri_make_current(__DRIcontext * cPriv,
else if (!draw || !read)
return GL_FALSE;
if (ctx->draw != draw) {
ctx->draw = draw;
if (old_draw != draw)
draw->texture_stamp = draw->lastStamp - 1;
}
if (ctx->read != read) {
ctx->read = read;
if (old_read != read)
read->texture_stamp = read->lastStamp - 1;
}
st_api_make_current(ctx->st, &draw->base, &read->base);

View file

@ -40,13 +40,21 @@ struct pipe_context;
struct pipe_fence;
struct st_context_iface;
struct dri_drawable;
struct dri_screen;
struct dri_context
{
/* dri */
__DRIscreen *sPriv;
__DRIcontext *cPriv;
struct dri_screen *screen;
/**
* Pointer to drawable currently bound to this context for drawing.
*/
struct dri_drawable *draw;
/**
* Pointer to drawable currently bound to this context for reading.
*/
struct dri_drawable *read;
/**
@ -55,6 +63,16 @@ struct dri_context
*/
bool is_shared_buffer_bound;
/**
* The loaders's private context data. This structure is opaque.
*/
void *loaderPrivate;
struct {
int draw_stamp;
int read_stamp;
} dri2;
/* gallium */
struct st_context_iface *st;
struct pp_queue_t *pp;
@ -62,35 +80,39 @@ struct dri_context
};
static inline struct dri_context *
dri_context(__DRIcontext * driContextPriv)
dri_context(__DRIcontext *driContextPriv)
{
if (!driContextPriv)
return NULL;
return (struct dri_context *)driContextPriv->driverPrivate;
return (struct dri_context *)driContextPriv;
}
static inline __DRIcontext *
opaque_dri_context(struct dri_context *ctx)
{
return (__DRIcontext *)ctx;
}
/***********************************************************************
* dri_context.c
*/
void dri_destroy_context(__DRIcontext * driContextPriv);
void dri_destroy_context(struct dri_context *ctx);
boolean dri_unbind_context(__DRIcontext * driContextPriv);
boolean dri_unbind_context(struct dri_context *ctx);
boolean
dri_make_current(__DRIcontext * driContextPriv,
dri_make_current(struct dri_context *ctx,
struct dri_drawable *draw,
struct dri_drawable *read);
struct dri_context *
dri_get_current(__DRIscreen * driScreenPriv);
boolean
dri_create_context(gl_api api,
const struct gl_config * visual,
__DRIcontext * driContextPriv,
struct dri_context *
dri_create_context(struct dri_screen *screen,
gl_api api, const struct gl_config *visual,
const struct __DriverContextConfig *ctx_config,
unsigned *error,
void *sharedContextPrivate);
struct dri_context *sharedContextPrivate,
void *loaderPrivate);
#endif

View file

@ -158,7 +158,7 @@ dri_create_buffer(__DRIscreen *sPriv, const struct gl_config *visual,
drawable->loaderPrivate = loaderPrivate;
drawable->sPriv = sPriv;
drawable->driContextPriv = NULL;
drawable->ctx = NULL;
drawable->refcount = 1;
drawable->lastStamp = 0;
drawable->w = 0;
@ -186,7 +186,7 @@ fail:
return NULL;
}
void
static void
dri_destroy_buffer(struct dri_drawable *drawable)
{
struct dri_screen *screen = drawable->screen;
@ -207,6 +207,18 @@ dri_destroy_buffer(struct dri_drawable *drawable)
FREE(drawable);
}
void
dri_put_drawable(struct dri_drawable *drawable)
{
if (drawable) {
drawable->refcount--;
if (drawable->refcount)
return;
dri_destroy_buffer(drawable);
}
}
/**
* Validate the texture at an attachment. Allocate the texture if it does not
* exist. Used by the TFP extension.
@ -515,7 +527,7 @@ dri_flush(__DRIcontext *cPriv,
flush_flags |= ST_FLUSH_END_OF_FRAME;
/* Flush the context and throttle if needed. */
if (dri_screen(ctx->sPriv)->throttle &&
if (ctx->screen->throttle &&
drawable &&
(reason == __DRI2_THROTTLE_SWAPBUFFER ||
reason == __DRI2_THROTTLE_FLUSHFRONT)) {

View file

@ -70,7 +70,7 @@ struct dri_drawable
/**
* Pointer to context to which this drawable is currently bound.
*/
__DRIcontext *driContextPriv;
struct dri_context *ctx;
/**
* Reference count for number of context's currently bound to this
@ -124,6 +124,12 @@ opaque_dri_drawable(struct dri_drawable *drawable)
return (__DRIdrawable *)drawable;
}
static inline void
dri_get_drawable(struct dri_drawable *drawable)
{
drawable->refcount++;
}
/***********************************************************************
* dri_drawable.c
*/
@ -131,7 +137,8 @@ struct dri_drawable *
dri_create_buffer(__DRIscreen *sPriv, const struct gl_config *visual,
bool isPixmap, void *loaderPrivate);
void dri_destroy_buffer(struct dri_drawable *drawable);
void
dri_put_drawable(struct dri_drawable *drawable);
void
dri_drawable_get_format(struct dri_drawable *drawable,

View file

@ -90,7 +90,8 @@ static unsigned dri2_fence_get_caps(__DRIscreen *_screen)
static void *
dri2_create_fence(__DRIcontext *_ctx)
{
struct st_context_iface *stapi = dri_context(_ctx)->st;
struct dri_context *ctx = dri_context(_ctx);
struct st_context_iface *stapi = ctx->st;
struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
if (!fence)
@ -109,14 +110,15 @@ dri2_create_fence(__DRIcontext *_ctx)
return NULL;
}
fence->driscreen = dri_screen(_ctx->driScreenPriv);
fence->driscreen = ctx->screen;
return fence;
}
static void *
dri2_create_fence_fd(__DRIcontext *_ctx, int fd)
{
struct st_context_iface *stapi = dri_context(_ctx)->st;
struct dri_context *dri_ctx = dri_context(_ctx);
struct st_context_iface *stapi = dri_ctx->st;
struct pipe_context *ctx = stapi->pipe;
struct dri2_fence *fence = CALLOC_STRUCT(dri2_fence);
@ -138,7 +140,7 @@ dri2_create_fence_fd(__DRIcontext *_ctx, int fd)
return NULL;
}
fence->driscreen = dri_screen(_ctx->driScreenPriv);
fence->driscreen = dri_ctx->screen;
return fence;
}
@ -292,7 +294,8 @@ dri2_create_image_from_renderbuffer2(__DRIcontext *context,
int renderbuffer, void *loaderPrivate,
unsigned *error)
{
struct st_context_iface *st = dri_context(context)->st;
struct dri_context *dri_ctx = dri_context(context);
struct st_context_iface *st = dri_ctx->st;
struct st_context *st_ctx = (struct st_context *)st;
struct gl_context *ctx = st_ctx->ctx;
struct pipe_context *p_ctx = st_ctx->pipe;
@ -338,7 +341,7 @@ dri2_create_image_from_renderbuffer2(__DRIcontext *context,
img->dri_format = driGLFormatToImageFormat(rb->Format);
img->internal_format = rb->InternalFormat;
img->loader_private = loaderPrivate;
img->sPriv = context->driScreenPriv;
img->sPriv = dri_ctx->screen->sPriv;
img->in_fence_fd = -1;
pipe_resource_reference(&img->texture, tex);
@ -393,7 +396,8 @@ dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
void *loaderPrivate)
{
__DRIimage *img;
struct st_context_iface *st = dri_context(context)->st;
struct dri_context *dri_ctx = dri_context(context);
struct st_context_iface *st = dri_ctx->st;
struct st_context *st_ctx = (struct st_context *)st;
struct gl_context *ctx = st_ctx->ctx;
struct pipe_context *p_ctx = st_ctx->pipe;
@ -449,7 +453,7 @@ dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
img->internal_format = obj->Image[face][level]->InternalFormat;
img->loader_private = loaderPrivate;
img->sPriv = context->driScreenPriv;
img->sPriv = dri_ctx->screen->sPriv;
pipe_resource_reference(&img->texture, tex);

View file

@ -814,10 +814,10 @@ dri_set_background_context(struct st_context_iface *st,
{
struct dri_context *ctx = (struct dri_context *)st->st_manager_private;
const __DRIbackgroundCallableExtension *backgroundCallable =
ctx->sPriv->dri2.backgroundCallable;
ctx->screen->sPriv->dri2.backgroundCallable;
if (backgroundCallable)
backgroundCallable->setBackgroundContext(ctx->cPriv->loaderPrivate);
backgroundCallable->setBackgroundContext(ctx->loaderPrivate);
if (ctx->hud)
hud_add_queue_for_monitoring(ctx->hud, queue_info);

View file

@ -452,9 +452,7 @@ driCreateContextAttribs(__DRIscreen *screen, int api,
unsigned *error,
void *data)
{
__DRIcontext *context;
const struct gl_config *modes = (config != NULL) ? &config->modes : NULL;
void *shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
gl_api mesa_api;
struct __DriverContextConfig ctx_config;
@ -628,26 +626,11 @@ driCreateContextAttribs(__DRIscreen *screen, int api,
error))
return NULL;
context = calloc(1, sizeof *context);
if (!context) {
*error = __DRI_CTX_ERROR_NO_MEMORY;
return NULL;
}
context->loaderPrivate = data;
context->driScreenPriv = screen;
context->draw = NULL;
context->read = NULL;
if (!dri_create_context(mesa_api, modes, context, &ctx_config, error,
shareCtx)) {
free(context);
return NULL;
}
*error = __DRI_CTX_ERROR_SUCCESS;
return context;
struct dri_context *ctx = dri_create_context(dri_screen(screen), mesa_api,
modes, &ctx_config, error,
dri_context(shared),
data);
return opaque_dri_context(ctx);
}
static __DRIcontext *
@ -679,10 +662,8 @@ driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
static void
driDestroyContext(__DRIcontext *pcp)
{
if (pcp) {
dri_destroy_context(pcp);
free(pcp);
}
if (pcp)
dri_destroy_context(dri_context(pcp));
}
static int
@ -702,9 +683,6 @@ driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
/*****************************************************************/
/*@{*/
static void dri_get_drawable(struct dri_drawable *drawable);
static void dri_put_drawable(struct dri_drawable *drawable);
/**
* This function takes both a read buffer and a draw buffer. This is needed
* for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
@ -716,28 +694,14 @@ static int driBindContext(__DRIcontext *pcp,
{
/*
** Assume error checking is done properly in glXMakeCurrent before
** calling driUnbindContext.
** calling driBindContext.
*/
if (!pcp)
return GL_FALSE;
struct dri_drawable *draw = dri_drawable(pdp);
struct dri_drawable *read = dri_drawable(prp);
/* Bind the drawable to the context */
pcp->draw = draw;
pcp->read = read;
if (draw) {
draw->driContextPriv = pcp;
dri_get_drawable(draw);
}
if (prp && pdp != prp) {
dri_get_drawable(read);
}
return dri_make_current(pcp, draw, read);
return dri_make_current(dri_context(pcp), dri_drawable(pdp),
dri_drawable(prp));
}
/**
@ -770,57 +734,11 @@ static int driUnbindContext(__DRIcontext *pcp)
** Call dri_unbind_context before checking for valid drawables
** to handle surfaceless contexts properly.
*/
dri_unbind_context(pcp);
struct dri_drawable *draw = pcp->draw;
struct dri_drawable *read = pcp->read;
/* already unbound */
if (!draw && !read)
return GL_TRUE;
assert(draw);
if (draw->refcount == 0) {
/* ERROR!!! */
return GL_FALSE;
}
dri_put_drawable(draw);
if (read != draw) {
if (read->refcount == 0) {
/* ERROR!!! */
return GL_FALSE;
}
dri_put_drawable(read);
}
pcp->draw = NULL;
pcp->read = NULL;
return GL_TRUE;
return dri_unbind_context(dri_context(pcp));
}
/*@}*/
static void dri_get_drawable(struct dri_drawable *drawable)
{
drawable->refcount++;
}
static void dri_put_drawable(struct dri_drawable *drawable)
{
if (drawable) {
drawable->refcount--;
if (drawable->refcount)
return;
dri_destroy_buffer(drawable);
}
}
static __DRIdrawable *
driCreateNewDrawable(__DRIscreen *screen,
const __DRIconfig *config,

View file

@ -207,41 +207,6 @@ struct __DRIscreenRec {
unsigned int api_mask;
};
/**
* Per-context private driver information.
*/
struct __DRIcontextRec {
/**
* Device driver's private context data. This structure is opaque.
*/
void *driverPrivate;
/**
* The loaders's private context data. This structure is opaque.
*/
void *loaderPrivate;
/**
* Pointer to drawable currently bound to this context for drawing.
*/
struct dri_drawable *draw;
/**
* Pointer to drawable currently bound to this context for reading.
*/
struct dri_drawable *read;
/**
* Pointer to screen on which this context was created.
*/
__DRIscreen *driScreenPriv;
struct {
int draw_stamp;
int read_stamp;
} dri2;
};
extern uint32_t
driGLFormatToImageFormat(mesa_format format);

View file

@ -75,7 +75,8 @@ kopper_flush_drawable(__DRIdrawable *dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
dri_flush(drawable->driContextPriv, dPriv, __DRI2_FLUSH_DRAWABLE, -1);
dri_flush(opaque_dri_context(drawable->ctx), dPriv, __DRI2_FLUSH_DRAWABLE,
-1);
}
static inline void
@ -376,9 +377,8 @@ dri3_create_image(xcb_connection_t *c,
static void
handle_in_fence(__DRIcontext *context, __DRIimage *img)
handle_in_fence(struct dri_context *ctx, __DRIimage *img)
{
struct dri_context *ctx = dri_context(context);
struct pipe_context *pipe = ctx->st->pipe;
struct pipe_fence_handle *fence;
int fd = img->in_fence_fd;
@ -631,7 +631,7 @@ XXX do this once swapinterval is hooked up
#ifdef VK_USE_PLATFORM_XCB_KHR
else if (is_pixmap && statts[i] == ST_ATTACHMENT_FRONT_LEFT && !kscreen->is_sw) {
drawable->textures[statts[i]] = kopper_get_pixmap_buffer(cdraw, format);
handle_in_fence(ctx->cPriv, cdraw->image);
handle_in_fence(ctx, cdraw->image);
}
#endif
else {
@ -926,7 +926,11 @@ kopperSwapBuffers(__DRIdrawable *dPriv)
ctx->st->thread_finish(ctx->st);
drawable->texture_stamp = drawable->lastStamp - 1;
dri_flush(ctx->cPriv, opaque_dri_drawable(drawable), __DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT, __DRI2_THROTTLE_SWAPBUFFER);
dri_flush(opaque_dri_context(ctx), opaque_dri_drawable(drawable),
__DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT,
__DRI2_THROTTLE_SWAPBUFFER);
kopper_copy_to_front(ctx->st->pipe, drawable, ptex);
if (kdraw->is_window && !zink_kopper_check(ptex))
return -1;