mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 05:08:08 +02:00
st/dri/sw: add drisw_api similarly to dri1_api
I am pretty sure that this is in gallium spirit, so commit. Thanks to Chia-I for suggesting this.
This commit is contained in:
parent
6cc5fbd76b
commit
625e024b18
10 changed files with 148 additions and 109 deletions
|
|
@ -7,14 +7,14 @@
|
|||
|
||||
#include "state_tracker/drm_api.h"
|
||||
|
||||
struct drm_clip_rect;
|
||||
|
||||
struct pipe_screen;
|
||||
struct pipe_winsys;
|
||||
struct pipe_buffer;
|
||||
struct pipe_context;
|
||||
struct pipe_texture;
|
||||
|
||||
struct drm_clip_rect;
|
||||
|
||||
struct dri1_api_version
|
||||
{
|
||||
int major;
|
||||
|
|
@ -31,8 +31,8 @@ struct dri1_api_lock_funcs
|
|||
{
|
||||
void (*lock) (struct pipe_context * pipe);
|
||||
void (*unlock) (struct pipe_context * locked_pipe);
|
||||
boolean(*is_locked) (struct pipe_context * locked_pipe);
|
||||
boolean(*is_lock_lost) (struct pipe_context * locked_pipe);
|
||||
boolean(*is_locked) (struct pipe_context * locked_pipe);
|
||||
boolean(*is_lock_lost) (struct pipe_context * locked_pipe);
|
||||
void (*clear_lost_lock) (struct pipe_context * locked_pipe);
|
||||
};
|
||||
|
||||
|
|
|
|||
35
src/gallium/include/state_tracker/drisw_api.h
Normal file
35
src/gallium/include/state_tracker/drisw_api.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef _DRISW_API_H_
|
||||
#define _DRISW_API_H_
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_format.h"
|
||||
|
||||
#include "state_tracker/drm_api.h"
|
||||
|
||||
struct pipe_screen;
|
||||
struct pipe_winsys;
|
||||
struct pipe_buffer;
|
||||
struct pipe_context;
|
||||
struct pipe_texture;
|
||||
|
||||
struct dri_drawable;
|
||||
|
||||
/**
|
||||
* This callback struct is intended for the winsys to call the loader.
|
||||
*/
|
||||
|
||||
struct drisw_loader_funcs
|
||||
{
|
||||
void (*put_image) (struct dri_drawable *dri_drawable,
|
||||
void *data, unsigned width, unsigned height);
|
||||
};
|
||||
|
||||
struct drisw_create_screen_arg
|
||||
{
|
||||
struct drm_create_screen_arg base;
|
||||
|
||||
struct drisw_loader_funcs *lf;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -80,7 +80,7 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi,
|
|||
}
|
||||
#else
|
||||
if (new_stamp)
|
||||
drisw_update_drawable_info(drawable->dPriv);
|
||||
drisw_update_drawable_info(drawable);
|
||||
|
||||
drisw_allocate_textures(drawable, statt_mask);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -404,6 +404,19 @@ dri1_allocate_textures(struct dri_drawable *drawable,
|
|||
drawable->old_h = height;
|
||||
}
|
||||
|
||||
/*
|
||||
* Backend function for init_screen.
|
||||
*/
|
||||
|
||||
static const __DRIextension *dri1_screen_extensions[] = {
|
||||
&driReadDrawableExtension,
|
||||
&driCopySubBufferExtension.base,
|
||||
&driSwapControlExtension.base,
|
||||
&driFrameTrackingExtension.base,
|
||||
&driMediaStreamCounterExtension.base,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
st_dri_lock(struct pipe_context *pipe)
|
||||
{
|
||||
|
|
@ -442,21 +455,6 @@ static struct dri1_api_lock_funcs dri1_lf = {
|
|||
.clear_lost_lock = st_dri_clear_lost_lock
|
||||
};
|
||||
|
||||
/*
|
||||
* Backend function for init_screen.
|
||||
*/
|
||||
|
||||
static const __DRIextension *dri1_screen_extensions[] = {
|
||||
&driReadDrawableExtension,
|
||||
&driCopySubBufferExtension.base,
|
||||
&driSwapControlExtension.base,
|
||||
&driFrameTrackingExtension.base,
|
||||
&driMediaStreamCounterExtension.base,
|
||||
NULL
|
||||
};
|
||||
|
||||
struct dri1_api *__dri1_api_hooks = NULL;
|
||||
|
||||
static INLINE void
|
||||
dri1_copy_version(struct dri1_api_version *dst,
|
||||
const struct __DRIversionRec *src)
|
||||
|
|
@ -466,6 +464,8 @@ dri1_copy_version(struct dri1_api_version *dst,
|
|||
dst->patch_level = src->patch;
|
||||
}
|
||||
|
||||
struct dri1_api *__dri1_api_hooks = NULL;
|
||||
|
||||
const __DRIconfig **
|
||||
dri1_init_screen(__DRIscreen * sPriv)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,38 +27,18 @@
|
|||
**************************************************************************/
|
||||
|
||||
/* TODO:
|
||||
*
|
||||
* stride:
|
||||
*
|
||||
* The driver and the loaders (libGL, xserver/glx) compute the stride from the
|
||||
* width independently. winsys has a workaround that works for softpipe but may
|
||||
* explode for other drivers or platforms, rendering- or performance-wise.
|
||||
* Solving this issue properly requires extending the DRISW loader extension,
|
||||
* in order to make the stride available to the putImage callback.
|
||||
*
|
||||
* drisw_api:
|
||||
*
|
||||
* Define drisw_api similarly to dri1_api and use it to call the loader. This
|
||||
* is predicated on support for calling the loader from the winsys, which has
|
||||
* to grow for DRI2 as well.
|
||||
*
|
||||
* xshm / texture_from_pixmap / EGLImage:
|
||||
*
|
||||
* Allow the loaders to use the XSHM extension. It probably requires callbacks
|
||||
* for createImage/destroyImage similar to DRI2 getBuffers. Probably not worth
|
||||
* it, given the scope of DRISW, unless it falls naturally from properly
|
||||
* solving the other issues.
|
||||
*
|
||||
* fences:
|
||||
*
|
||||
* No fences are used, are they needed for llvmpipe / cell ?
|
||||
* for createImage/destroyImage similar to DRI2 getBuffers.
|
||||
*/
|
||||
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_inlines.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "state_tracker/drm_api.h"
|
||||
#include "state_tracker/drisw_api.h"
|
||||
|
||||
#include "dri_screen.h"
|
||||
#include "dri_context.h"
|
||||
|
|
@ -80,60 +60,47 @@ get_drawable_info(__DRIdrawable *dPriv, int *w, int *h)
|
|||
dPriv->loaderPrivate);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the width to 'stride / cpp'. PutImage seems to correctly clip the width
|
||||
* to the actual width of the dst drawable. Even if this is not specified but
|
||||
* an implementation detail, it is the correct thing to do, so rely on it. XXX
|
||||
*/
|
||||
static INLINE void
|
||||
put_image(__DRIdrawable *dPriv, void *data, unsigned width)
|
||||
put_image(__DRIdrawable *dPriv, void *data, unsigned width, unsigned height)
|
||||
{
|
||||
__DRIscreen *sPriv = dPriv->driScreenPriv;
|
||||
const __DRIswrastLoaderExtension *loader = sPriv->swrast_loader;
|
||||
|
||||
loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
|
||||
0, 0, width, dPriv->h,
|
||||
0, 0, width, height,
|
||||
data, dPriv->loaderPrivate);
|
||||
}
|
||||
|
||||
void
|
||||
drisw_update_drawable_info(__DRIdrawable *dPriv)
|
||||
drisw_update_drawable_info(struct dri_drawable *drawable)
|
||||
{
|
||||
__DRIdrawable *dPriv = drawable->dPriv;
|
||||
|
||||
get_drawable_info(dPriv, &dPriv->w, &dPriv->h);
|
||||
}
|
||||
|
||||
static void
|
||||
drisw_put_image(struct dri_drawable *drawable,
|
||||
void *data, unsigned width, unsigned height)
|
||||
{
|
||||
__DRIdrawable *dPriv = drawable->dPriv;
|
||||
|
||||
put_image(dPriv, data, width, height);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
drisw_present_texture(__DRIdrawable *dPriv,
|
||||
struct pipe_texture *ptex)
|
||||
{
|
||||
struct dri_drawable *drawable = dri_drawable(dPriv);
|
||||
struct dri_screen *screen = dri_screen(drawable->sPriv);
|
||||
struct pipe_context *pipe;
|
||||
struct pipe_surface *psurf;
|
||||
struct pipe_transfer *ptrans;
|
||||
void *pmap;
|
||||
unsigned width;
|
||||
|
||||
pipe = dri1_get_pipe_context(screen);
|
||||
psurf = dri1_get_pipe_surface(drawable, ptex);
|
||||
if (!pipe || !psurf)
|
||||
if (!psurf)
|
||||
return;
|
||||
|
||||
ptrans = pipe->get_tex_transfer(pipe, ptex, 0, 0, 0,
|
||||
PIPE_TRANSFER_READ,
|
||||
0, 0, dPriv->w, dPriv->h);
|
||||
|
||||
width = ptrans->stride / util_format_get_blocksize(ptex->format);
|
||||
|
||||
pmap = pipe->transfer_map(pipe, ptrans);
|
||||
|
||||
assert(pmap);
|
||||
|
||||
put_image(dPriv, pmap, width);
|
||||
|
||||
pipe->transfer_unmap(pipe, ptrans);
|
||||
|
||||
pipe->tex_transfer_destroy(pipe, ptrans);
|
||||
screen->pipe_screen->flush_frontbuffer(screen->pipe_screen, psurf, drawable);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
|
|
@ -162,23 +129,6 @@ drisw_copy_to_front(__DRIdrawable * dPriv,
|
|||
* Backend functions for st_framebuffer interface and swap_buffers.
|
||||
*/
|
||||
|
||||
void
|
||||
drisw_flush_frontbuffer(struct dri_drawable *drawable,
|
||||
enum st_attachment_type statt)
|
||||
{
|
||||
struct dri_context *ctx = dri_get_current();
|
||||
struct pipe_texture *ptex;
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
ptex = drawable->textures[statt];
|
||||
|
||||
if (ptex) {
|
||||
drisw_copy_to_front(ctx->dPriv, ptex);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drisw_swap_buffers(__DRIdrawable *dPriv)
|
||||
{
|
||||
|
|
@ -198,6 +148,23 @@ drisw_swap_buffers(__DRIdrawable *dPriv)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
drisw_flush_frontbuffer(struct dri_drawable *drawable,
|
||||
enum st_attachment_type statt)
|
||||
{
|
||||
struct dri_context *ctx = dri_get_current();
|
||||
struct pipe_texture *ptex;
|
||||
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
ptex = drawable->textures[statt];
|
||||
|
||||
if (ptex) {
|
||||
drisw_copy_to_front(ctx->dPriv, ptex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate framebuffer attachments.
|
||||
*
|
||||
|
|
@ -286,12 +253,16 @@ static const __DRIextension *drisw_screen_extensions[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static struct drisw_loader_funcs drisw_lf = {
|
||||
.put_image = drisw_put_image
|
||||
};
|
||||
|
||||
const __DRIconfig **
|
||||
drisw_init_screen(__DRIscreen * sPriv)
|
||||
{
|
||||
const __DRIconfig **configs;
|
||||
struct dri_screen *screen;
|
||||
struct drm_create_screen_arg arg;
|
||||
struct drisw_create_screen_arg arg;
|
||||
|
||||
screen = CALLOC_STRUCT(dri_screen);
|
||||
if (!screen)
|
||||
|
|
@ -304,9 +275,10 @@ drisw_init_screen(__DRIscreen * sPriv)
|
|||
sPriv->private = (void *)screen;
|
||||
sPriv->extensions = drisw_screen_extensions;
|
||||
|
||||
arg.mode = DRM_CREATE_DRISW;
|
||||
arg.base.mode = DRM_CREATE_DRISW;
|
||||
arg.lf = &drisw_lf;
|
||||
|
||||
configs = dri_init_screen_helper(screen, &arg, 32);
|
||||
configs = dri_init_screen_helper(screen, &arg.base, 32);
|
||||
if (!configs)
|
||||
goto fail;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const __DRIconfig **
|
|||
drisw_init_screen(__DRIscreen * sPriv);
|
||||
|
||||
void
|
||||
drisw_update_drawable_info(__DRIdrawable *dPriv);
|
||||
drisw_update_drawable_info(struct dri_drawable *drawable);
|
||||
|
||||
void
|
||||
drisw_flush_frontbuffer(struct dri_drawable *drawable,
|
||||
|
|
|
|||
|
|
@ -32,15 +32,7 @@
|
|||
#include "state_tracker/sw_winsys.h"
|
||||
#include "dri_sw_winsys.h"
|
||||
|
||||
/* Copied from targets/libgl-xlib.
|
||||
*
|
||||
* TODO:
|
||||
* This function should be put in targets/common or winsys/sw/common and shared
|
||||
* with targets/libgl-xlib and winsys/sw/drm.
|
||||
*
|
||||
* For targets/common, you get layering violations unless all of drm_api's are
|
||||
* moved under targets.
|
||||
*/
|
||||
/* Copied from targets/libgl-xlib */
|
||||
|
||||
#ifdef GALLIUM_SOFTPIPE
|
||||
#include "softpipe/sp_public.h"
|
||||
|
|
@ -98,19 +90,24 @@ swrast_drm_create_screen(struct drm_api *api,
|
|||
{
|
||||
struct sw_winsys *winsys = NULL;
|
||||
struct pipe_screen *screen = NULL;
|
||||
struct drisw_create_screen_arg *drisw;
|
||||
|
||||
(void) drmFD;
|
||||
|
||||
if (arg != NULL) {
|
||||
switch(arg->mode) {
|
||||
case DRM_CREATE_DRISW:
|
||||
drisw = (struct drisw_create_screen_arg *)arg;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
winsys = dri_create_sw_winsys();
|
||||
winsys = dri_create_sw_winsys(drisw->lf);
|
||||
if (winsys == NULL)
|
||||
return NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,14 @@ PUBLIC const struct st_module st_module_OpenGL = {
|
|||
* GALLIUM_CELL, etc. Scons already eliminates those #defines, so
|
||||
* things that are painful for it now are likely to be painful for
|
||||
* other build systems in the future.
|
||||
*
|
||||
* Copies (full or partial):
|
||||
* targets/libgl-xlib
|
||||
* targets/graw-xlib
|
||||
* targets/dri-swrast
|
||||
* winsys/sw/drm
|
||||
* drivers/sw
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef GALLIUM_SOFTPIPE
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@
|
|||
|
||||
struct dri_sw_displaytarget
|
||||
{
|
||||
enum pipe_format format;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned stride;
|
||||
|
||||
void *data;
|
||||
void *mapped;
|
||||
};
|
||||
|
|
@ -46,6 +51,8 @@ struct dri_sw_displaytarget
|
|||
struct dri_sw_winsys
|
||||
{
|
||||
struct sw_winsys base;
|
||||
|
||||
struct drisw_loader_funcs *lf;
|
||||
};
|
||||
|
||||
static INLINE struct dri_sw_displaytarget *
|
||||
|
|
@ -79,23 +86,27 @@ dri_sw_displaytarget_create(struct sw_winsys *winsys,
|
|||
unsigned *stride)
|
||||
{
|
||||
struct dri_sw_displaytarget *dri_sw_dt;
|
||||
unsigned nblocksy, size, dri_sw_stride, format_stride;
|
||||
unsigned nblocksy, size, format_stride;
|
||||
|
||||
dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget);
|
||||
if(!dri_sw_dt)
|
||||
goto no_dt;
|
||||
|
||||
dri_sw_dt->format = format;
|
||||
dri_sw_dt->width = width;
|
||||
dri_sw_dt->height = height;
|
||||
|
||||
format_stride = util_format_get_stride(format, width);
|
||||
dri_sw_stride = align(format_stride, alignment);
|
||||
dri_sw_dt->stride = align(format_stride, alignment);
|
||||
|
||||
nblocksy = util_format_get_nblocksy(format, height);
|
||||
size = dri_sw_stride * nblocksy;
|
||||
size = dri_sw_dt->stride * nblocksy;
|
||||
|
||||
dri_sw_dt->data = align_malloc(size, alignment);
|
||||
if(!dri_sw_dt->data)
|
||||
goto no_data;
|
||||
|
||||
*stride = dri_sw_stride;
|
||||
*stride = dri_sw_dt->stride;
|
||||
return (struct sw_displaytarget *)dri_sw_dt;
|
||||
|
||||
no_data:
|
||||
|
|
@ -159,7 +170,20 @@ dri_sw_displaytarget_display(struct sw_winsys *ws,
|
|||
struct sw_displaytarget *dt,
|
||||
void *context_private)
|
||||
{
|
||||
assert(0);
|
||||
struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
|
||||
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
|
||||
struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
|
||||
unsigned width, height;
|
||||
|
||||
/* Set the width to 'stride / cpp'.
|
||||
*
|
||||
* PutImage correctly clips to the width of the dst drawable.
|
||||
*/
|
||||
width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format);
|
||||
|
||||
height = dri_sw_dt->height;
|
||||
|
||||
dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -170,7 +194,7 @@ dri_destroy_sw_winsys(struct sw_winsys *winsys)
|
|||
}
|
||||
|
||||
struct sw_winsys *
|
||||
dri_create_sw_winsys(void)
|
||||
dri_create_sw_winsys(struct drisw_loader_funcs *lf)
|
||||
{
|
||||
struct dri_sw_winsys *ws;
|
||||
|
||||
|
|
@ -178,6 +202,7 @@ dri_create_sw_winsys(void)
|
|||
if (!ws)
|
||||
return NULL;
|
||||
|
||||
ws->lf = lf;
|
||||
ws->base.destroy = dri_destroy_sw_winsys;
|
||||
|
||||
ws->base.is_displaytarget_format_supported = dri_sw_is_displaytarget_format_supported;
|
||||
|
|
|
|||
|
|
@ -29,8 +29,10 @@
|
|||
#ifndef DRI_SW_WINSYS
|
||||
#define DRI_SW_WINSYS
|
||||
|
||||
#include "state_tracker/drisw_api.h"
|
||||
|
||||
struct sw_winsys;
|
||||
|
||||
struct sw_winsys *dri_create_sw_winsys(void);
|
||||
struct sw_winsys *dri_create_sw_winsys(struct drisw_loader_funcs *lf);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue