summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/xorg
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/xorg')
-rw-r--r--src/gallium/state_trackers/xorg/Makefile3
-rw-r--r--src/gallium/state_trackers/xorg/SConscript6
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c186
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.h4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c102
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c114
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c630
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c533
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h13
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa_tgsi.c177
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa_tgsi.h10
-rw-r--r--src/gallium/state_trackers/xorg/xorg_output.c44
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c875
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h77
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h40
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c190
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/surface.c17
17 files changed, 1842 insertions, 1179 deletions
diff --git a/src/gallium/state_trackers/xorg/Makefile b/src/gallium/state_trackers/xorg/Makefile
index 22c107370e..cb2c3aea41 100644
--- a/src/gallium/state_trackers/xorg/Makefile
+++ b/src/gallium/state_trackers/xorg/Makefile
@@ -7,6 +7,9 @@ LIBRARY_INCLUDES = \
-DHAVE_CONFIG_H \
$(shell pkg-config xextproto --atleast-version=7.0.99.1 \
&& echo "-DHAVE_XEXTPROTO_71") \
+ $(shell pkg-config libkms --atleast-version=1.0 \
+ && echo "-DHAVE_LIBKMS") \
+ $(shell pkg-config libkms --silence-errors --cflags-only-I) \
$(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
-I$(TOP)/src/gallium/include \
-I$(TOP)/src/gallium/auxiliary \
diff --git a/src/gallium/state_trackers/xorg/SConscript b/src/gallium/state_trackers/xorg/SConscript
index 6165bae7a4..5d0b6613ac 100644
--- a/src/gallium/state_trackers/xorg/SConscript
+++ b/src/gallium/state_trackers/xorg/SConscript
@@ -13,6 +13,11 @@ if 'xorg' in env['statetrackers']:
env.ParseConfig('pkg-config --cflags --libs xorg-server')
+ conf = env.Configure()
+
+ if conf.CheckHeader('X11/extensions/dpmsconst.h'):
+ env.Append(CPPDEFINES = [('HAVE_XEXTPROTO_71', '1')])
+
st_xorg = env.ConvenienceLibrary(
target = 'st_xorg',
source = [ 'xorg_composite.c',
@@ -22,6 +27,7 @@ if 'xorg' in env['statetrackers']:
'xorg_exa.c',
'xorg_exa_tgsi.c',
'xorg_output.c',
+ 'xorg_renderer.c',
'xorg_xv.c',
]
)
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index a8d779b8ad..1c248a629e 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -118,7 +118,7 @@ render_repeat_to_gallium(int mode)
{
switch(mode) {
case RepeatNone:
- return PIPE_TEX_WRAP_CLAMP;
+ return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
case RepeatNormal:
return PIPE_TEX_WRAP_REPEAT;
case RepeatReflect:
@@ -151,8 +151,11 @@ render_filter_to_gallium(int xrender_filter, int *out_filter)
case PictFilterBest:
*out_filter = PIPE_TEX_FILTER_LINEAR;
break;
+ case PictFilterConvolution:
+ *out_filter = PIPE_TEX_FILTER_NEAREST;
+ return FALSE;
default:
- debug_printf("Unkown xrender filter");
+ debug_printf("Unknown xrender filter\n");
*out_filter = PIPE_TEX_FILTER_NEAREST;
return FALSE;
}
@@ -199,6 +202,7 @@ boolean xorg_composite_accelerated(int op,
op);
}
}
+
return TRUE;
}
XORG_FALLBACK("Unsupported composition operation = %d", op);
@@ -227,10 +231,72 @@ bind_blend_state(struct exa_context *exa, int op,
cso_set_blend(exa->renderer->cso, &blend);
}
+static unsigned
+picture_format_fixups(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture, boolean mask,
+ PicturePtr pDstPicture)
+{
+ boolean set_alpha = FALSE;
+ boolean swizzle = FALSE;
+ unsigned ret = 0;
+
+ if (pSrc->picture_format == pSrcPicture->format) {
+ if (pSrc->picture_format == PICT_a8) {
+ if (mask)
+ return FS_MASK_LUMINANCE;
+ else if (pDstPicture->format != PICT_a8) {
+ /* if both dst and src are luminance then
+ * we don't want to swizzle the alpha (X) of the
+ * source into W component of the dst because
+ * it will break our destination */
+ return FS_SRC_LUMINANCE;
+ }
+ }
+ return 0;
+ }
+
+ if (pSrc->picture_format != PICT_a8r8g8b8) {
+ assert(!"can not handle formats");
+ return 0;
+ }
+
+ /* pSrc->picture_format == PICT_a8r8g8b8 */
+ switch (pSrcPicture->format) {
+ case PICT_x8b8g8r8:
+ case PICT_b8g8r8:
+ set_alpha = TRUE; /* fall trough */
+ case PICT_a8b8g8r8:
+ swizzle = TRUE;
+ break;
+ case PICT_x8r8g8b8:
+ case PICT_r8g8b8:
+ set_alpha = TRUE; /* fall through */
+ case PICT_a8r8g8b8:
+ break;
+#ifdef PICT_TYPE_BGRA
+ case PICT_b8g8r8a8:
+ case PICT_b8g8r8x8:
+ case PICT_a2r10g10b10:
+ case PICT_x2r10g10b10:
+ case PICT_a2b10g10r10:
+ case PICT_x2b10g10r10:
+#endif
+ default:
+ assert(!"can not handle formats");
+ return 0;
+ }
+
+ if (set_alpha)
+ ret |= mask ? FS_MASK_SET_ALPHA : FS_SRC_SET_ALPHA;
+ if (swizzle)
+ ret |= mask ? FS_MASK_SWIZZLE_RGB : FS_SRC_SWIZZLE_RGB;
+
+ return ret;
+}
static void
bind_shaders(struct exa_context *exa, int op,
- PicturePtr pSrcPicture, PicturePtr pMaskPicture)
+ PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture,
+ struct exa_pixmap_priv *pSrc, struct exa_pixmap_priv *pMask)
{
unsigned vs_traits = 0, fs_traits = 0;
struct xorg_shader shader;
@@ -238,6 +304,9 @@ bind_shaders(struct exa_context *exa, int op,
exa->has_solid_color = FALSE;
if (pSrcPicture) {
+ if (pSrcPicture->repeatType == RepeatNone && pSrcPicture->transform)
+ fs_traits |= FS_SRC_REPEAT_NONE;
+
if (pSrcPicture->pSourcePict) {
if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
fs_traits |= FS_SOLID_FILL;
@@ -253,11 +322,15 @@ bind_shaders(struct exa_context *exa, int op,
fs_traits |= FS_COMPOSITE;
vs_traits |= VS_COMPOSITE;
}
+
+ fs_traits |= picture_format_fixups(pSrc, pSrcPicture, FALSE, pDstPicture);
}
if (pMaskPicture) {
vs_traits |= VS_MASK;
fs_traits |= FS_MASK;
+ if (pMaskPicture->repeatType == RepeatNone && pMaskPicture->transform)
+ fs_traits |= FS_MASK_REPEAT_NONE;
if (pMaskPicture->componentAlpha) {
struct xorg_composite_blend blend;
blend_for_op(&blend, op,
@@ -267,6 +340,8 @@ bind_shaders(struct exa_context *exa, int op,
} else
fs_traits |= FS_CA_FULL;
}
+
+ fs_traits |= picture_format_fixups(pMask, pMaskPicture, TRUE, pDstPicture);
}
shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
@@ -287,6 +362,14 @@ bind_samplers(struct exa_context *exa, int op,
exa->num_bound_samplers = 0;
+#if 0
+ if ((pSrc && (exa->pipe->is_texture_referenced(exa->pipe, pSrc->tex, 0, 0) &
+ PIPE_REFERENCED_FOR_WRITE)) ||
+ (pMask && (exa->pipe->is_texture_referenced(exa->pipe, pMask->tex, 0, 0) &
+ PIPE_REFERENCED_FOR_WRITE)))
+ xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
+#endif
+
memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
@@ -338,40 +421,7 @@ bind_samplers(struct exa_context *exa, int op,
exa->bound_textures);
}
-static void
-setup_vs_constant_buffer(struct exa_context *exa,
- int width, int height)
-{
- const int param_bytes = 8 * sizeof(float);
- float vs_consts[8] = {
- 2.f/width, 2.f/height, 1, 1,
- -1, -1, 0, 0
- };
- renderer_set_constants(exa->renderer, PIPE_SHADER_VERTEX,
- vs_consts, param_bytes);
-}
-
-
-static void
-setup_fs_constant_buffer(struct exa_context *exa)
-{
- const int param_bytes = 4 * sizeof(float);
- const float fs_consts[8] = {
- 0, 0, 0, 1,
- };
- renderer_set_constants(exa->renderer, PIPE_SHADER_FRAGMENT,
- fs_consts, param_bytes);
-}
-
-static void
-setup_constant_buffers(struct exa_context *exa, struct exa_pixmap_priv *pDst)
-{
- int width = pDst->tex->width[0];
- int height = pDst->tex->height[0];
- setup_vs_constant_buffer(exa, width, height);
- setup_fs_constant_buffer(exa);
-}
static INLINE boolean matrix_from_pict_transform(PictTransform *trans, float *matrix)
{
@@ -420,17 +470,29 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
struct exa_pixmap_priv *pMask,
struct exa_pixmap_priv *pDst)
{
- renderer_bind_framebuffer(exa->renderer, pDst);
- renderer_bind_viewport(exa->renderer, pDst);
+ struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pDst);
+
+ renderer_bind_destination(exa->renderer, dst_surf,
+ pDst->width,
+ pDst->height);
+
bind_blend_state(exa, op, pSrcPicture, pMaskPicture, pDstPicture);
- renderer_bind_rasterizer(exa->renderer);
- bind_shaders(exa, op, pSrcPicture, pMaskPicture);
+ bind_shaders(exa, op, pSrcPicture, pMaskPicture, pDstPicture, pSrc, pMask);
bind_samplers(exa, op, pSrcPicture, pMaskPicture,
pDstPicture, pSrc, pMask, pDst);
- setup_constant_buffers(exa, pDst);
setup_transforms(exa, pSrcPicture, pMaskPicture);
+ if (exa->num_bound_samplers == 0 ) { /* solid fill */
+ renderer_begin_solid(exa->renderer);
+ } else {
+ renderer_begin_textures(exa->renderer,
+ exa->bound_textures,
+ exa->num_bound_samplers);
+ }
+
+
+ pipe_surface_reference(&dst_surf, NULL);
return TRUE;
}
@@ -440,9 +502,9 @@ void xorg_composite(struct exa_context *exa,
int dstX, int dstY, int width, int height)
{
if (exa->num_bound_samplers == 0 ) { /* solid fill */
- renderer_draw_solid_rect(exa->renderer,
- dstX, dstY, dstX + width, dstY + height,
- exa->solid_color);
+ renderer_solid(exa->renderer,
+ dstX, dstY, dstX + width, dstY + height,
+ exa->solid_color);
} else {
int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY};
float *src_matrix = NULL;
@@ -453,11 +515,11 @@ void xorg_composite(struct exa_context *exa,
if (exa->transform.has_mask)
mask_matrix = exa->transform.mask;
- renderer_draw_textures(exa->renderer,
- pos, width, height,
- exa->bound_textures,
- exa->num_bound_samplers,
- src_matrix, mask_matrix);
+ renderer_texture(exa->renderer,
+ pos, width, height,
+ exa->bound_textures,
+ exa->num_bound_samplers,
+ src_matrix, mask_matrix);
}
}
@@ -465,6 +527,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
struct exa_pixmap_priv *pixmap,
Pixel fg)
{
+ struct pipe_surface *dst_surf = xorg_gpu_surface(exa->scrn, pixmap);
unsigned vs_traits, fs_traits;
struct xorg_shader shader;
@@ -482,16 +545,19 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
vs_traits = VS_SOLID_FILL;
fs_traits = FS_SOLID_FILL;
- renderer_bind_framebuffer(exa->renderer, pixmap);
- renderer_bind_viewport(exa->renderer, pixmap);
- renderer_bind_rasterizer(exa->renderer);
+ renderer_bind_destination(exa->renderer, dst_surf,
+ pixmap->width, pixmap->height);
bind_blend_state(exa, PictOpSrc, NULL, NULL, NULL);
- setup_constant_buffers(exa, pixmap);
+ cso_set_samplers(exa->renderer->cso, 0, NULL);
+ cso_set_sampler_textures(exa->renderer->cso, 0, NULL);
shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
+ renderer_begin_solid(exa->renderer);
+
+ pipe_surface_reference(&dst_surf, NULL);
return TRUE;
}
@@ -499,7 +565,17 @@ void xorg_solid(struct exa_context *exa,
struct exa_pixmap_priv *pixmap,
int x0, int y0, int x1, int y1)
{
- renderer_draw_solid_rect(exa->renderer,
- x0, y0, x1, y1, exa->solid_color);
+ renderer_solid(exa->renderer,
+ x0, y0, x1, y1, exa->solid_color);
}
+void
+xorg_composite_done(struct exa_context *exa)
+{
+ renderer_draw_flush(exa->renderer);
+
+ exa->transform.has_src = FALSE;
+ exa->transform.has_mask = FALSE;
+ exa->has_solid_color = FALSE;
+ exa->num_bound_samplers = 0;
+}
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.h b/src/gallium/state_trackers/xorg/xorg_composite.h
index 236addf1ce..ec71ebfe0d 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.h
+++ b/src/gallium/state_trackers/xorg/xorg_composite.h
@@ -29,4 +29,8 @@ void xorg_solid(struct exa_context *exa,
struct exa_pixmap_priv *pixmap,
int x0, int y0, int x1, int y1);
+
+void
+xorg_composite_done(struct exa_context *exa);
+
#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 85b9162d4c..650d2c0d1d 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -50,20 +50,29 @@
#endif
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
#include "util/u_rect.h"
+#ifdef HAVE_LIBKMS
+#include "libkms.h"
+#endif
+
struct crtc_private
{
drmModeCrtcPtr drm_crtc;
/* hwcursor */
struct pipe_texture *cursor_tex;
+ struct kms_bo *cursor_bo;
+
unsigned cursor_handle;
};
static void
crtc_dpms(xf86CrtcPtr crtc, int mode)
{
+ /* ScrnInfoPtr pScrn = crtc->scrn; */
+
switch (mode) {
case DPMSModeOn:
case DPMSModeStandby:
@@ -114,7 +123,8 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
drm_mode.vrefresh = mode->VRefresh;
if (!mode->name)
xf86SetModeDefaultName(mode);
- strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN);
+ strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN - 1);
+ drm_mode.name[DRM_DISPLAY_MODE_LEN - 1] = '\0';
ret = drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y,
&drm_connector->connector_id, 1, &drm_mode);
@@ -134,23 +144,29 @@ static void
crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
int size)
{
+ /* XXX: hockup */
}
static void *
crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
+ /* ScrnInfoPtr pScrn = crtc->scrn; */
+
return NULL;
}
static PixmapPtr
crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
{
+ /* ScrnInfoPtr pScrn = crtc->scrn; */
+
return NULL;
}
static void
crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
{
+ /* ScrnInfoPtr pScrn = crtc->scrn; */
}
/*
@@ -160,6 +176,7 @@ crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
static void
crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
{
+ /* XXX: See if this one is needed, as we only support ARGB cursors */
}
static void
@@ -170,8 +187,9 @@ crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y);
}
+
static void
-crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
+crtc_load_cursor_argb_ga3d(xf86CrtcPtr crtc, CARD32 * image)
{
unsigned char *ptr;
modesettingPtr ms = modesettingPTR(crtc->scrn);
@@ -187,11 +205,10 @@ crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
- templat.depth[0] = 1;
+ templat.depth0 = 1;
templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
- templat.width[0] = 64;
- templat.height[0] = 64;
- pf_get_block(templat.format, &templat.block);
+ templat.width0 = 64;
+ templat.height0 = 64;
crtcp->cursor_tex = ms->screen->texture_create(ms->screen,
&templat);
@@ -207,20 +224,70 @@ crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
PIPE_TRANSFER_WRITE,
0, 0, 64, 64);
ptr = ms->screen->transfer_map(ms->screen, transfer);
- util_copy_rect(ptr, &crtcp->cursor_tex->block,
+ util_copy_rect(ptr, crtcp->cursor_tex->format,
transfer->stride, 0, 0,
64, 64, (void*)image, 64 * 4, 0, 0);
ms->screen->transfer_unmap(ms->screen, transfer);
ms->screen->tex_transfer_destroy(transfer);
}
+#if HAVE_LIBKMS
+static void
+crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image)
+{
+ modesettingPtr ms = modesettingPTR(crtc->scrn);
+ struct crtc_private *crtcp = crtc->driver_private;
+ unsigned char *ptr;
+
+ if (!crtcp->cursor_bo) {
+ unsigned attr[8];
+
+ attr[0] = KMS_BO_TYPE;
+ attr[1] = KMS_BO_TYPE_CURSOR;
+ attr[2] = KMS_WIDTH;
+ attr[3] = 64;
+ attr[4] = KMS_HEIGHT;
+ attr[5] = 64;
+ attr[6] = 0;
+
+ if (kms_bo_create(ms->kms, attr, &crtcp->cursor_bo))
+ return;
+
+ if (kms_bo_get_prop(crtcp->cursor_bo, KMS_HANDLE,
+ &crtcp->cursor_handle))
+ goto err_bo_destroy;
+ }
+
+ kms_bo_map(crtcp->cursor_bo, (void**)&ptr);
+ memcpy(ptr, image, 64*64*4);
+ kms_bo_unmap(crtcp->cursor_bo);
+
+ return;
+
+err_bo_destroy:
+ kms_bo_destroy(&crtcp->cursor_bo);
+}
+#endif
+
+static void
+crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
+{
+ modesettingPtr ms = modesettingPTR(crtc->scrn);
+ if (ms->screen)
+ crtc_load_cursor_argb_ga3d(crtc, image);
+#ifdef HAVE_LIBKMS
+ else if (ms->kms)
+ crtc_load_cursor_argb_kms(crtc, image);
+#endif
+}
+
static void
crtc_show_cursor(xf86CrtcPtr crtc)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
- if (crtcp->cursor_tex)
+ if (crtcp->cursor_tex || crtcp->cursor_bo)
drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id,
crtcp->cursor_handle, 64, 64);
}
@@ -234,14 +301,20 @@ crtc_hide_cursor(xf86CrtcPtr crtc)
drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0);
}
+/**
+ * Called at vt leave
+ */
void
-crtc_cursor_destroy(xf86CrtcPtr crtc)
+xorg_crtc_cursor_destroy(xf86CrtcPtr crtc)
{
struct crtc_private *crtcp = crtc->driver_private;
- if (crtcp->cursor_tex) {
+ if (crtcp->cursor_tex)
pipe_texture_reference(&crtcp->cursor_tex, NULL);
- }
+#ifdef HAVE_LIBKMS
+ if (crtcp->cursor_bo)
+ kms_bo_destroy(&crtcp->cursor_bo);
+#endif
}
/*
@@ -253,11 +326,12 @@ crtc_destroy(xf86CrtcPtr crtc)
{
struct crtc_private *crtcp = crtc->driver_private;
- if (crtcp->cursor_tex)
- pipe_texture_reference(&crtcp->cursor_tex, NULL);
+ xorg_crtc_cursor_destroy(crtc);
drmModeFreeCrtc(crtcp->drm_crtc);
+
xfree(crtcp);
+ crtc->driver_private = NULL;
}
static const xf86CrtcFuncsRec crtc_funcs = {
@@ -279,7 +353,7 @@ static const xf86CrtcFuncsRec crtc_funcs = {
};
void
-crtc_init(ScrnInfoPtr pScrn)
+xorg_crtc_init(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
xf86CrtcPtr crtc;
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index c41a7cd639..fd82f4fa1d 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -40,8 +40,15 @@
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
#include "util/u_rect.h"
+/* Make all the #if cases in the code esier to read */
+/* XXX can it be set to 1? */
+#ifndef DRI2INFOREC_VERSION
+#define DRI2INFOREC_VERSION 0
+#endif
+
typedef struct {
PixmapPtr pPixmap;
struct pipe_texture *tex;
@@ -49,7 +56,7 @@ typedef struct {
} *BufferPrivatePtr;
static Bool
-driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
+dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
{
struct pipe_texture *tex = NULL;
ScreenPtr pScreen = pDraw->pScreen;
@@ -79,14 +86,14 @@ driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
case DRI2BufferFrontLeft:
break;
case DRI2BufferStencil:
-#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
+#if DRI2INFOREC_VERSION >= 3
case DRI2BufferDepthStencil:
#else
/* Works on old X servers because sanity checking is for the weak */
case 9:
#endif
if (exa_priv->depth_stencil_tex &&
- !pf_is_depth_stencil(exa_priv->depth_stencil_tex->format))
+ !util_format_is_depth_or_stencil(exa_priv->depth_stencil_tex->format))
exa_priv->depth_stencil_tex = NULL;
/* Fall through */
case DRI2BufferDepth:
@@ -102,10 +109,9 @@ driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
else
template.format = ms->ds_depth_bits_last ?
PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
- pf_get_block(template.format, &template.block);
- template.width[0] = pDraw->width;
- template.height[0] = pDraw->height;
- template.depth[0] = 1;
+ template.width0 = pDraw->width;
+ template.height0 = pDraw->height;
+ template.depth0 = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
@@ -121,9 +127,12 @@ driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
}
if (!tex) {
+ /* First call to make sure we have a pixmap private */
exaMoveInPixmap(private->pPixmap);
xorg_exa_set_shared_usage(private->pPixmap);
pScreen->ModifyPixmapHeader(private->pPixmap, 0, 0, 0, 0, 0, NULL);
+ /* Second call to make sure texture has valid contents */
+ exaMoveInPixmap(private->pPixmap);
tex = xorg_exa_get_texture(private->pPixmap);
}
@@ -137,13 +146,18 @@ driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
buffer->cpp = 4;
buffer->driverPrivate = private;
buffer->flags = 0; /* not tiled */
+#if DRI2INFOREC_VERSION == 2
+ ((DRI2Buffer2Ptr)buffer)->format = 0;
+#elif DRI2INFOREC_VERSION >= 3
+ buffer->format = 0;
+#endif
private->tex = tex;
return TRUE;
}
static void
-driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
+dri2_do_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
{
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -157,12 +171,12 @@ driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
(*pScreen->DestroyPixmap)(private->pPixmap);
}
-#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
+#if DRI2INFOREC_VERSION >= 2
-static DRI2BufferPtr
-driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
+static DRI2Buffer2Ptr
+dri2_create_buffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
{
- DRI2BufferPtr buffer;
+ DRI2Buffer2Ptr buffer;
BufferPrivatePtr private;
buffer = xcalloc(1, sizeof *buffer);
@@ -177,7 +191,8 @@ driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
buffer->attachment = attachment;
buffer->driverPrivate = private;
- if (driDoCreateBuffer(pDraw, buffer, format))
+ /* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */
+ if (dri2_do_create_buffer(pDraw, (DRI2BufferPtr)buffer, format))
return buffer;
xfree(private);
@@ -187,18 +202,19 @@ fail:
}
static void
-driDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
+dri2_destroy_buffer(DrawablePtr pDraw, DRI2Buffer2Ptr buffer)
{
- driDoDestroyBuffer(pDraw, buffer);
+ /* So far it is safe to downcast a DRI2Buffer2Ptr to DRI2BufferPtr */
+ dri2_do_destroy_buffer(pDraw, (DRI2BufferPtr)buffer);
xfree(buffer->driverPrivate);
xfree(buffer);
}
-#else /* DRI2INFOREC_VERSION <= 2 */
+#else /* DRI2INFOREC_VERSION < 2 */
static DRI2BufferPtr
-driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
+dri2_create_buffers(DrawablePtr pDraw, unsigned int *attachments, int count)
{
BufferPrivatePtr privates;
DRI2BufferPtr buffers;
@@ -216,7 +232,7 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
buffers[i].attachment = attachments[i];
buffers[i].driverPrivate = &privates[i];
- if (!driDoCreateBuffer(pDraw, &buffers[i], 0))
+ if (!dri2_do_create_buffer(pDraw, &buffers[i], 0))
goto fail;
}
@@ -231,12 +247,12 @@ fail_buffers:
}
static void
-driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
+dri2_destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
{
int i;
for (i = 0; i < count; i++) {
- driDoDestroyBuffer(pDraw, &buffers[i]);
+ dri2_do_destroy_buffer(pDraw, &buffers[i]);
}
if (buffers) {
@@ -245,21 +261,22 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
}
}
-#endif /* DRI2INFOREC_VERSION */
+#endif /* DRI2INFOREC_VERSION >= 2 */
static void
-driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
- DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
+dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
+ DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
{
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate;
BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate;
- PixmapPtr src_pixmap;
- PixmapPtr dst_pixmap;
+ DrawablePtr src_draw;
+ DrawablePtr dst_draw;
GCPtr gc;
RegionPtr copy_clip;
+ Bool save_accel;
/*
* In driCreateBuffers we dewrap windows into the
@@ -267,12 +284,10 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
* We need to use the real drawable in CopyArea
* so that cliprects and offsets are correct.
*/
- src_pixmap = src_priv->pPixmap;
- dst_pixmap = dst_priv->pPixmap;
- if (pSrcBuffer->attachment == DRI2BufferFrontLeft)
- src_pixmap = (PixmapPtr)pDraw;
- if (pDestBuffer->attachment == DRI2BufferFrontLeft)
- dst_pixmap = (PixmapPtr)pDraw;
+ src_draw = (pSrcBuffer->attachment == DRI2BufferFrontLeft) ? pDraw :
+ &src_priv->pPixmap->drawable;
+ dst_draw = (pDestBuffer->attachment == DRI2BufferFrontLeft) ? pDraw :
+ &dst_priv->pPixmap->drawable;
/*
* The clients implements glXWaitX with a copy front to fake and then
@@ -291,7 +306,7 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
* must in the glXWaitGL case but we don't know if this is a glXWaitGL
* or a glFlush/glFinish call.
*/
- if (dst_pixmap == src_pixmap) {
+ if (dst_priv->pPixmap == src_priv->pPixmap) {
/* pixmap glXWaitX */
if (pSrcBuffer->attachment == DRI2BufferFrontLeft &&
pDestBuffer->attachment == DRI2BufferFakeFrontLeft) {
@@ -312,7 +327,7 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
copy_clip = REGION_CREATE(pScreen, NULL, 0);
REGION_COPY(pScreen, copy_clip, pRegion);
(*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0);
- ValidateGC(&dst_pixmap->drawable, gc);
+ ValidateGC(dst_draw, gc);
/* If this is a full buffer swap, throttle on the previous one */
if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
@@ -325,8 +340,21 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
}
}
- (*gc->ops->CopyArea)(&src_pixmap->drawable, &dst_pixmap->drawable, gc,
+ /* Try to make sure the blit will be accelerated */
+ save_accel = ms->exa->accel;
+ ms->exa->accel = TRUE;
+
+ /* In case it won't be though, make sure the GPU copy contents of the
+ * source pixmap will be used for the software fallback - presumably the
+ * client modified them before calling in here.
+ */
+ exaMoveInPixmap(src_priv->pPixmap);
+ DamageRegionAppend(src_draw, pRegion);
+ DamageRegionProcessPending(src_draw);
+
+ (*gc->ops->CopyArea)(src_draw, dst_draw, gc,
0, 0, pDraw->width, pDraw->height, 0, 0);
+ ms->exa->accel = save_accel;
FreeScratchGC(gc);
@@ -336,13 +364,13 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
}
Bool
-driScreenInit(ScreenPtr pScreen)
+xorg_dri2_init(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
DRI2InfoRec dri2info;
-#if defined(DRI2INFOREC_VERSION)
+#if DRI2INFOREC_VERSION >= 2
dri2info.version = DRI2INFOREC_VERSION;
#else
dri2info.version = 1;
@@ -352,14 +380,14 @@ driScreenInit(ScreenPtr pScreen)
dri2info.driverName = pScrn->driverName;
dri2info.deviceName = "/dev/dri/card0"; /* FIXME */
-#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
- dri2info.CreateBuffer = driCreateBuffer;
- dri2info.DestroyBuffer = driDestroyBuffer;
+#if DRI2INFOREC_VERSION >= 2
+ dri2info.CreateBuffer = dri2_create_buffer;
+ dri2info.DestroyBuffer = dri2_destroy_buffer;
#else
- dri2info.CreateBuffers = driCreateBuffers;
- dri2info.DestroyBuffers = driDestroyBuffers;
+ dri2info.CreateBuffers = dri2_create_buffers;
+ dri2info.DestroyBuffers = dri2_destroy_buffers;
#endif
- dri2info.CopyRegion = driCopyRegion;
+ dri2info.CopyRegion = dri2_copy_region;
dri2info.Wait = NULL;
ms->d_depth_bits_last =
@@ -375,7 +403,7 @@ driScreenInit(ScreenPtr pScreen)
}
void
-driCloseScreen(ScreenPtr pScreen)
+xorg_dri2_close(ScreenPtr pScreen)
{
DRI2CloseScreen(pScreen);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 26cf2dd772..b02fe68f31 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -56,32 +56,38 @@
#include "xorg_tracker.h"
#include "xorg_winsys.h"
-static void AdjustFrame(int scrnIndex, int x, int y, int flags);
-static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen);
-static Bool EnterVT(int scrnIndex, int flags);
-static Bool SaveHWState(ScrnInfoPtr pScrn);
-static Bool RestoreHWState(ScrnInfoPtr pScrn);
-
-
-static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
- int flags);
-static void FreeScreen(int scrnIndex, int flags);
-static void LeaveVT(int scrnIndex, int flags);
-static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
-static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
- char **argv);
-static Bool PreInit(ScrnInfoPtr pScrn, int flags);
+#ifdef HAVE_LIBKMS
+#include "libkms.h"
+#endif
+
+/*
+ * Functions and symbols exported to Xorg via pointers.
+ */
+
+static Bool drv_pre_init(ScrnInfoPtr pScrn, int flags);
+static Bool drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc,
+ char **argv);
+static Bool drv_switch_mode(int scrnIndex, DisplayModePtr mode, int flags);
+static void drv_adjust_frame(int scrnIndex, int x, int y, int flags);
+static Bool drv_enter_vt(int scrnIndex, int flags);
+static void drv_leave_vt(int scrnIndex, int flags);
+static void drv_free_screen(int scrnIndex, int flags);
+static ModeStatus drv_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose,
+ int flags);
typedef enum
{
OPTION_SW_CURSOR,
-} modesettingOpts;
+ OPTION_2D_ACCEL,
+} drv_option_enums;
-static const OptionInfoRec Options[] = {
+static const OptionInfoRec drv_options[] = {
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
+
/*
* Exported Xorg driver functions to winsys
*/
@@ -89,28 +95,39 @@ static const OptionInfoRec Options[] = {
const OptionInfoRec *
xorg_tracker_available_options(int chipid, int busid)
{
- return Options;
+ return drv_options;
}
void
xorg_tracker_set_functions(ScrnInfoPtr scrn)
{
- scrn->PreInit = PreInit;
- scrn->ScreenInit = ScreenInit;
- scrn->SwitchMode = SwitchMode;
- scrn->AdjustFrame = AdjustFrame;
- scrn->EnterVT = EnterVT;
- scrn->LeaveVT = LeaveVT;
- scrn->FreeScreen = FreeScreen;
- scrn->ValidMode = ValidMode;
+ scrn->PreInit = drv_pre_init;
+ scrn->ScreenInit = drv_screen_init;
+ scrn->SwitchMode = drv_switch_mode;
+ scrn->AdjustFrame = drv_adjust_frame;
+ scrn->EnterVT = drv_enter_vt;
+ scrn->LeaveVT = drv_leave_vt;
+ scrn->FreeScreen = drv_free_screen;
+ scrn->ValidMode = drv_valid_mode;
}
+
+/*
+ * Internal function definitions
+ */
+
+static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn);
+static Bool drv_close_screen(int scrnIndex, ScreenPtr pScreen);
+static Bool drv_save_hw_state(ScrnInfoPtr pScrn);
+static Bool drv_restore_hw_state(ScrnInfoPtr pScrn);
+
+
/*
- * Static Xorg funtctions
+ * Internal functions
*/
static Bool
-GetRec(ScrnInfoPtr pScrn)
+drv_get_rec(ScrnInfoPtr pScrn)
{
if (pScrn->driverPrivate)
return TRUE;
@@ -121,7 +138,7 @@ GetRec(ScrnInfoPtr pScrn)
}
static void
-FreeRec(ScrnInfoPtr pScrn)
+drv_free_rec(ScrnInfoPtr pScrn)
{
if (!pScrn)
return;
@@ -135,88 +152,21 @@ FreeRec(ScrnInfoPtr pScrn)
}
static void
-ProbeDDC(ScrnInfoPtr pScrn, int index)
+drv_probe_ddc(ScrnInfoPtr pScrn, int index)
{
ConfiguredMonitor = NULL;
}
static Bool
-CreateFrontBuffer(ScrnInfoPtr pScrn)
-{
- modesettingPtr ms = modesettingPTR(pScrn);
- unsigned handle, stride;
- struct pipe_texture *tex;
-
- ms->noEvict = TRUE;
-
- tex = xorg_exa_create_root_texture(pScrn, pScrn->virtualX, pScrn->virtualY,
- pScrn->depth, pScrn->bitsPerPixel);
-
- if (!tex)
- return FALSE;
-
- if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
- tex,
- &stride,
- &handle))
- return FALSE;
-
- drmModeAddFB(ms->fd,
- pScrn->virtualX,
- pScrn->virtualY,
- pScrn->depth,
- pScrn->bitsPerPixel,
- stride,
- handle,
- &ms->fb_id);
-
- pScrn->frameX0 = 0;
- pScrn->frameY0 = 0;
- AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
- pipe_texture_reference(&ms->root_texture, tex);
- pipe_texture_reference(&tex, NULL);
- return TRUE;
-}
-
-static Bool
-BindTextureToRoot(ScrnInfoPtr pScrn)
-{
- modesettingPtr ms = modesettingPTR(pScrn);
- ScreenPtr pScreen = pScrn->pScreen;
- struct pipe_texture *check;
- PixmapPtr rootPixmap;
-
- rootPixmap = pScreen->GetScreenPixmap(pScreen);
-
- xorg_exa_set_displayed_usage(rootPixmap);
- xorg_exa_set_shared_usage(rootPixmap);
- xorg_exa_set_texture(rootPixmap, ms->root_texture);
- if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
- FatalError("Couldn't adjust screen pixmap\n");
-
- check = xorg_exa_get_texture(rootPixmap);
- if (ms->root_texture != check)
- FatalError("Created new root texture\n");
-
- pipe_texture_reference(&check, NULL);
-
- return TRUE;
-}
-
-static Bool
-crtc_resize(ScrnInfoPtr pScrn, int width, int height)
+drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height)
{
modesettingPtr ms = modesettingPTR(pScrn);
- unsigned handle, stride;
PixmapPtr rootPixmap;
ScreenPtr pScreen = pScrn->pScreen;
if (width == pScrn->virtualX && height == pScrn->virtualY)
return TRUE;
- ErrorF("RESIZING TO %dx%d\n", width, height);
-
pScrn->virtualX = width;
pScrn->virtualY = height;
@@ -224,44 +174,25 @@ crtc_resize(ScrnInfoPtr pScrn, int width, int height)
* Remove the old framebuffer & texture.
*/
drmModeRmFB(ms->fd, ms->fb_id);
- pipe_texture_reference(&ms->root_texture, NULL);
-
+ if (!ms->destroy_front_buffer(pScrn))
+ FatalError("failed to destroy front buffer\n");
rootPixmap = pScreen->GetScreenPixmap(pScreen);
if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL))
return FALSE;
- /* takes one ref */
- ms->root_texture = xorg_exa_get_texture(rootPixmap);
-
- if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
- ms->root_texture,
- &stride,
- &handle))
- FatalError("Could not get handle and stride from texture\n");
-
- drmModeAddFB(ms->fd,
- pScrn->virtualX,
- pScrn->virtualY,
- pScrn->depth,
- pScrn->bitsPerPixel,
- stride,
- handle,
- &ms->fb_id);
-
- /* HW dependent - FIXME */
- pScrn->displayWidth = pScrn->virtualX;
+ pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
/* now create new frontbuffer */
- return CreateFrontBuffer(pScrn) && BindTextureToRoot(pScrn);
+ return ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn);
}
static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
- crtc_resize
+ .resize = drv_crtc_resize
};
static Bool
-InitDRM(ScrnInfoPtr pScrn)
+drv_init_drm(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
@@ -281,18 +212,77 @@ InitDRM(ScrnInfoPtr pScrn)
return FALSE;
}
- if (!ms->api) {
- ms->api = drm_api_create();
+ return TRUE;
+}
+
+static Bool
+drv_init_resource_management(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ /*
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ Bool fbAccessDisabled;
+ CARD8 *fbstart;
+ */
- if (!ms->api)
- return FALSE;
+ if (ms->screen || ms->kms)
+ return TRUE;
+
+ ms->api = drm_api_create();
+ if (ms->api) {
+ ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
+
+ if (ms->screen)
+ return TRUE;
+
+ if (ms->api->destroy)
+ ms->api->destroy(ms->api);
+
+ ms->api = NULL;
}
+#ifdef HAVE_LIBKMS
+ if (!kms_create(ms->fd, &ms->kms))
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+static Bool
+drv_close_resource_management(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ int i;
+
+ if (ms->screen) {
+ assert(ms->ctx == NULL);
+
+ for (i = 0; i < XORG_NR_FENCES; i++) {
+ if (ms->fence[i]) {
+ ms->screen->fence_finish(ms->screen, ms->fence[i], 0);
+ ms->screen->fence_reference(ms->screen, &ms->fence[i], NULL);
+ }
+ }
+ ms->screen->destroy(ms->screen);
+ }
+ ms->screen = NULL;
+
+ if (ms->api && ms->api->destroy)
+ ms->api->destroy(ms->api);
+ ms->api = NULL;
+
+#ifdef HAVE_LIBKMS
+ if (ms->kms)
+ kms_destroy(&ms->kms);
+#endif
+
return TRUE;
}
static Bool
-PreInit(ScrnInfoPtr pScrn, int flags)
+drv_pre_init(ScrnInfoPtr pScrn, int flags)
{
xf86CrtcConfigPtr xf86_config;
modesettingPtr ms;
@@ -307,12 +297,12 @@ PreInit(ScrnInfoPtr pScrn, int flags)
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
if (flags & PROBE_DETECT) {
- ProbeDDC(pScrn, pEnt->index);
+ drv_probe_ddc(pScrn, pEnt->index);
return TRUE;
}
/* Allocate driverPrivate */
- if (!GetRec(pScrn))
+ if (!drv_get_rec(pScrn))
return FALSE;
ms = modesettingPTR(pScrn);
@@ -349,7 +339,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
ms->fd = -1;
ms->api = NULL;
- if (!InitDRM(pScrn))
+ if (!drv_init_drm(pScrn))
return FALSE;
pScrn->monitor = pScrn->confScreen->monitor;
@@ -381,9 +371,9 @@ PreInit(ScrnInfoPtr pScrn, int flags)
/* Process the options */
xf86CollectOptions(pScrn, NULL);
- if (!(ms->Options = xalloc(sizeof(Options))))
+ if (!(ms->Options = xalloc(sizeof(drv_options))))
return FALSE;
- memcpy(ms->Options, Options, sizeof(Options));
+ memcpy(ms->Options, drv_options, sizeof(drv_options));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options);
/* Allocate an xf86CrtcConfig */
@@ -398,18 +388,18 @@ PreInit(ScrnInfoPtr pScrn, int flags)
ms->SWCursor = TRUE;
}
- SaveHWState(pScrn);
+ drv_save_hw_state(pScrn);
- crtc_init(pScrn);
- output_init(pScrn);
+ xorg_crtc_init(pScrn);
+ xorg_output_init(pScrn);
if (!xf86InitialConfiguration(pScrn, TRUE)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
- RestoreHWState(pScrn);
+ drv_restore_hw_state(pScrn);
return FALSE;
}
- RestoreHWState(pScrn);
+ drv_restore_hw_state(pScrn);
/*
* If the driver can do gamma correction, it should call xf86SetGamma() here.
@@ -433,21 +423,23 @@ PreInit(ScrnInfoPtr pScrn, int flags)
xf86SetDpi(pScrn, 0, 0);
/* Load the required sub modules */
- if (!xf86LoadSubModule(pScrn, "fb")) {
+ if (!xf86LoadSubModule(pScrn, "fb"))
return FALSE;
- }
- xf86LoadSubModule(pScrn, "exa");
+ /* XXX: these aren't needed when we are using libkms */
+ if (!xf86LoadSubModule(pScrn, "exa"))
+ return FALSE;
#ifdef DRI2
- xf86LoadSubModule(pScrn, "dri2");
+ if (!xf86LoadSubModule(pScrn, "dri2"))
+ return FALSE;
#endif
return TRUE;
}
static Bool
-SaveHWState(ScrnInfoPtr pScrn)
+drv_save_hw_state(ScrnInfoPtr pScrn)
{
/*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/
@@ -455,24 +447,45 @@ SaveHWState(ScrnInfoPtr pScrn)
}
static Bool
-RestoreHWState(ScrnInfoPtr pScrn)
+drv_restore_hw_state(ScrnInfoPtr pScrn)
{
/*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/
return TRUE;
}
-static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
- pointer pReadmask)
+static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
+ pointer pReadmask)
{
ScreenPtr pScreen = screenInfo.screens[i];
modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
pScreen->BlockHandler = ms->blockHandler;
pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
- pScreen->BlockHandler = xorgBlockHandler;
-
- ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ pScreen->BlockHandler = drv_block_handler;
+
+ if (ms->ctx) {
+ int j;
+
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]);
+
+ if (ms->fence[0])
+ ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0);
+
+ /* The amount of rendering generated by a block handler can be
+ * quite small. Let us get a fair way ahead of hardware before
+ * throttling.
+ */
+ for (j = 0; j < XORG_NR_FENCES - 1; j++)
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[j],
+ ms->fence[j+1]);
+
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[XORG_NR_FENCES-1],
+ NULL);
+ }
+
#ifdef DRM_MODE_FEATURE_DIRTYFB
{
@@ -482,7 +495,7 @@ static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
if (num_cliprects) {
drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip));
BoxPtr rect = REGION_RECTS(dirty);
- int i;
+ int i, ret;
/* XXX no need for copy? */
for (i = 0; i < num_cliprects; i++, rect++) {
@@ -493,7 +506,11 @@ static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
}
/* TODO query connector property to see if this is needed */
- drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+ ret = drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+ if (ret) {
+ debug_printf("%s: failed to send dirty (%i, %s)\n",
+ __func__, ret, strerror(-ret));
+ }
DamageEmpty(ms->damage);
}
@@ -502,7 +519,7 @@ static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
}
static Bool
-CreateScreenResources(ScreenPtr pScreen)
+drv_create_screen_resources(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
@@ -513,13 +530,13 @@ CreateScreenResources(ScreenPtr pScreen)
pScreen->CreateScreenResources = ms->createScreenResources;
ret = pScreen->CreateScreenResources(pScreen);
- pScreen->CreateScreenResources = CreateScreenResources;
+ pScreen->CreateScreenResources = drv_create_screen_resources;
- BindTextureToRoot(pScrn);
+ ms->bind_front_buffer(pScrn);
ms->noEvict = FALSE;
- AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
#ifdef DRM_MODE_FEATURE_DIRTYFB
rootPixmap = pScreen->GetScreenPixmap(pScreen);
@@ -543,22 +560,25 @@ CreateScreenResources(ScreenPtr pScreen)
}
static Bool
-ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
+drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
VisualPtr visual;
- if (!InitDRM(pScrn))
+ if (!drv_init_drm(pScrn)) {
+ FatalError("Could not init DRM");
return FALSE;
+ }
- if (!ms->screen) {
- ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL);
+ if (!drv_init_resource_management(pScrn)) {
+ FatalError("Could not init resource management (!pipe_screen && !libkms)");
+ return FALSE;
+ }
- if (!ms->screen) {
- FatalError("Could not init pipe_screen\n");
- return FALSE;
- }
+ if (!drv_init_front_buffer_functions(pScrn)) {
+ FatalError("Could not init front buffer manager");
+ return FALSE;
}
pScrn->pScreen = pScreen;
@@ -603,16 +623,22 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
fbPictureInit(pScreen, NULL, 0);
ms->blockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = xorgBlockHandler;
+ pScreen->BlockHandler = drv_block_handler;
ms->createScreenResources = pScreen->CreateScreenResources;
- pScreen->CreateScreenResources = CreateScreenResources;
+ pScreen->CreateScreenResources = drv_create_screen_resources;
xf86SetBlackWhitePixels(pScreen);
- ms->exa = xorg_exa_init(pScrn);
- ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
+ if (ms->screen) {
+ ms->exa = xorg_exa_init(pScrn, xf86ReturnOptValBool(ms->Options,
+ OPTION_2D_ACCEL, TRUE));
+ ms->debug_fallback = debug_get_bool_option("XORG_DEBUG_FALLBACK", TRUE);
- xorg_init_video(pScreen);
+ xorg_xv_init(pScreen);
+#ifdef DRI2
+ xorg_dri2_init(pScreen);
+#endif
+ }
miInitializeBackingStore(pScreen);
xf86SetBackingStore(pScreen);
@@ -631,7 +657,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
pScreen->SaveScreen = xf86SaveScreen;
ms->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = CloseScreen;
+ pScreen->CloseScreen = drv_close_screen;
if (!xf86CrtcScreenInit(pScreen))
return FALSE;
@@ -644,17 +670,14 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
-#if 1
-#ifdef DRI2
- driScreenInit(pScreen);
-#endif
-#endif
+ if (ms->winsys_screen_init)
+ ms->winsys_screen_init(pScrn);
- return EnterVT(scrnIndex, 1);
+ return drv_enter_vt(scrnIndex, 1);
}
static void
-AdjustFrame(int scrnIndex, int x, int y, int flags)
+drv_adjust_frame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -670,23 +693,26 @@ AdjustFrame(int scrnIndex, int x, int y, int flags)
}
static void
-FreeScreen(int scrnIndex, int flags)
+drv_free_screen(int scrnIndex, int flags)
{
- FreeRec(xf86Screens[scrnIndex]);
+ drv_free_rec(xf86Screens[scrnIndex]);
}
static void
-LeaveVT(int scrnIndex, int flags)
+drv_leave_vt(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int o;
+ if (ms->winsys_leave_vt)
+ ms->winsys_leave_vt(pScrn);
+
for (o = 0; o < config->num_crtc; o++) {
xf86CrtcPtr crtc = config->crtc[o];
- crtc_cursor_destroy(crtc);
+ xorg_crtc_cursor_destroy(crtc);
if (crtc->rotatedPixmap || crtc->rotatedData) {
crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
@@ -698,7 +724,7 @@ LeaveVT(int scrnIndex, int flags)
drmModeRmFB(ms->fd, ms->fb_id);
- RestoreHWState(pScrn);
+ drv_restore_hw_state(pScrn);
if (drmDropMaster(ms->fd))
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -711,7 +737,7 @@ LeaveVT(int scrnIndex, int flags)
* This gets called when gaining control of the VT, and from ScreenInit().
*/
static Bool
-EnterVT(int scrnIndex, int flags)
+drv_enter_vt(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
@@ -733,23 +759,26 @@ EnterVT(int scrnIndex, int flags)
*/
if (ms->SaveGeneration != serverGeneration) {
ms->SaveGeneration = serverGeneration;
- SaveHWState(pScrn);
+ drv_save_hw_state(pScrn);
}
- if (!CreateFrontBuffer(pScrn))
+ if (!ms->create_front_buffer(pScrn))
return FALSE;
- if (!flags && !BindTextureToRoot(pScrn))
+ if (!flags && !ms->bind_front_buffer(pScrn))
return FALSE;
if (!xf86SetDesiredModes(pScrn))
return FALSE;
+ if (ms->winsys_enter_vt)
+ ms->winsys_enter_vt(pScrn);
+
return TRUE;
}
static Bool
-SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+drv_switch_mode(int scrnIndex, DisplayModePtr mode, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
@@ -757,16 +786,21 @@ SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
}
static Bool
-CloseScreen(int scrnIndex, ScreenPtr pScreen)
+drv_close_screen(int scrnIndex, ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
if (pScrn->vtSema) {
- LeaveVT(scrnIndex, 0);
+ drv_leave_vt(scrnIndex, 0);
}
+
+ if (ms->winsys_screen_close)
+ ms->winsys_screen_close(pScrn);
+
#ifdef DRI2
- driCloseScreen(pScreen);
+ if (ms->screen)
+ xorg_dri2_close(pScreen);
#endif
pScreen->BlockHandler = ms->blockHandler;
@@ -780,14 +814,14 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
}
#endif
- pipe_texture_reference(&ms->root_texture, NULL);
+ drmModeRmFB(ms->fd, ms->fb_id);
+ ms->destroy_front_buffer(pScrn);
if (ms->exa)
xorg_exa_close(pScrn);
+ ms->exa = NULL;
- if (ms->api && ms->api->destroy)
- ms->api->destroy(ms->api);
- ms->api = NULL;
+ drv_close_resource_management(pScrn);
drmClose(ms->fd);
ms->fd = -1;
@@ -798,9 +832,217 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
}
static ModeStatus
-ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+drv_valid_mode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
{
return MODE_OK;
}
+
+/*
+ * Front buffer backing store functions.
+ */
+
+static Bool
+drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ pipe_texture_reference(&ms->root_texture, NULL);
+ return TRUE;
+}
+
+static Bool
+drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ unsigned handle, stride;
+ struct pipe_texture *tex;
+ int ret;
+
+ ms->noEvict = TRUE;
+
+ tex = xorg_exa_create_root_texture(pScrn, pScrn->virtualX, pScrn->virtualY,
+ pScrn->depth, pScrn->bitsPerPixel);
+
+ if (!tex)
+ return FALSE;
+
+ if (!ms->api->local_handle_from_texture(ms->api, ms->screen,
+ tex,
+ &stride,
+ &handle))
+ goto err_destroy;
+
+ ret = drmModeAddFB(ms->fd,
+ pScrn->virtualX,
+ pScrn->virtualY,
+ pScrn->depth,
+ pScrn->bitsPerPixel,
+ stride,
+ handle,
+ &ms->fb_id);
+ if (ret) {
+ debug_printf("%s: failed to create framebuffer (%i, %s)",
+ __func__, ret, strerror(-ret));
+ goto err_destroy;
+ }
+
+ pScrn->frameX0 = 0;
+ pScrn->frameY0 = 0;
+ drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ pipe_texture_reference(&ms->root_texture, tex);
+ pipe_texture_reference(&tex, NULL);
+
+ return TRUE;
+
+err_destroy:
+ pipe_texture_reference(&tex, NULL);
+ return FALSE;
+}
+
+static Bool
+drv_bind_front_buffer_ga3d(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ struct pipe_texture *check;
+
+ xorg_exa_set_displayed_usage(rootPixmap);
+ xorg_exa_set_shared_usage(rootPixmap);
+ xorg_exa_set_texture(rootPixmap, ms->root_texture);
+ if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
+ FatalError("Couldn't adjust screen pixmap\n");
+
+ check = xorg_exa_get_texture(rootPixmap);
+ if (ms->root_texture != check)
+ FatalError("Created new root texture\n");
+
+ pipe_texture_reference(&check, NULL);
+ return TRUE;
+}
+
+#ifdef HAVE_LIBKMS
+static Bool
+drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+
+ /* XXX Do something with the rootPixmap.
+ * This currently works fine but if we are getting crashes in
+ * the fb functions after VT switches maybe look more into it.
+ */
+ (void)rootPixmap;
+
+ if (!ms->root_bo)
+ return TRUE;
+
+ kms_bo_unmap(ms->root_bo);
+ kms_bo_destroy(&ms->root_bo);
+ return TRUE;
+}
+
+static Bool
+drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ unsigned handle, stride;
+ struct kms_bo *bo;
+ unsigned attr[8];
+ int ret;
+
+ attr[0] = KMS_BO_TYPE;
+ attr[1] = KMS_BO_TYPE_SCANOUT;
+ attr[2] = KMS_WIDTH;
+ attr[3] = pScrn->virtualX;
+ attr[4] = KMS_HEIGHT;
+ attr[5] = pScrn->virtualY;
+ attr[6] = 0;
+
+ if (kms_bo_create(ms->kms, attr, &bo))
+ return FALSE;
+
+ if (kms_bo_get_prop(bo, KMS_PITCH, &stride))
+ goto err_destroy;
+
+ if (kms_bo_get_prop(bo, KMS_HANDLE, &handle))
+ goto err_destroy;
+
+ ret = drmModeAddFB(ms->fd,
+ pScrn->virtualX,
+ pScrn->virtualY,
+ pScrn->depth,
+ pScrn->bitsPerPixel,
+ stride,
+ handle,
+ &ms->fb_id);
+ if (ret) {
+ debug_printf("%s: failed to create framebuffer (%i, %s)",
+ __func__, ret, strerror(-ret));
+ goto err_destroy;
+ }
+
+ pScrn->frameX0 = 0;
+ pScrn->frameY0 = 0;
+ drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ ms->root_bo = bo;
+
+ return TRUE;
+
+err_destroy:
+ kms_bo_destroy(&bo);
+ return FALSE;
+}
+
+static Bool
+drv_bind_front_buffer_kms(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ unsigned stride;
+ void *ptr;
+
+ if (kms_bo_get_prop(ms->root_bo, KMS_PITCH, &stride))
+ return FALSE;
+
+ if (kms_bo_map(ms->root_bo, &ptr))
+ goto err_destroy;
+
+ pScreen->ModifyPixmapHeader(rootPixmap,
+ pScreen->width,
+ pScreen->height,
+ pScreen->rootDepth,
+ pScrn->bitsPerPixel,
+ stride,
+ ptr);
+ return TRUE;
+
+err_destroy:
+ kms_bo_destroy(&ms->root_bo);
+ return FALSE;
+}
+#endif /* HAVE_LIBKMS */
+
+static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn)
+{
+ modesettingPtr ms = modesettingPTR(pScrn);
+ if (ms->screen) {
+ ms->destroy_front_buffer = drv_destroy_front_buffer_ga3d;
+ ms->create_front_buffer = drv_create_front_buffer_ga3d;
+ ms->bind_front_buffer = drv_bind_front_buffer_ga3d;
+#ifdef HAVE_LIBKMS
+ } else if (ms->kms) {
+ ms->destroy_front_buffer = drv_destroy_front_buffer_kms;
+ ms->create_front_buffer = drv_create_front_buffer_kms;
+ ms->bind_front_buffer = drv_bind_front_buffer_kms;
+#endif
+ } else
+ return FALSE;
+
+ return TRUE;
+}
+
/* vim: set sw=4 ts=8 sts=4: */
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index bd97baae2b..d9432babf1 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -43,38 +43,104 @@
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
#include "util/u_rect.h"
+#include "util/u_math.h"
+#include "util/u_debug.h"
#define DEBUG_PRINT 0
-#define DEBUG_SOLID 0
-#define ACCEL_ENABLED TRUE
+#define ROUND_UP_TEXTURES 1
/*
* Helper functions
*/
+struct render_format_str {
+ int format;
+ const char *name;
+};
+static const struct render_format_str formats_info[] =
+{
+ {PICT_a8r8g8b8, "PICT_a8r8g8b8"},
+ {PICT_x8r8g8b8, "PICT_x8r8g8b8"},
+ {PICT_a8b8g8r8, "PICT_a8b8g8r8"},
+ {PICT_x8b8g8r8, "PICT_x8b8g8r8"},
+#ifdef PICT_TYPE_BGRA
+ {PICT_b8g8r8a8, "PICT_b8g8r8a8"},
+ {PICT_b8g8r8x8, "PICT_b8g8r8x8"},
+ {PICT_a2r10g10b10, "PICT_a2r10g10b10"},
+ {PICT_x2r10g10b10, "PICT_x2r10g10b10"},
+ {PICT_a2b10g10r10, "PICT_a2b10g10r10"},
+ {PICT_x2b10g10r10, "PICT_x2b10g10r10"},
+#endif
+ {PICT_r8g8b8, "PICT_r8g8b8"},
+ {PICT_b8g8r8, "PICT_b8g8r8"},
+ {PICT_r5g6b5, "PICT_r5g6b5"},
+ {PICT_b5g6r5, "PICT_b5g6r5"},
+ {PICT_a1r5g5b5, "PICT_a1r5g5b5"},
+ {PICT_x1r5g5b5, "PICT_x1r5g5b5"},
+ {PICT_a1b5g5r5, "PICT_a1b5g5r5"},
+ {PICT_x1b5g5r5, "PICT_x1b5g5r5"},
+ {PICT_a4r4g4b4, "PICT_a4r4g4b4"},
+ {PICT_x4r4g4b4, "PICT_x4r4g4b4"},
+ {PICT_a4b4g4r4, "PICT_a4b4g4r4"},
+ {PICT_x4b4g4r4, "PICT_x4b4g4r4"},
+ {PICT_a8, "PICT_a8"},
+ {PICT_r3g3b2, "PICT_r3g3b2"},
+ {PICT_b2g3r3, "PICT_b2g3r3"},
+ {PICT_a2r2g2b2, "PICT_a2r2g2b2"},
+ {PICT_a2b2g2r2, "PICT_a2b2g2r2"},
+ {PICT_c8, "PICT_c8"},
+ {PICT_g8, "PICT_g8"},
+ {PICT_x4a4, "PICT_x4a4"},
+ {PICT_x4c4, "PICT_x4c4"},
+ {PICT_x4g4, "PICT_x4g4"},
+ {PICT_a4, "PICT_a4"},
+ {PICT_r1g2b1, "PICT_r1g2b1"},
+ {PICT_b1g2r1, "PICT_b1g2r1"},
+ {PICT_a1r1g1b1, "PICT_a1r1g1b1"},
+ {PICT_a1b1g1r1, "PICT_a1b1g1r1"},
+ {PICT_c4, "PICT_c4"},
+ {PICT_g4, "PICT_g4"},
+ {PICT_a1, "PICT_a1"},
+ {PICT_g1, "PICT_g1"}
+};
+static const char *render_format_name(int format)
+{
+ int i = 0;
+ for (i = 0; i < sizeof(formats_info)/sizeof(formats_info[0]); ++i) {
+ if (formats_info[i].format == format)
+ return formats_info[i].name;
+ }
+ return NULL;
+}
static void
-exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
+exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp, int *picture_format)
{
switch (depth) {
case 32:
*format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ *picture_format = PICT_a8r8g8b8;
assert(*bbp == 32);
break;
case 24:
*format = PIPE_FORMAT_X8R8G8B8_UNORM;
+ *picture_format = PICT_x8r8g8b8;
assert(*bbp == 32);
break;
case 16:
*format = PIPE_FORMAT_R5G6B5_UNORM;
+ *picture_format = PICT_r5g6b5;
assert(*bbp == 16);
break;
case 15:
*format = PIPE_FORMAT_A1R5G5B5_UNORM;
+ *picture_format = PICT_x1r5g5b5;
assert(*bbp == 16);
break;
case 8:
*format = PIPE_FORMAT_L8_UNORM;
+ *picture_format = PICT_a8;
assert(*bbp == 8);
break;
case 4:
@@ -87,16 +153,6 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
}
}
-static void
-xorg_exa_common_done(struct exa_context *exa)
-{
- exa->copy.src = NULL;
- exa->copy.dst = NULL;
- exa->transform.has_src = FALSE;
- exa->transform.has_mask = FALSE;
- exa->has_solid_color = FALSE;
- exa->num_bound_samplers = 0;
-}
/*
* Static exported EXA functions
@@ -105,15 +161,7 @@ xorg_exa_common_done(struct exa_context *exa)
static void
ExaWaitMarker(ScreenPtr pScreen, int marker)
{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_context *exa = ms->exa;
-
-#if 0
- xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
-#else
- xorg_exa_finish(exa);
-#endif
+ /* Nothing to do, handled in the PrepareAccess hook */
}
static int
@@ -122,6 +170,11 @@ ExaMarkSync(ScreenPtr pScreen)
return 1;
}
+
+/***********************************************************************
+ * Screen upload/download
+ */
+
static Bool
ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
int dst_pitch)
@@ -150,7 +203,7 @@ ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
x, y, w, h, dst_pitch);
#endif
- util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0,
+ util_copy_rect((unsigned char*)dst, priv->tex->format, dst_pitch, 0, 0,
w, h, exa->scrn->transfer_map(exa->scrn, transfer),
transfer->stride, 0, 0);
@@ -174,6 +227,11 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
if (!priv || !priv->tex)
return FALSE;
+ /* make sure that any pending operations are flushed to hardware */
+ if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
+ (PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE))
+ xorg_exa_flush(exa, 0, NULL);
+
transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
PIPE_TRANSFER_WRITE, x, y, w, h);
if (!transfer)
@@ -185,7 +243,7 @@ ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
#endif
util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
- &priv->tex->block, transfer->stride, 0, 0, w, h,
+ priv->tex->format, transfer->stride, 0, 0, w, h,
(unsigned char*)src, src_pitch, 0, 0);
exa->scrn->transfer_unmap(exa->scrn, transfer);
@@ -217,13 +275,18 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
PIPE_REFERENCED_FOR_WRITE)
exa->pipe->flush(exa->pipe, 0, NULL);
+ assert(pPix->drawable.width <= priv->tex->width0);
+ assert(pPix->drawable.height <= priv->tex->height0);
+
priv->map_transfer =
exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
#ifdef EXA_MIXED_PIXMAPS
PIPE_TRANSFER_MAP_DIRECTLY |
#endif
PIPE_TRANSFER_READ_WRITE,
- 0, 0, priv->tex->width[0], priv->tex->height[0]);
+ 0, 0,
+ pPix->drawable.width,
+ pPix->drawable.height );
if (!priv->map_transfer)
#ifdef EXA_MIXED_PIXMAPS
return FALSE;
@@ -266,29 +329,9 @@ ExaFinishAccess(PixmapPtr pPix, int index)
}
}
-static void
-ExaDone(PixmapPtr pPixmap)
-{
- ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
- struct exa_context *exa = ms->exa;
-
- if (!priv)
- return;
-
- xorg_exa_common_done(exa);
-}
-
-static void
-ExaDoneComposite(PixmapPtr pPixmap)
-{
- ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_context *exa = ms->exa;
-
- xorg_exa_common_done(exa);
-}
+/***********************************************************************
+ * Solid Fills
+ */
static Bool
ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
@@ -301,6 +344,9 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
#if DEBUG_PRINT
debug_printf("ExaPrepareSolid(0x%x)\n", fg);
#endif
+ if (!exa->accel)
+ return FALSE;
+
if (!exa->pipe)
XORG_FALLBACK("accle not enabled");
@@ -319,11 +365,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
XORG_FALLBACK("format %s", pf_name(priv->tex->format));
}
-#if DEBUG_SOLID
- fg = 0xffff0000;
-#endif
-
- return ACCEL_ENABLED && xorg_solid_bind_state(exa, priv, fg);
+ return xorg_solid_bind_state(exa, priv, fg);
}
static void
@@ -338,48 +380,34 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1);
#endif
-#if 0
if (x0 == 0 && y0 == 0 &&
- x1 == priv->tex->width[0] &&
- y1 == priv->tex->height[0]) {
- exa->ctx->clear(exa->pipe, PIPE_CLEAR_COLOR,
- exa->solid_color, 1., 0);
- } else
-#endif
+ x1 == pPixmap->drawable.width && y1 == pPixmap->drawable.height) {
+ exa->pipe->clear(exa->pipe, PIPE_CLEAR_COLOR, exa->solid_color, 0.0, 0);
+ return;
+ }
-#if DEBUG_SOLID
- exa->solid_color[0] = 0.f;
- exa->solid_color[1] = 1.f;
- exa->solid_color[2] = 0.f;
- exa->solid_color[3] = 1.f;
- xorg_solid(exa, priv, 0, 0, 1024, 768);
- exa->solid_color[0] = 1.f;
- exa->solid_color[1] = 0.f;
- exa->solid_color[2] = 0.f;
- exa->solid_color[3] = 1.f;
- xorg_solid(exa, priv, 0, 0, 300, 300);
- xorg_solid(exa, priv, 300, 300, 350, 350);
- xorg_solid(exa, priv, 350, 350, 500, 500);
-
- xorg_solid(exa, priv,
- priv->tex->width[0] - 10,
- priv->tex->height[0] - 10,
- priv->tex->width[0],
- priv->tex->height[0]);
-
- exa->solid_color[0] = 0.f;
- exa->solid_color[1] = 0.f;
- exa->solid_color[2] = 1.f;
- exa->solid_color[3] = 1.f;
-
- exa->has_solid_color = FALSE;
- ExaPrepareCopy(pPixmap, pPixmap, 0, 0, GXcopy, 0xffffffff);
- ExaCopy(pPixmap, 0, 0, 50, 50, 500, 500);
-#else
xorg_solid(exa, priv, x0, y0, x1, y1) ;
-#endif
}
+
+static void
+ExaDoneSolid(PixmapPtr pPixmap)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+ struct exa_context *exa = ms->exa;
+
+ if (!priv)
+ return;
+
+ xorg_composite_done(exa);
+}
+
+/***********************************************************************
+ * Copy Blits
+ */
+
static Bool
ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
int ydir, int alu, Pixel planeMask)
@@ -393,6 +421,10 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
#if DEBUG_PRINT
debug_printf("ExaPrepareCopy\n");
#endif
+
+ if (!exa->accel)
+ return FALSE;
+
if (!exa->pipe)
XORG_FALLBACK("accle not enabled");
@@ -421,7 +453,52 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
exa->copy.src = src_priv;
exa->copy.dst = priv;
- return ACCEL_ENABLED;
+ /* For same-surface copies, the pipe->surface_copy path is clearly
+ * superior, providing it is implemented. In other cases it's not
+ * clear what the better path would be, and eventually we'd
+ * probably want to gather timings and choose dynamically.
+ */
+ if (exa->pipe->surface_copy &&
+ exa->copy.src == exa->copy.dst) {
+
+ exa->copy.use_surface_copy = TRUE;
+
+ exa->copy.src_surface =
+ exa->scrn->get_tex_surface( exa->scrn,
+ exa->copy.src->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ);
+
+ exa->copy.dst_surface =
+ exa->scrn->get_tex_surface( exa->scrn,
+ exa->copy.dst->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE );
+ }
+ else {
+ exa->copy.use_surface_copy = FALSE;
+
+ if (exa->copy.dst == exa->copy.src)
+ exa->copy.src_texture = renderer_clone_texture( exa->renderer,
+ exa->copy.src->tex );
+ else
+ pipe_texture_reference(&exa->copy.src_texture,
+ exa->copy.src->tex);
+
+ exa->copy.dst_surface =
+ exa->scrn->get_tex_surface(exa->scrn,
+ exa->copy.dst->tex,
+ 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+
+ renderer_copy_prepare(exa->renderer,
+ exa->copy.dst_surface,
+ exa->copy.src_texture );
+ }
+
+
+ return TRUE;
}
static void
@@ -439,12 +516,113 @@ ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
#endif
debug_assert(priv == exa->copy.dst);
+ (void) priv;
+
+ if (exa->copy.use_surface_copy) {
+ /* XXX: consider exposing >1 box in surface_copy interface.
+ */
+ exa->pipe->surface_copy( exa->pipe,
+ exa->copy.dst_surface,
+ dstX, dstY,
+ exa->copy.src_surface,
+ srcX, srcY,
+ width, height );
+ }
+ else {
+ renderer_copy_pixmap(exa->renderer,
+ dstX, dstY,
+ srcX, srcY,
+ width, height,
+ exa->copy.src_texture->width0,
+ exa->copy.src_texture->height0);
+ }
+}
+
+static void
+ExaDoneCopy(PixmapPtr pPixmap)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+ struct exa_context *exa = ms->exa;
- renderer_copy_pixmap(exa->renderer, exa->copy.dst, dstX, dstY,
- exa->copy.src, srcX, srcY,
- width, height);
+ if (!priv)
+ return;
+
+ renderer_draw_flush(exa->renderer);
+
+ exa->copy.src = NULL;
+ exa->copy.dst = NULL;
+ pipe_surface_reference(&exa->copy.src_surface, NULL);
+ pipe_surface_reference(&exa->copy.dst_surface, NULL);
+ pipe_texture_reference(&exa->copy.src_texture, NULL);
}
+
+
+static Bool
+picture_check_formats(struct exa_pixmap_priv *pSrc, PicturePtr pSrcPicture)
+{
+ if (pSrc->picture_format == pSrcPicture->format)
+ return TRUE;
+
+ if (pSrc->picture_format != PICT_a8r8g8b8)
+ return FALSE;
+
+ /* pSrc->picture_format == PICT_a8r8g8b8 */
+ switch (pSrcPicture->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ /* just treat these two as x8... */
+ case PICT_r8g8b8:
+ case PICT_b8g8r8:
+ return TRUE;
+#ifdef PICT_TYPE_BGRA
+ case PICT_b8g8r8a8:
+ case PICT_b8g8r8x8:
+ return FALSE; /* does not support swizzleing the alpha channel yet */
+ case PICT_a2r10g10b10:
+ case PICT_x2r10g10b10:
+ case PICT_a2b10g10r10:
+ case PICT_x2b10g10r10:
+ return FALSE;
+#endif
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ * Composite entrypoints
+ */
+
+static Bool
+ExaCheckComposite(int op,
+ PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPicture->pDrawable->pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa = ms->exa;
+
+#if DEBUG_PRINT
+ debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
+ op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
+#endif
+
+ if (!exa->accel)
+ return FALSE;
+
+ return xorg_composite_accelerated(op,
+ pSrcPicture,
+ pMaskPicture,
+ pDstPicture);
+}
+
+
static Bool
ExaPrepareComposite(int op, PicturePtr pSrcPicture,
PicturePtr pMaskPicture, PicturePtr pDstPicture,
@@ -455,9 +633,16 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
struct exa_context *exa = ms->exa;
struct exa_pixmap_priv *priv;
+ if (!exa->accel)
+ return FALSE;
+
#if DEBUG_PRINT
debug_printf("ExaPrepareComposite(%d, src=0x%p, mask=0x%p, dst=0x%p)\n",
op, pSrcPicture, pMaskPicture, pDstPicture);
+ debug_printf("\tFormats: src(%s), mask(%s), dst(%s)\n",
+ pSrcPicture ? render_format_name(pSrcPicture->format) : "none",
+ pMaskPicture ? render_format_name(pMaskPicture->format) : "none",
+ pDstPicture ? render_format_name(pDstPicture->format) : "none");
#endif
if (!exa->pipe)
XORG_FALLBACK("accle not enabled");
@@ -471,6 +656,11 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
XORG_FALLBACK("pDst format: %s", pf_name(priv->tex->format));
+ if (priv->picture_format != pDstPicture->format)
+ XORG_FALLBACK("pDst pic_format: %s != %s",
+ render_format_name(priv->picture_format),
+ render_format_name(pDstPicture->format));
+
if (pSrc) {
priv = exaGetPixmapDriverPrivate(pSrc);
if (!priv || !priv->tex)
@@ -480,6 +670,12 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
priv->tex->target,
PIPE_TEXTURE_USAGE_SAMPLER, 0))
XORG_FALLBACK("pSrc format: %s", pf_name(priv->tex->format));
+
+ if (!picture_check_formats(priv, pSrcPicture))
+ XORG_FALLBACK("pSrc pic_format: %s != %s",
+ render_format_name(priv->picture_format),
+ render_format_name(pSrcPicture->format));
+
}
if (pMask) {
@@ -491,10 +687,14 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
priv->tex->target,
PIPE_TEXTURE_USAGE_SAMPLER, 0))
XORG_FALLBACK("pMask format: %s", pf_name(priv->tex->format));
+
+ if (!picture_check_formats(priv, pMaskPicture))
+ XORG_FALLBACK("pMask pic_format: %s != %s",
+ render_format_name(priv->picture_format),
+ render_format_name(pMaskPicture->format));
}
- return ACCEL_ENABLED &&
- xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
+ return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
pDstPicture,
pSrc ? exaGetPixmapDriverPrivate(pSrc) : NULL,
pMask ? exaGetPixmapDriverPrivate(pMask) : NULL,
@@ -521,22 +721,23 @@ ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
dstX, dstY, width, height);
}
-static Bool
-ExaCheckComposite(int op,
- PicturePtr pSrcPicture, PicturePtr pMaskPicture,
- PicturePtr pDstPicture)
+
+
+static void
+ExaDoneComposite(PixmapPtr pPixmap)
{
- boolean accelerated = xorg_composite_accelerated(op,
- pSrcPicture,
- pMaskPicture,
- pDstPicture);
-#if DEBUG_PRINT
- debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
- op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
-#endif
- return ACCEL_ENABLED && accelerated;
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa = ms->exa;
+
+ xorg_composite_done(exa);
}
+
+/***********************************************************************
+ * Pixmaps
+ */
+
static void *
ExaCreatePixmap(ScreenPtr pScreen, int size, int align)
{
@@ -610,33 +811,22 @@ xorg_exa_set_shared_usage(PixmapPtr pPixmap)
return 0;
}
-unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_pixmap_priv *priv;
- unsigned handle;
- unsigned stride;
- if (!ms->exa) {
- FatalError("NO MS->EXA\n");
- return 0;
- }
- priv = exaGetPixmapDriverPrivate(pPixmap);
-
- if (!priv) {
- FatalError("NO PIXMAP PRIVATE\n");
- return 0;
- }
+static Bool
+size_match( int width, int tex_width )
+{
+#if ROUND_UP_TEXTURES
+ if (width > tex_width)
+ return FALSE;
- ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle);
- if (stride_out)
- *stride_out = stride;
+ if (width * 2 < tex_width)
+ return FALSE;
- return handle;
+ return TRUE;
+#else
+ return width == tex_width;
+#endif
}
static Bool
@@ -653,6 +843,17 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
if (!priv || pPixData)
return FALSE;
+ if (0) {
+ debug_printf("%s pixmap %p sz %dx%dx%d devKind %d\n",
+ __FUNCTION__, pPixmap, width, height, bitsPerPixel, devKind);
+
+ if (priv->tex)
+ debug_printf(" ==> old texture %dx%d\n",
+ priv->tex->width0,
+ priv->tex->height0);
+ }
+
+
if (depth <= 0)
depth = pPixmap->drawable.depth;
@@ -671,21 +872,31 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
miModifyPixmapHeader(pPixmap, width, height, depth,
bitsPerPixel, devKind, NULL);
+ priv->width = width;
+ priv->height = height;
+
/* Deal with screen resize */
- if (!priv->tex ||
- (priv->tex->width[0] != width ||
- priv->tex->height[0] != height ||
+ if ((exa->accel || priv->flags) &&
+ (!priv->tex ||
+ !size_match(width, priv->tex->width0) ||
+ !size_match(height, priv->tex->height0) ||
priv->tex_flags != priv->flags)) {
struct pipe_texture *texture = NULL;
struct pipe_texture template;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
- exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
- pf_get_block(template.format, &template.block);
- template.width[0] = width;
- template.height[0] = height;
- template.depth[0] = 1;
+ exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &priv->picture_format);
+ if (ROUND_UP_TEXTURES && priv->flags == 0) {
+ template.width0 = util_next_power_of_two(width);
+ template.height0 = util_next_power_of_two(height);
+ }
+ else {
+ template.width0 = width;
+ template.height0 = height;
+ }
+
+ template.depth0 = 1;
template.last_level = 0;
template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
priv->tex_flags = priv->flags;
@@ -698,15 +909,15 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
dst_surf = exa->scrn->get_tex_surface(
exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
src_surf = xorg_gpu_surface(exa->pipe->screen, priv);
- if (exa->pipe->surface_copy) {
- exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
- 0, 0, min(width, texture->width[0]),
- min(height, texture->height[0]));
- } else {
- util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf,
- 0, 0, min(width, texture->width[0]),
- min(height, texture->height[0]));
- }
+ if (exa->pipe->surface_copy) {
+ exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
+ 0, 0, min(width, texture->width0),
+ min(height, texture->height0));
+ } else {
+ util_surface_copy(exa->pipe, FALSE, dst_surf, 0, 0, src_surf,
+ 0, 0, min(width, texture->width0),
+ min(height, texture->height0));
+ }
exa->scrn->tex_surface_destroy(dst_surf);
exa->scrn->tex_surface_destroy(src_surf);
}
@@ -738,8 +949,8 @@ xorg_exa_set_texture(PixmapPtr pPixmap, struct pipe_texture *tex)
if (!priv)
return FALSE;
- if (pPixmap->drawable.width != tex->width[0] ||
- pPixmap->drawable.height != tex->height[0])
+ if (pPixmap->drawable.width != tex->width0 ||
+ pPixmap->drawable.height != tex->height0)
return FALSE;
pipe_texture_reference(&priv->tex, tex);
@@ -756,14 +967,14 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
struct pipe_texture template;
+ int dummy;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
- exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
- pf_get_block(template.format, &template.block);
- template.width[0] = width;
- template.height[0] = height;
- template.depth[0] = 1;
+ exa_get_pipe_format(depth, &template.format, &bitsPerPixel, &dummy);
+ template.width0 = width;
+ template.height0 = height;
+ template.depth0 = 1;
template.last_level = 0;
template.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
template.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
@@ -782,6 +993,9 @@ xorg_exa_close(ScrnInfoPtr pScrn)
if (exa->pipe)
exa->pipe->destroy(exa->pipe);
+ exa->pipe = NULL;
+ /* Since this was shared be proper with the pointer */
+ ms->ctx = NULL;
exaDriverFini(pScrn->pScreen);
xfree(exa);
@@ -789,7 +1003,7 @@ xorg_exa_close(ScrnInfoPtr pScrn)
}
void *
-xorg_exa_init(ScrnInfoPtr pScrn)
+xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
{
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa;
@@ -827,10 +1041,10 @@ xorg_exa_init(ScrnInfoPtr pScrn)
pExa->MarkSync = ExaMarkSync;
pExa->PrepareSolid = ExaPrepareSolid;
pExa->Solid = ExaSolid;
- pExa->DoneSolid = ExaDone;
+ pExa->DoneSolid = ExaDoneSolid;
pExa->PrepareCopy = ExaPrepareCopy;
pExa->Copy = ExaCopy;
- pExa->DoneCopy = ExaDone;
+ pExa->DoneCopy = ExaDoneCopy;
pExa->CheckComposite = ExaCheckComposite;
pExa->PrepareComposite = ExaPrepareComposite;
pExa->Composite = ExaComposite;
@@ -854,6 +1068,7 @@ xorg_exa_init(ScrnInfoPtr pScrn)
ms->ctx = exa->pipe;
exa->renderer = renderer_create(exa->pipe);
+ exa->accel = accel;
return (void *)exa;
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index 45f88d9404..f2cefe23b9 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -24,6 +24,8 @@ struct exa_context
float solid_color[4];
boolean has_solid_color;
+ boolean accel;
+
/* float[9] projective matrix bound to pictures */
struct {
float src[9];
@@ -33,16 +35,27 @@ struct exa_context
} transform;
struct {
+ boolean use_surface_copy;
+
struct exa_pixmap_priv *src;
struct exa_pixmap_priv *dst;
+
+ struct pipe_surface *src_surface;
+ struct pipe_surface *dst_surface;
+
+ struct pipe_texture *src_texture;
} copy;
};
struct exa_pixmap_priv
{
+ int width, height;
+
int flags;
int tex_flags;
+ int picture_format;
+
struct pipe_texture *tex;
struct pipe_texture *depth_stencil_tex;
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
index 83cc12fea9..bed17caab7 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
@@ -43,6 +43,38 @@
* OUT[0] = color
*/
+static void
+print_fs_traits(int fs_traits)
+{
+ const char *strings[] = {
+ "FS_COMPOSITE", /* = 1 << 0, */
+ "FS_MASK", /* = 1 << 1, */
+ "FS_SOLID_FILL", /* = 1 << 2, */
+ "FS_LINGRAD_FILL", /* = 1 << 3, */
+ "FS_RADGRAD_FILL", /* = 1 << 4, */
+ "FS_CA_FULL", /* = 1 << 5, */ /* src.rgba * mask.rgba */
+ "FS_CA_SRCALPHA", /* = 1 << 6, */ /* src.aaaa * mask.rgba */
+ "FS_YUV", /* = 1 << 7, */
+ "FS_SRC_REPEAT_NONE", /* = 1 << 8, */
+ "FS_MASK_REPEAT_NONE",/* = 1 << 9, */
+ "FS_SRC_SWIZZLE_RGB", /* = 1 << 10, */
+ "FS_MASK_SWIZZLE_RGB",/* = 1 << 11, */
+ "FS_SRC_SET_ALPHA", /* = 1 << 12, */
+ "FS_MASK_SET_ALPHA", /* = 1 << 13, */
+ "FS_SRC_LUMINANCE", /* = 1 << 14, */
+ "FS_MASK_LUMINANCE", /* = 1 << 15, */
+ };
+ int i, k;
+ debug_printf("%s: ", __func__);
+
+ for (i = 0, k = 1; k < (1 << 16); i++, k <<= 1) {
+ if (fs_traits & k)
+ debug_printf("%s, ", strings[i]);
+ }
+
+ debug_printf("\n");
+}
+
struct xorg_shaders {
struct xorg_renderer *r;
@@ -55,7 +87,8 @@ src_in_mask(struct ureg_program *ureg,
struct ureg_dst dst,
struct ureg_src src,
struct ureg_src mask,
- int component_alpha)
+ unsigned component_alpha,
+ unsigned mask_luminance)
{
if (component_alpha == FS_CA_FULL) {
ureg_MUL(ureg, dst, src, mask);
@@ -64,8 +97,12 @@ src_in_mask(struct ureg_program *ureg,
ureg_scalar(src, TGSI_SWIZZLE_W), mask);
}
else {
- ureg_MUL(ureg, dst, src,
- ureg_scalar(mask, TGSI_SWIZZLE_X));
+ if (mask_luminance)
+ ureg_MUL(ureg, dst, src,
+ ureg_scalar(mask, TGSI_SWIZZLE_X));
+ else
+ ureg_MUL(ureg, dst, src,
+ ureg_scalar(mask, TGSI_SWIZZLE_W));
}
}
@@ -233,10 +270,10 @@ create_vs(struct pipe_context *pipe,
struct ureg_src src;
struct ureg_dst dst;
struct ureg_src const0, const1;
- boolean is_fill = vs_traits & VS_FILL;
- boolean is_composite = vs_traits & VS_COMPOSITE;
- boolean has_mask = vs_traits & VS_MASK;
- boolean is_yuv = vs_traits & VS_YUV;
+ boolean is_fill = (vs_traits & VS_FILL) != 0;
+ boolean is_composite = (vs_traits & VS_COMPOSITE) != 0;
+ boolean has_mask = (vs_traits & VS_MASK) != 0;
+ boolean is_yuv = (vs_traits & VS_YUV) != 0;
unsigned input_slot = 0;
ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
@@ -353,6 +390,69 @@ create_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg)
return ureg_create_shader_and_destroy(ureg, pipe);
}
+
+static INLINE void
+xrender_tex(struct ureg_program *ureg,
+ struct ureg_dst dst,
+ struct ureg_src coords,
+ struct ureg_src sampler,
+ struct ureg_src imm0,
+ boolean repeat_none,
+ boolean swizzle,
+ boolean set_alpha)
+{
+ if (repeat_none) {
+ struct ureg_dst tmp0 = ureg_DECL_temporary(ureg);
+ struct ureg_dst tmp1 = ureg_DECL_temporary(ureg);
+ ureg_SGT(ureg, tmp1, ureg_swizzle(coords,
+ TGSI_SWIZZLE_X,
+ TGSI_SWIZZLE_Y,
+ TGSI_SWIZZLE_X,
+ TGSI_SWIZZLE_Y),
+ ureg_scalar(imm0, TGSI_SWIZZLE_X));
+ ureg_SLT(ureg, tmp0, ureg_swizzle(coords,
+ TGSI_SWIZZLE_X,
+ TGSI_SWIZZLE_Y,
+ TGSI_SWIZZLE_X,
+ TGSI_SWIZZLE_Y),
+ ureg_scalar(imm0, TGSI_SWIZZLE_W));
+ ureg_MIN(ureg, tmp0, ureg_src(tmp0), ureg_src(tmp1));
+ ureg_MIN(ureg, tmp0, ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_X),
+ ureg_scalar(ureg_src(tmp0), TGSI_SWIZZLE_Y));
+ ureg_TEX(ureg, tmp1, TGSI_TEXTURE_2D, coords, sampler);
+ if (swizzle)
+ ureg_MOV(ureg, tmp1, ureg_swizzle(ureg_src(tmp1),
+ TGSI_SWIZZLE_Z,
+ TGSI_SWIZZLE_Y,
+ TGSI_SWIZZLE_X,
+ TGSI_SWIZZLE_W));
+ if (set_alpha)
+ ureg_MOV(ureg,
+ ureg_writemask(tmp1, TGSI_WRITEMASK_W),
+ ureg_scalar(imm0, TGSI_SWIZZLE_W));
+ ureg_MUL(ureg, dst, ureg_src(tmp1), ureg_src(tmp0));
+ ureg_release_temporary(ureg, tmp0);
+ ureg_release_temporary(ureg, tmp1);
+ } else {
+ if (swizzle) {
+ struct ureg_dst tmp = ureg_DECL_temporary(ureg);
+ ureg_TEX(ureg, tmp, TGSI_TEXTURE_2D, coords, sampler);
+ ureg_MOV(ureg, dst, ureg_swizzle(ureg_src(tmp),
+ TGSI_SWIZZLE_Z,
+ TGSI_SWIZZLE_Y,
+ TGSI_SWIZZLE_X,
+ TGSI_SWIZZLE_W));
+ ureg_release_temporary(ureg, tmp);
+ } else {
+ ureg_TEX(ureg, dst, TGSI_TEXTURE_2D, coords, sampler);
+ }
+ if (set_alpha)
+ ureg_MOV(ureg,
+ ureg_writemask(dst, TGSI_WRITEMASK_W),
+ ureg_scalar(imm0, TGSI_SWIZZLE_W));
+ }
+}
+
static void *
create_fs(struct pipe_context *pipe,
unsigned fs_traits)
@@ -362,14 +462,29 @@ create_fs(struct pipe_context *pipe,
struct ureg_src /*dst_pos,*/ src_input, mask_pos;
struct ureg_dst src, mask;
struct ureg_dst out;
- boolean has_mask = fs_traits & FS_MASK;
- boolean is_fill = fs_traits & FS_FILL;
- boolean is_composite = fs_traits & FS_COMPOSITE;
- boolean is_solid = fs_traits & FS_SOLID_FILL;
- boolean is_lingrad = fs_traits & FS_LINGRAD_FILL;
- boolean is_radgrad = fs_traits & FS_RADGRAD_FILL;
- unsigned comp_alpha = fs_traits & FS_COMPONENT_ALPHA;
- boolean is_yuv = fs_traits & FS_YUV;
+ struct ureg_src imm0 = { 0 };
+ unsigned has_mask = (fs_traits & FS_MASK) != 0;
+ unsigned is_fill = (fs_traits & FS_FILL) != 0;
+ unsigned is_composite = (fs_traits & FS_COMPOSITE) != 0;
+ unsigned is_solid = (fs_traits & FS_SOLID_FILL) != 0;
+ unsigned is_lingrad = (fs_traits & FS_LINGRAD_FILL) != 0;
+ unsigned is_radgrad = (fs_traits & FS_RADGRAD_FILL) != 0;
+ unsigned comp_alpha_mask = fs_traits & FS_COMPONENT_ALPHA;
+ unsigned is_yuv = (fs_traits & FS_YUV) != 0;
+ unsigned src_repeat_none = (fs_traits & FS_SRC_REPEAT_NONE) != 0;
+ unsigned mask_repeat_none = (fs_traits & FS_MASK_REPEAT_NONE) != 0;
+ unsigned src_swizzle = (fs_traits & FS_SRC_SWIZZLE_RGB) != 0;
+ unsigned mask_swizzle = (fs_traits & FS_MASK_SWIZZLE_RGB) != 0;
+ unsigned src_set_alpha = (fs_traits & FS_SRC_SET_ALPHA) != 0;
+ unsigned mask_set_alpha = (fs_traits & FS_MASK_SET_ALPHA) != 0;
+ unsigned src_luminance = (fs_traits & FS_SRC_LUMINANCE) != 0;
+ unsigned mask_luminance = (fs_traits & FS_MASK_LUMINANCE) != 0;
+
+#if 0
+ print_fs_traits(fs_traits);
+#else
+ (void)print_fs_traits;
+#endif
ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
if (ureg == NULL)
@@ -377,11 +492,17 @@ create_fs(struct pipe_context *pipe,
/* it has to be either a fill, a composite op or a yuv conversion */
debug_assert((is_fill ^ is_composite) ^ is_yuv);
+ (void) is_yuv;
out = ureg_DECL_output(ureg,
TGSI_SEMANTIC_COLOR,
0);
+ if (src_repeat_none || mask_repeat_none ||
+ src_set_alpha || mask_set_alpha ||
+ src_luminance) {
+ imm0 = ureg_imm4f(ureg, 0, 0, 0, 1);
+ }
if (is_composite) {
src_sampler = ureg_DECL_sampler(ureg, 0);
src_input = ureg_DECL_fs_input(ureg,
@@ -420,16 +541,17 @@ create_fs(struct pipe_context *pipe,
TGSI_INTERPOLATE_PERSPECTIVE);
#endif
+
if (is_composite) {
- if (has_mask)
+ if (has_mask || src_luminance)
src = ureg_DECL_temporary(ureg);
else
src = out;
- ureg_TEX(ureg, src,
- TGSI_TEXTURE_2D, src_input, src_sampler);
+ xrender_tex(ureg, src, src_input, src_sampler, imm0,
+ src_repeat_none, src_swizzle, src_set_alpha);
} else if (is_fill) {
if (is_solid) {
- if (has_mask)
+ if (has_mask || src_luminance)
src = ureg_dst(src_input);
else
ureg_MOV(ureg, out, src_input);
@@ -437,7 +559,7 @@ create_fs(struct pipe_context *pipe,
struct ureg_src coords, const0124,
matrow0, matrow1, matrow2;
- if (has_mask)
+ if (has_mask || src_luminance)
src = ureg_DECL_temporary(ureg);
else
src = out;
@@ -462,13 +584,22 @@ create_fs(struct pipe_context *pipe,
} else
debug_assert(!"Unknown fill type!");
}
+ if (src_luminance) {
+ ureg_MOV(ureg, src,
+ ureg_scalar(ureg_src(src), TGSI_SWIZZLE_X));
+ ureg_MOV(ureg, ureg_writemask(src, TGSI_WRITEMASK_XYZ),
+ ureg_scalar(imm0, TGSI_SWIZZLE_X));
+ if (!has_mask)
+ ureg_MOV(ureg, out, ureg_src(src));
+ }
if (has_mask) {
mask = ureg_DECL_temporary(ureg);
- ureg_TEX(ureg, mask,
- TGSI_TEXTURE_2D, mask_pos, mask_sampler);
+ xrender_tex(ureg, mask, mask_pos, mask_sampler, imm0,
+ mask_repeat_none, mask_swizzle, mask_set_alpha);
/* src IN mask */
- src_in_mask(ureg, out, ureg_src(src), ureg_src(mask), comp_alpha);
+ src_in_mask(ureg, out, ureg_src(src), ureg_src(mask),
+ comp_alpha_mask, mask_luminance);
ureg_release_temporary(ureg, mask);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
index d3bfa304c2..6f2a361d03 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
@@ -25,7 +25,15 @@ enum xorg_fs_traits {
FS_RADGRAD_FILL = 1 << 4,
FS_CA_FULL = 1 << 5, /* src.rgba * mask.rgba */
FS_CA_SRCALPHA = 1 << 6, /* src.aaaa * mask.rgba */
- FS_YUV = 1<< 7,
+ FS_YUV = 1 << 7,
+ FS_SRC_REPEAT_NONE = 1 << 8,
+ FS_MASK_REPEAT_NONE = 1 << 9,
+ FS_SRC_SWIZZLE_RGB = 1 << 10,
+ FS_MASK_SWIZZLE_RGB = 1 << 11,
+ FS_SRC_SET_ALPHA = 1 << 12,
+ FS_MASK_SET_ALPHA = 1 << 13,
+ FS_SRC_LUMINANCE = 1 << 14,
+ FS_MASK_LUMINANCE = 1 << 15,
FS_FILL = (FS_SOLID_FILL |
FS_LINGRAD_FILL |
diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c
index bfeddc5e11..251f331ea7 100644
--- a/src/gallium/state_trackers/xorg/xorg_output.c
+++ b/src/gallium/state_trackers/xorg/xorg_output.c
@@ -53,7 +53,7 @@
#include "xorg_tracker.h"
-static char *connector_enum_list[] = {
+static char *output_enum_list[] = {
"Unknown",
"VGA",
"DVI",
@@ -70,19 +70,19 @@ static char *connector_enum_list[] = {
};
static void
-create_resources(xf86OutputPtr output)
+output_create_resources(xf86OutputPtr output)
{
#ifdef RANDR_12_INTERFACE
#endif /* RANDR_12_INTERFACE */
}
static void
-dpms(xf86OutputPtr output, int mode)
+output_dpms(xf86OutputPtr output, int mode)
{
}
static xf86OutputStatus
-detect(xf86OutputPtr output)
+output_detect(xf86OutputPtr output)
{
drmModeConnectorPtr drm_connector = output->driver_private;
@@ -97,7 +97,7 @@ detect(xf86OutputPtr output)
}
static DisplayModePtr
-get_modes(xf86OutputPtr output)
+output_get_modes(xf86OutputPtr output)
{
drmModeConnectorPtr drm_connector = output->driver_private;
drmModeModeInfoPtr drm_mode = NULL;
@@ -110,7 +110,6 @@ get_modes(xf86OutputPtr output)
mode = xcalloc(1, sizeof(DisplayModeRec));
if (!mode)
continue;
- mode->type = 0;
mode->Clock = drm_mode->clock;
mode->HDisplay = drm_mode->hdisplay;
mode->HSyncStart = drm_mode->hsync_start;
@@ -125,6 +124,11 @@ get_modes(xf86OutputPtr output)
mode->VScan = drm_mode->vscan;
mode->VRefresh = xf86ModeVRefresh(mode);
mode->Private = (void *)drm_mode;
+ mode->type = 0;
+ if (drm_mode->type & DRM_MODE_TYPE_PREFERRED)
+ mode->type |= M_T_PREFERRED;
+ if (drm_mode->type & DRM_MODE_TYPE_DRIVER)
+ mode->type |= M_T_DRIVER;
xf86SetModeDefaultName(mode);
modes = xf86ModesAdd(modes, mode);
xf86PrintModeline(0, mode);
@@ -135,14 +139,14 @@ get_modes(xf86OutputPtr output)
}
static int
-mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
+output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
{
return MODE_OK;
}
#ifdef RANDR_12_INTERFACE
static Bool
-set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
+output_set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
{
return TRUE;
}
@@ -150,36 +154,36 @@ set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value)
#ifdef RANDR_13_INTERFACE
static Bool
-get_property(xf86OutputPtr output, Atom property)
+output_get_property(xf86OutputPtr output, Atom property)
{
return TRUE;
}
#endif /* RANDR_13_INTERFACE */
static void
-destroy(xf86OutputPtr output)
+output_destroy(xf86OutputPtr output)
{
drmModeFreeConnector(output->driver_private);
}
static const xf86OutputFuncsRec output_funcs = {
- .create_resources = create_resources,
+ .create_resources = output_create_resources,
#ifdef RANDR_12_INTERFACE
- .set_property = set_property,
+ .set_property = output_set_property,
#endif
#ifdef RANDR_13_INTERFACE
- .get_property = get_property,
+ .get_property = output_get_property,
#endif
- .dpms = dpms,
- .detect = detect,
+ .dpms = output_dpms,
+ .detect = output_detect,
- .get_modes = get_modes,
- .mode_valid = mode_valid,
- .destroy = destroy,
+ .get_modes = output_get_modes,
+ .mode_valid = output_mode_valid,
+ .destroy = output_destroy,
};
void
-output_init(ScrnInfoPtr pScrn)
+xorg_output_init(ScrnInfoPtr pScrn)
{
modesettingPtr ms = modesettingPTR(pScrn);
xf86OutputPtr output;
@@ -220,7 +224,7 @@ output_init(ScrnInfoPtr pScrn)
#endif
snprintf(name, 32, "%s%d",
- connector_enum_list[drm_connector->connector_type],
+ output_enum_list[drm_connector->connector_type],
drm_connector->connector_type_id);
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index ac2c4935a5..d80f341e6c 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -5,6 +5,7 @@
#include "cso_cache/cso_context.h"
#include "util/u_draw_quad.h"
+#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_rect.h"
@@ -13,14 +14,11 @@
#include <math.h>
-enum AxisOrientation {
- Y0_BOTTOM,
- Y0_TOP
-};
-
#define floatsEqual(x, y) (fabs(x - y) <= 0.00001f * MIN2(fabs(x), fabs(y)))
#define floatIsZero(x) (floatsEqual((x) + 1, 1))
+#define NUM_COMPONENTS 4
+
static INLINE boolean is_affine(float *matrix)
{
return floatIsZero(matrix[2]) && floatIsZero(matrix[5])
@@ -44,131 +42,187 @@ static INLINE void map_point(float *mat, float x, float y,
}
}
+static INLINE struct pipe_buffer *
+renderer_buffer_create(struct xorg_renderer *r)
+{
+ struct pipe_buffer *buf =
+ pipe_user_buffer_create(r->pipe->screen,
+ r->buffer,
+ sizeof(float)*
+ r->buffer_size);
+ r->buffer_size = 0;
+
+ return buf;
+}
+
+static INLINE void
+renderer_draw(struct xorg_renderer *r)
+{
+ struct pipe_context *pipe = r->pipe;
+ struct pipe_buffer *buf = 0;
+ int num_verts = r->buffer_size/(r->attrs_per_vertex * NUM_COMPONENTS);
+
+ if (!r->buffer_size)
+ return;
+
+ buf = renderer_buffer_create(r);
+
+
+ if (buf) {
+ util_draw_vertex_buffer(pipe, buf, 0,
+ PIPE_PRIM_QUADS,
+ num_verts, /* verts */
+ r->attrs_per_vertex); /* attribs/vert */
+
+ pipe_buffer_reference(&buf, NULL);
+ }
+}
+
+static INLINE void
+renderer_draw_conditional(struct xorg_renderer *r,
+ int next_batch)
+{
+ if (r->buffer_size + next_batch >= BUF_SIZE ||
+ (next_batch == 0 && r->buffer_size)) {
+ renderer_draw(r);
+ }
+}
+
static void
renderer_init_state(struct xorg_renderer *r)
{
struct pipe_depth_stencil_alpha_state dsa;
+ struct pipe_rasterizer_state raster;
/* set common initial clip state */
memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
cso_set_depth_stencil_alpha(r->cso, &dsa);
+
+
+ /* XXX: move to renderer_init_state? */
+ memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
+ raster.gl_rasterization_rules = 1;
+ cso_set_rasterizer(r->cso, &raster);
+
}
static INLINE void
-setup_vertex0(float vertex[2][4], float x, float y,
- float color[4])
+add_vertex_color(struct xorg_renderer *r,
+ float x, float y,
+ float color[4])
{
- vertex[0][0] = x;
- vertex[0][1] = y;
- vertex[0][2] = 0.f; /*z*/
- vertex[0][3] = 1.f; /*w*/
-
- vertex[1][0] = color[0]; /*r*/
- vertex[1][1] = color[1]; /*g*/
- vertex[1][2] = color[2]; /*b*/
- vertex[1][3] = color[3]; /*a*/
+ float *vertex = r->buffer + r->buffer_size;
+
+ vertex[0] = x;
+ vertex[1] = y;
+ vertex[2] = 0.f; /*z*/
+ vertex[3] = 1.f; /*w*/
+
+ vertex[4] = color[0]; /*r*/
+ vertex[5] = color[1]; /*g*/
+ vertex[6] = color[2]; /*b*/
+ vertex[7] = color[3]; /*a*/
+
+ r->buffer_size += 8;
}
static INLINE void
-setup_vertex1(float vertex[2][4], float x, float y, float s, float t)
+add_vertex_1tex(struct xorg_renderer *r,
+ float x, float y, float s, float t)
{
- vertex[0][0] = x;
- vertex[0][1] = y;
- vertex[0][2] = 0.f; /*z*/
- vertex[0][3] = 1.f; /*w*/
-
- vertex[1][0] = s; /*s*/
- vertex[1][1] = t; /*t*/
- vertex[1][2] = 0.f; /*r*/
- vertex[1][3] = 1.f; /*q*/
+ float *vertex = r->buffer + r->buffer_size;
+
+ vertex[0] = x;
+ vertex[1] = y;
+ vertex[2] = 0.f; /*z*/
+ vertex[3] = 1.f; /*w*/
+
+ vertex[4] = s; /*s*/
+ vertex[5] = t; /*t*/
+ vertex[6] = 0.f; /*r*/
+ vertex[7] = 1.f; /*q*/
+
+ r->buffer_size += 8;
}
-static struct pipe_buffer *
-setup_vertex_data1(struct xorg_renderer *r,
- float srcX, float srcY, float dstX, float dstY,
- float width, float height,
- struct pipe_texture *src, float *src_matrix)
+static void
+add_vertex_data1(struct xorg_renderer *r,
+ float srcX, float srcY, float dstX, float dstY,
+ float width, float height,
+ struct pipe_texture *src, float *src_matrix)
{
- float s0, t0, s1, t1;
- float pt0[2], pt1[2];
+ float s0, t0, s1, t1, s2, t2, s3, t3;
+ float pt0[2], pt1[2], pt2[2], pt3[2];
pt0[0] = srcX;
pt0[1] = srcY;
pt1[0] = (srcX + width);
- pt1[1] = (srcY + height);
+ pt1[1] = srcY;
+ pt2[0] = (srcX + width);
+ pt2[1] = (srcY + height);
+ pt3[0] = srcX;
+ pt3[1] = (srcY + height);
if (src_matrix) {
map_point(src_matrix, pt0[0], pt0[1], &pt0[0], &pt0[1]);
map_point(src_matrix, pt1[0], pt1[1], &pt1[0], &pt1[1]);
+ map_point(src_matrix, pt2[0], pt2[1], &pt2[0], &pt2[1]);
+ map_point(src_matrix, pt3[0], pt3[1], &pt3[0], &pt3[1]);
}
- s0 = pt0[0] / src->width[0];
- s1 = pt1[0] / src->width[0];
- t0 = pt0[1] / src->height[0];
- t1 = pt1[1] / src->height[0];
+ s0 = pt0[0] / src->width0;
+ s1 = pt1[0] / src->width0;
+ s2 = pt2[0] / src->width0;
+ s3 = pt3[0] / src->width0;
+ t0 = pt0[1] / src->height0;
+ t1 = pt1[1] / src->height0;
+ t2 = pt2[1] / src->height0;
+ t3 = pt3[1] / src->height0;
/* 1st vertex */
- setup_vertex1(r->vertices2[0], dstX, dstY, s0, t0);
+ add_vertex_1tex(r, dstX, dstY, s0, t0);
/* 2nd vertex */
- setup_vertex1(r->vertices2[1], dstX + width, dstY, s1, t0);
+ add_vertex_1tex(r, dstX + width, dstY, s1, t1);
/* 3rd vertex */
- setup_vertex1(r->vertices2[2], dstX + width, dstY + height, s1, t1);
+ add_vertex_1tex(r, dstX + width, dstY + height, s2, t2);
/* 4th vertex */
- setup_vertex1(r->vertices2[3], dstX, dstY + height, s0, t1);
-
- return pipe_user_buffer_create(r->pipe->screen,
- r->vertices2,
- sizeof(r->vertices2));
+ add_vertex_1tex(r, dstX, dstY + height, s3, t3);
}
-static struct pipe_buffer *
-setup_vertex_data_tex(struct xorg_renderer *r,
- float x0, float y0, float x1, float y1,
- float s0, float t0, float s1, float t1,
- float z)
-{
- /* 1st vertex */
- setup_vertex1(r->vertices2[0], x0, y0, s0, t0);
- /* 2nd vertex */
- setup_vertex1(r->vertices2[1], x1, y0, s1, t0);
- /* 3rd vertex */
- setup_vertex1(r->vertices2[2], x1, y1, s1, t1);
- /* 4th vertex */
- setup_vertex1(r->vertices2[3], x0, y1, s0, t1);
-
- return pipe_user_buffer_create(r->pipe->screen,
- r->vertices2,
- sizeof(r->vertices2));
-}
static INLINE void
-setup_vertex2(float vertex[3][4], float x, float y,
- float s0, float t0, float s1, float t1)
+add_vertex_2tex(struct xorg_renderer *r,
+ float x, float y,
+ float s0, float t0, float s1, float t1)
{
- vertex[0][0] = x;
- vertex[0][1] = y;
- vertex[0][2] = 0.f; /*z*/
- vertex[0][3] = 1.f; /*w*/
-
- vertex[1][0] = s0; /*s*/
- vertex[1][1] = t0; /*t*/
- vertex[1][2] = 0.f; /*r*/
- vertex[1][3] = 1.f; /*q*/
-
- vertex[2][0] = s1; /*s*/
- vertex[2][1] = t1; /*t*/
- vertex[2][2] = 0.f; /*r*/
- vertex[2][3] = 1.f; /*q*/
+ float *vertex = r->buffer + r->buffer_size;
+
+ vertex[0] = x;
+ vertex[1] = y;
+ vertex[2] = 0.f; /*z*/
+ vertex[3] = 1.f; /*w*/
+
+ vertex[4] = s0; /*s*/
+ vertex[5] = t0; /*t*/
+ vertex[6] = 0.f; /*r*/
+ vertex[7] = 1.f; /*q*/
+
+ vertex[8] = s1; /*s*/
+ vertex[9] = t1; /*t*/
+ vertex[10] = 0.f; /*r*/
+ vertex[11] = 1.f; /*q*/
+
+ r->buffer_size += 12;
}
-static struct pipe_buffer *
-setup_vertex_data2(struct xorg_renderer *r,
- float srcX, float srcY, float maskX, float maskY,
- float dstX, float dstY, float width, float height,
- struct pipe_texture *src,
- struct pipe_texture *mask,
- float *src_matrix, float *mask_matrix)
+static void
+add_vertex_data2(struct xorg_renderer *r,
+ float srcX, float srcY, float maskX, float maskY,
+ float dstX, float dstY, float width, float height,
+ struct pipe_texture *src,
+ struct pipe_texture *mask,
+ float *src_matrix, float *mask_matrix)
{
float src_s0, src_t0, src_s1, src_t1;
float mask_s0, mask_t0, mask_s1, mask_t1;
@@ -195,33 +249,28 @@ setup_vertex_data2(struct xorg_renderer *r,
map_point(mask_matrix, mpt1[0], mpt1[1], &mpt1[0], &mpt1[1]);
}
- src_s0 = spt0[0] / src->width[0];
- src_t0 = spt0[1] / src->height[0];
- src_s1 = spt1[0] / src->width[0];
- src_t1 = spt1[1] / src->height[0];
+ src_s0 = spt0[0] / src->width0;
+ src_t0 = spt0[1] / src->height0;
+ src_s1 = spt1[0] / src->width0;
+ src_t1 = spt1[1] / src->height0;
- mask_s0 = mpt0[0] / mask->width[0];
- mask_t0 = mpt0[1] / mask->height[0];
- mask_s1 = mpt1[0] / mask->width[0];
- mask_t1 = mpt1[1] / mask->height[0];
+ mask_s0 = mpt0[0] / mask->width0;
+ mask_t0 = mpt0[1] / mask->height0;
+ mask_s1 = mpt1[0] / mask->width0;
+ mask_t1 = mpt1[1] / mask->height0;
/* 1st vertex */
- setup_vertex2(r->vertices3[0], dstX, dstY,
- src_s0, src_t0, mask_s0, mask_t0);
+ add_vertex_2tex(r, dstX, dstY,
+ src_s0, src_t0, mask_s0, mask_t0);
/* 2nd vertex */
- setup_vertex2(r->vertices3[1], dstX + width, dstY,
- src_s1, src_t0, mask_s1, mask_t0);
+ add_vertex_2tex(r, dstX + width, dstY,
+ src_s1, src_t0, mask_s1, mask_t0);
/* 3rd vertex */
- setup_vertex2(r->vertices3[2], dstX + width, dstY + height,
- src_s1, src_t1, mask_s1, mask_t1);
+ add_vertex_2tex(r, dstX + width, dstY + height,
+ src_s1, src_t1, mask_s1, mask_t1);
/* 4th vertex */
- setup_vertex2(r->vertices3[3], dstX, dstY + height,
- src_s0, src_t1, mask_s0, mask_t1);
-
-
- return pipe_user_buffer_create(r->pipe->screen,
- r->vertices3,
- sizeof(r->vertices3));
+ add_vertex_2tex(r, dstX, dstY + height,
+ src_s0, src_t1, mask_s0, mask_t1);
}
static struct pipe_buffer *
@@ -238,40 +287,54 @@ setup_vertex_data_yuv(struct xorg_renderer *r,
spt1[0] = srcX + srcW;
spt1[1] = srcY + srcH;
- s0 = spt0[0] / tex[0]->width[0];
- t0 = spt0[1] / tex[0]->height[0];
- s1 = spt1[0] / tex[0]->width[0];
- t1 = spt1[1] / tex[0]->height[0];
+ s0 = spt0[0] / tex[0]->width0;
+ t0 = spt0[1] / tex[0]->height0;
+ s1 = spt1[0] / tex[0]->width0;
+ t1 = spt1[1] / tex[0]->height0;
/* 1st vertex */
- setup_vertex1(r->vertices2[0], dstX, dstY, s0, t0);
+ add_vertex_1tex(r, dstX, dstY, s0, t0);
/* 2nd vertex */
- setup_vertex1(r->vertices2[1], dstX + dstW, dstY,
- s1, t0);
+ add_vertex_1tex(r, dstX + dstW, dstY,
+ s1, t0);
/* 3rd vertex */
- setup_vertex1(r->vertices2[2], dstX + dstW, dstY + dstH,
- s1, t1);
+ add_vertex_1tex(r, dstX + dstW, dstY + dstH,
+ s1, t1);
/* 4th vertex */
- setup_vertex1(r->vertices2[3], dstX, dstY + dstH,
- s0, t1);
+ add_vertex_1tex(r, dstX, dstY + dstH,
+ s0, t1);
-
- return pipe_user_buffer_create(r->pipe->screen,
- r->vertices2,
- sizeof(r->vertices2));
+ return renderer_buffer_create(r);
}
-static void
-set_viewport(struct xorg_renderer *r, int width, int height,
- enum AxisOrientation orientation)
+/* Set up framebuffer, viewport and vertex shader constant buffer
+ * state for a particular destinaton surface. In all our rendering,
+ * these concepts are linked.
+ */
+void renderer_bind_destination(struct xorg_renderer *r,
+ struct pipe_surface *surface,
+ int width,
+ int height )
{
+
+ struct pipe_framebuffer_state fb;
struct pipe_viewport_state viewport;
- float y_scale = (orientation == Y0_BOTTOM) ? -2.f : 2.f;
+ /* Framebuffer uses actual surface width/height
+ */
+ memset(&fb, 0, sizeof fb);
+ fb.width = surface->width;
+ fb.height = surface->height;
+ fb.nr_cbufs = 1;
+ fb.cbufs[0] = surface;
+ fb.zsbuf = 0;
+
+ /* Viewport just touches the bit we're interested in:
+ */
viewport.scale[0] = width / 2.f;
- viewport.scale[1] = height / y_scale;
+ viewport.scale[1] = height / 2.f;
viewport.scale[2] = 1.0;
viewport.scale[3] = 1.0;
viewport.translate[0] = width / 2.f;
@@ -279,11 +342,28 @@ set_viewport(struct xorg_renderer *r, int width, int height,
viewport.translate[2] = 0.0;
viewport.translate[3] = 0.0;
+ /* Constant buffer set up to match viewport dimensions:
+ */
+ if (r->fb_width != width ||
+ r->fb_height != height)
+ {
+ float vs_consts[8] = {
+ 2.f/width, 2.f/height, 1, 1,
+ -1, -1, 0, 0
+ };
+
+ r->fb_width = width;
+ r->fb_height = height;
+
+ renderer_set_constants(r, PIPE_SHADER_VERTEX,
+ vs_consts, sizeof vs_consts);
+ }
+
+ cso_set_framebuffer(r->cso, &fb);
cso_set_viewport(r->cso, &viewport);
}
-
struct xorg_renderer * renderer_create(struct pipe_context *pipe)
{
struct xorg_renderer *renderer = CALLOC_STRUCT(xorg_renderer);
@@ -320,51 +400,9 @@ void renderer_destroy(struct xorg_renderer *r)
}
}
-void renderer_bind_framebuffer(struct xorg_renderer *r,
- struct exa_pixmap_priv *priv)
-{
- unsigned i;
- struct pipe_framebuffer_state state;
- struct pipe_surface *surface = xorg_gpu_surface(r->pipe->screen, priv);
- memset(&state, 0, sizeof(struct pipe_framebuffer_state));
-
- state.width = priv->tex->width[0];
- state.height = priv->tex->height[0];
-
- state.nr_cbufs = 1;
- state.cbufs[0] = surface;
- for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
- state.cbufs[i] = 0;
-
- /* currently we don't use depth/stencil */
- state.zsbuf = 0;
-
- cso_set_framebuffer(r->cso, &state);
-
- /* we do fire and forget for the framebuffer, this is the forget part */
- pipe_surface_reference(&surface, NULL);
-}
-void renderer_bind_viewport(struct xorg_renderer *r,
- struct exa_pixmap_priv *dst)
-{
- int width = dst->tex->width[0];
- int height = dst->tex->height[0];
-
- /*debug_printf("Bind viewport (%d, %d)\n", width, height);*/
- set_viewport(r, width, height, Y0_TOP);
-}
-void renderer_bind_rasterizer(struct xorg_renderer *r)
-{
- struct pipe_rasterizer_state raster;
-
- /* XXX: move to renderer_init_state? */
- memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
- raster.gl_rasterization_rules = 1;
- cso_set_rasterizer(r->cso, &raster);
-}
void renderer_set_constants(struct xorg_renderer *r,
int shader_type,
@@ -387,181 +425,20 @@ void renderer_set_constants(struct xorg_renderer *r,
r->pipe->set_constant_buffer(r->pipe, shader_type, 0, cbuf);
}
-static void
-setup_vs_constant_buffer(struct xorg_renderer *r,
- int width, int height)
-{
- const int param_bytes = 8 * sizeof(float);
- float vs_consts[8] = {
- 2.f/width, 2.f/height, 1, 1,
- -1, -1, 0, 0
- };
- renderer_set_constants(r, PIPE_SHADER_VERTEX,
- vs_consts, param_bytes);
-}
-static void
-setup_fs_constant_buffer(struct xorg_renderer *r)
-{
- const int param_bytes = 4 * sizeof(float);
- const float fs_consts[8] = {
- 0, 0, 0, 1,
- };
- renderer_set_constants(r, PIPE_SHADER_FRAGMENT,
- fs_consts, param_bytes);
-}
-
-static INLINE void shift_rectx(float coords[4],
- const float *bounds,
- const float shift)
-{
- coords[0] += shift;
- coords[2] -= shift;
- if (bounds) {
- coords[2] = MIN2(coords[2], bounds[2]);
- /* bound x/y + width/height */
- if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) {
- coords[2] = (bounds[0] + bounds[2]) - coords[0];
- }
- }
-}
-
-static INLINE void shift_recty(float coords[4],
- const float *bounds,
- const float shift)
-{
- coords[1] += shift;
- coords[3] -= shift;
- if (bounds) {
- coords[3] = MIN2(coords[3], bounds[3]);
- if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) {
- coords[3] = (bounds[1] + bounds[3]) - coords[1];
- }
- }
-}
-
-static INLINE void bound_rect(float coords[4],
- const float bounds[4],
- float shift[4])
-{
- /* if outside the bounds */
- if (coords[0] > (bounds[0] + bounds[2]) ||
- coords[1] > (bounds[1] + bounds[3]) ||
- (coords[0] + coords[2]) < bounds[0] ||
- (coords[1] + coords[3]) < bounds[1]) {
- coords[0] = 0.f;
- coords[1] = 0.f;
- coords[2] = 0.f;
- coords[3] = 0.f;
- shift[0] = 0.f;
- shift[1] = 0.f;
- return;
- }
-
- /* bound x */
- if (coords[0] < bounds[0]) {
- shift[0] = bounds[0] - coords[0];
- coords[2] -= shift[0];
- coords[0] = bounds[0];
- } else
- shift[0] = 0.f;
-
- /* bound y */
- if (coords[1] < bounds[1]) {
- shift[1] = bounds[1] - coords[1];
- coords[3] -= shift[1];
- coords[1] = bounds[1];
- } else
- shift[1] = 0.f;
-
- shift[2] = bounds[2] - coords[2];
- shift[3] = bounds[3] - coords[3];
- /* bound width/height */
- coords[2] = MIN2(coords[2], bounds[2]);
- coords[3] = MIN2(coords[3], bounds[3]);
-
- /* bound x/y + width/height */
- if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) {
- coords[2] = (bounds[0] + bounds[2]) - coords[0];
- }
- if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) {
- coords[3] = (bounds[1] + bounds[3]) - coords[1];
- }
-
- /* if outside the bounds */
- if ((coords[0] + coords[2]) < bounds[0] ||
- (coords[1] + coords[3]) < bounds[1]) {
- coords[0] = 0.f;
- coords[1] = 0.f;
- coords[2] = 0.f;
- coords[3] = 0.f;
- return;
- }
-}
-
-static INLINE void sync_size(float *src_loc, float *dst_loc)
-{
- src_loc[2] = MIN2(src_loc[2], dst_loc[2]);
- src_loc[3] = MIN2(src_loc[3], dst_loc[3]);
- dst_loc[2] = src_loc[2];
- dst_loc[3] = src_loc[3];
-}
-
-static void renderer_copy_texture(struct xorg_renderer *r,
- struct pipe_texture *src,
- float sx1, float sy1,
- float sx2, float sy2,
- struct pipe_texture *dst,
- float dx1, float dy1,
- float dx2, float dy2)
+void renderer_copy_prepare(struct xorg_renderer *r,
+ struct pipe_surface *dst_surface,
+ struct pipe_texture *src_texture)
{
struct pipe_context *pipe = r->pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_buffer *buf;
- struct pipe_surface *dst_surf = screen->get_tex_surface(
- screen, dst, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
- struct pipe_framebuffer_state fb;
- float s0, t0, s1, t1;
struct xorg_shader shader;
- assert(src->width[0] != 0);
- assert(src->height[0] != 0);
- assert(dst->width[0] != 0);
- assert(dst->height[0] != 0);
-
-#if 1
- s0 = sx1 / src->width[0];
- s1 = sx2 / src->width[0];
- t0 = sy1 / src->height[0];
- t1 = sy2 / src->height[0];
-#else
- s0 = 0;
- s1 = 1;
- t0 = 0;
- t1 = 1;
-#endif
-
-#if 0
- debug_printf("copy texture src=[%f, %f, %f, %f], dst=[%f, %f, %f, %f], tex=[%f, %f, %f, %f]\n",
- sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2,
- s0, t0, s1, t1);
-#endif
-
- assert(screen->is_format_supported(screen, dst_surf->format,
+ assert(screen->is_format_supported(screen, dst_surface->format,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET,
0));
-
- /* save state (restored below) */
- cso_save_blend(r->cso);
- cso_save_samplers(r->cso);
- cso_save_sampler_textures(r->cso);
- cso_save_framebuffer(r->cso);
- cso_save_fragment_shader(r->cso);
- cso_save_vertex_shader(r->cso);
-
- cso_save_viewport(r->cso);
+ (void) screen;
/* set misc state we care about */
@@ -591,12 +468,12 @@ static void renderer_copy_texture(struct xorg_renderer *r,
cso_single_sampler_done(r->cso);
}
- set_viewport(r, dst_surf->width, dst_surf->height, Y0_TOP);
+ renderer_bind_destination(r, dst_surface,
+ dst_surface->width,
+ dst_surface->height);
/* texture */
- cso_set_sampler_textures(r->cso, 1, &src);
-
- renderer_bind_rasterizer(r);
+ cso_set_sampler_textures(r->cso, 1, &src_texture);
/* shaders */
shader = xorg_shaders_get(r->shaders,
@@ -605,51 +482,12 @@ static void renderer_copy_texture(struct xorg_renderer *r,
cso_set_vertex_shader_handle(r->cso, shader.vs);
cso_set_fragment_shader_handle(r->cso, shader.fs);
- /* drawing dest */
- memset(&fb, 0, sizeof(fb));
- fb.width = dst_surf->width;
- fb.height = dst_surf->height;
- fb.nr_cbufs = 1;
- fb.cbufs[0] = dst_surf;
- {
- int i;
- for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
- fb.cbufs[i] = 0;
- }
- cso_set_framebuffer(r->cso, &fb);
- setup_vs_constant_buffer(r, fb.width, fb.height);
- setup_fs_constant_buffer(r);
-
- /* draw quad */
- buf = setup_vertex_data_tex(r,
- dx1, dy1,
- dx2, dy2,
- s0, t0, s1, t1,
- 0.0f);
-
- if (buf) {
- util_draw_vertex_buffer(r->pipe, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
-
- pipe_buffer_reference(&buf, NULL);
- }
-
- /* restore state we changed */
- cso_restore_blend(r->cso);
- cso_restore_samplers(r->cso);
- cso_restore_sampler_textures(r->cso);
- cso_restore_framebuffer(r->cso);
- cso_restore_vertex_shader(r->cso);
- cso_restore_fragment_shader(r->cso);
- cso_restore_viewport(r->cso);
-
- pipe_surface_reference(&dst_surf, NULL);
+ r->buffer_size = 0;
+ r->attrs_per_vertex = 2;
}
-static struct pipe_texture *
-create_sampler_texture(struct xorg_renderer *r,
+struct pipe_texture *
+renderer_clone_texture(struct xorg_renderer *r,
struct pipe_texture *src)
{
enum pipe_format format;
@@ -658,7 +496,9 @@ create_sampler_texture(struct xorg_renderer *r,
struct pipe_texture *pt;
struct pipe_texture templ;
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ if (pipe->is_texture_referenced(pipe, src, 0, 0) &
+ PIPE_REFERENCED_FOR_WRITE)
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
/* the coming in texture should already have that invariance */
debug_assert(screen->is_format_supported(screen, src->format,
@@ -671,10 +511,9 @@ create_sampler_texture(struct xorg_renderer *r,
templ.target = PIPE_TEXTURE_2D;
templ.format = format;
templ.last_level = 0;
- templ.width[0] = src->width[0];
- templ.height[0] = src->height[0];
- templ.depth[0] = 1;
- pf_get_block(format, &templ.block);
+ templ.width0 = src->width0;
+ templ.height0 = src->height0;
+ templ.depth0 = 1;
templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
pt = screen->texture_create(screen, &templ);
@@ -695,13 +534,13 @@ create_sampler_texture(struct xorg_renderer *r,
ps_tex, /* dest */
0, 0, /* destx/y */
ps_read,
- 0, 0, src->width[0], src->height[0]);
+ 0, 0, src->width0, src->height0);
} else {
util_surface_copy(pipe, FALSE,
ps_tex, /* dest */
0, 0, /* destx/y */
ps_read,
- 0, 0, src->width[0], src->height[0]);
+ 0, 0, src->width0, src->height0);
}
pipe_surface_reference(&ps_read, NULL);
pipe_surface_reference(&ps_tex, NULL);
@@ -712,123 +551,113 @@ create_sampler_texture(struct xorg_renderer *r,
void renderer_copy_pixmap(struct xorg_renderer *r,
- struct exa_pixmap_priv *dst_priv, int dx, int dy,
- struct exa_pixmap_priv *src_priv, int sx, int sy,
- int width, int height)
+ int dx, int dy,
+ int sx, int sy,
+ int width, int height,
+ float src_width,
+ float src_height)
{
- float dst_loc[4], src_loc[4];
- float dst_bounds[4], src_bounds[4];
- float src_shift[4], dst_shift[4], shift[4];
- struct pipe_texture *dst = dst_priv->tex;
- struct pipe_texture *src = src_priv->tex;
+ float s0, t0, s1, t1;
+ float x0, y0, x1, y1;
- if (r->pipe->is_texture_referenced(r->pipe, src, 0, 0) &
- PIPE_REFERENCED_FOR_WRITE)
- r->pipe->flush(r->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
-
- dst_loc[0] = dx;
- dst_loc[1] = dy;
- dst_loc[2] = width;
- dst_loc[3] = height;
- dst_bounds[0] = 0.f;
- dst_bounds[1] = 0.f;
- dst_bounds[2] = dst->width[0];
- dst_bounds[3] = dst->height[0];
-
- src_loc[0] = sx;
- src_loc[1] = sy;
- src_loc[2] = width;
- src_loc[3] = height;
- src_bounds[0] = 0.f;
- src_bounds[1] = 0.f;
- src_bounds[2] = src->width[0];
- src_bounds[3] = src->height[0];
-
- bound_rect(src_loc, src_bounds, src_shift);
- bound_rect(dst_loc, dst_bounds, dst_shift);
- shift[0] = src_shift[0] - dst_shift[0];
- shift[1] = src_shift[1] - dst_shift[1];
-
- if (shift[0] < 0)
- shift_rectx(src_loc, src_bounds, -shift[0]);
- else
- shift_rectx(dst_loc, dst_bounds, shift[0]);
-
- if (shift[1] < 0)
- shift_recty(src_loc, src_bounds, -shift[1]);
- else
- shift_recty(dst_loc, dst_bounds, shift[1]);
-
- sync_size(src_loc, dst_loc);
-
- if (src_loc[2] >= 0 && src_loc[3] >= 0 &&
- dst_loc[2] >= 0 && dst_loc[3] >= 0) {
- struct pipe_texture *temp_src = src;
-
- if (src == dst)
- temp_src = create_sampler_texture(r, src);
-
- renderer_copy_texture(r,
- temp_src,
- src_loc[0],
- src_loc[1],
- src_loc[0] + src_loc[2],
- src_loc[1] + src_loc[3],
- dst,
- dst_loc[0],
- dst_loc[1],
- dst_loc[0] + dst_loc[2],
- dst_loc[1] + dst_loc[3]);
-
- if (src == dst)
- pipe_texture_reference(&temp_src, NULL);
- }
+
+ /* XXX: could put the texcoord scaling calculation into the vertex
+ * shader.
+ */
+ s0 = sx / src_width;
+ s1 = (sx + width) / src_width;
+ t0 = sy / src_height;
+ t1 = (sy + height) / src_height;
+
+ x0 = dx;
+ x1 = dx + width;
+ y0 = dy;
+ y1 = dy + height;
+
+ /* draw quad */
+ renderer_draw_conditional(r, 4*8);
+ add_vertex_1tex(r, x0, y0, s0, t0);
+ add_vertex_1tex(r, x1, y0, s1, t0);
+ add_vertex_1tex(r, x1, y1, s1, t1);
+ add_vertex_1tex(r, x0, y1, s0, t1);
}
-void renderer_draw_solid_rect(struct xorg_renderer *r,
- int x0, int y0,
- int x1, int y1,
- float *color)
+
+
+
+void renderer_draw_yuv(struct xorg_renderer *r,
+ int src_x, int src_y, int src_w, int src_h,
+ int dst_x, int dst_y, int dst_w, int dst_h,
+ struct pipe_texture **textures)
{
struct pipe_context *pipe = r->pipe;
struct pipe_buffer *buf = 0;
+ buf = setup_vertex_data_yuv(r,
+ src_x, src_y, src_w, src_h,
+ dst_x, dst_y, dst_w, dst_h,
+ textures);
+
+ if (buf) {
+ const int num_attribs = 2; /*pos + tex coord*/
+
+ util_draw_vertex_buffer(pipe, buf, 0,
+ PIPE_PRIM_QUADS,
+ 4, /* verts */
+ num_attribs); /* attribs/vert */
+
+ pipe_buffer_reference(&buf, NULL);
+ }
+}
+
+void renderer_begin_solid(struct xorg_renderer *r)
+{
+ r->buffer_size = 0;
+ r->attrs_per_vertex = 2;
+}
+
+void renderer_solid(struct xorg_renderer *r,
+ int x0, int y0,
+ int x1, int y1,
+ float *color)
+{
/*
debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
x0, y0, x1, y1, color[0], color[1], color[2], color[3]);*/
+
+ renderer_draw_conditional(r, 4 * 8);
+
/* 1st vertex */
- setup_vertex0(r->vertices2[0], x0, y0, color);
+ add_vertex_color(r, x0, y0, color);
/* 2nd vertex */
- setup_vertex0(r->vertices2[1], x1, y0, color);
+ add_vertex_color(r, x1, y0, color);
/* 3rd vertex */
- setup_vertex0(r->vertices2[2], x1, y1, color);
+ add_vertex_color(r, x1, y1, color);
/* 4th vertex */
- setup_vertex0(r->vertices2[3], x0, y1, color);
-
- buf = pipe_user_buffer_create(pipe->screen,
- r->vertices2,
- sizeof(r->vertices2));
-
+ add_vertex_color(r, x0, y1, color);
+}
- if (buf) {
- util_draw_vertex_buffer(pipe, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
+void renderer_draw_flush(struct xorg_renderer *r)
+{
+ renderer_draw_conditional(r, 0);
+}
- pipe_buffer_reference(&buf, NULL);
- }
+void renderer_begin_textures(struct xorg_renderer *r,
+ struct pipe_texture **textures,
+ int num_textures)
+{
+ r->attrs_per_vertex = 1 + num_textures;
+ r->buffer_size = 0;
}
-void renderer_draw_textures(struct xorg_renderer *r,
- int *pos,
- int width, int height,
- struct pipe_texture **textures,
- int num_textures,
- float *src_matrix, float *mask_matrix)
+void renderer_texture(struct xorg_renderer *r,
+ int *pos,
+ int width, int height,
+ struct pipe_texture **textures,
+ int num_textures,
+ float *src_matrix,
+ float *mask_matrix)
{
- struct pipe_context *pipe = r->pipe;
- struct pipe_buffer *buf = 0;
#if 0
if (src_matrix) {
@@ -845,63 +674,27 @@ void renderer_draw_textures(struct xorg_renderer *r,
}
#endif
- switch(num_textures) {
- case 1:
- buf = setup_vertex_data1(r,
- pos[0], pos[1], /* src */
- pos[4], pos[5], /* dst */
- width, height,
- textures[0], src_matrix);
- break;
+ switch(r->attrs_per_vertex) {
case 2:
- buf = setup_vertex_data2(r,
- pos[0], pos[1], /* src */
- pos[2], pos[3], /* mask */
- pos[4], pos[5], /* dst */
- width, height,
- textures[0], textures[1],
- src_matrix, mask_matrix);
+ renderer_draw_conditional(r, 4 * 8);
+ add_vertex_data1(r,
+ pos[0], pos[1], /* src */
+ pos[4], pos[5], /* dst */
+ width, height,
+ textures[0], src_matrix);
break;
case 3:
+ renderer_draw_conditional(r, 4 * 12);
+ add_vertex_data2(r,
+ pos[0], pos[1], /* src */
+ pos[2], pos[3], /* mask */
+ pos[4], pos[5], /* dst */
+ width, height,
+ textures[0], textures[1],
+ src_matrix, mask_matrix);
+ break;
default:
debug_assert(!"Unsupported number of textures");
break;
}
-
- if (buf) {
- int num_attribs = 1; /*pos*/
- num_attribs += num_textures;
-
- util_draw_vertex_buffer(pipe, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- num_attribs); /* attribs/vert */
-
- pipe_buffer_reference(&buf, NULL);
- }
-}
-
-void renderer_draw_yuv(struct xorg_renderer *r,
- int src_x, int src_y, int src_w, int src_h,
- int dst_x, int dst_y, int dst_w, int dst_h,
- struct pipe_texture **textures)
-{
- struct pipe_context *pipe = r->pipe;
- struct pipe_buffer *buf = 0;
-
- buf = setup_vertex_data_yuv(r,
- src_x, src_y, src_w, src_h,
- dst_x, dst_y, dst_w, dst_h,
- textures);
-
- if (buf) {
- const int num_attribs = 2; /*pos + tex coord*/
-
- util_draw_vertex_buffer(pipe, buf, 0,
- PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- num_attribs); /* attribs/vert */
-
- pipe_buffer_reference(&buf, NULL);
- }
}
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index 34c9ee4541..5272cde2b3 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -7,54 +7,89 @@
struct xorg_shaders;
struct exa_pixmap_priv;
+/* max number of vertices *
+ * max number of attributes per vertex *
+ * max number of components per attribute
+ *
+ * currently the max is 100 quads
+ */
+#define BUF_SIZE (100 * 4 * 3 * 4)
+
struct xorg_renderer {
struct pipe_context *pipe;
struct cso_context *cso;
struct xorg_shaders *shaders;
+ int fb_width;
+ int fb_height;
struct pipe_constant_buffer vs_const_buffer;
struct pipe_constant_buffer fs_const_buffer;
- /* we should combine these three */
- float vertices2[4][2][4];
- float vertices3[4][3][4];
+ float buffer[BUF_SIZE];
+ int buffer_size;
+
+ /* number of attributes per vertex for the current
+ * draw operation */
+ int attrs_per_vertex;
};
struct xorg_renderer *renderer_create(struct pipe_context *pipe);
void renderer_destroy(struct xorg_renderer *renderer);
+void renderer_bind_destination(struct xorg_renderer *r,
+ struct pipe_surface *surface,
+ int width,
+ int height );
+
void renderer_bind_framebuffer(struct xorg_renderer *r,
struct exa_pixmap_priv *priv);
void renderer_bind_viewport(struct xorg_renderer *r,
struct exa_pixmap_priv *dst);
-void renderer_bind_rasterizer(struct xorg_renderer *r);
void renderer_set_constants(struct xorg_renderer *r,
int shader_type,
const float *buffer,
int size);
-void renderer_copy_pixmap(struct xorg_renderer *r,
- struct exa_pixmap_priv *dst_priv, int dx, int dy,
- struct exa_pixmap_priv *src_priv, int sx, int sy,
- int width, int height);
-
-void renderer_draw_solid_rect(struct xorg_renderer *r,
- int x0, int y0,
- int x1, int y1,
- float *color);
-
-void renderer_draw_textures(struct xorg_renderer *r,
- int *pos,
- int width, int height,
- struct pipe_texture **textures,
- int num_textures,
- float *src_matrix,
- float *mask_matrix);
+
void renderer_draw_yuv(struct xorg_renderer *r,
int src_x, int src_y, int src_w, int src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
struct pipe_texture **textures);
+void renderer_begin_solid(struct xorg_renderer *r);
+void renderer_solid(struct xorg_renderer *r,
+ int x0, int y0,
+ int x1, int y1,
+ float *color);
+
+void renderer_begin_textures(struct xorg_renderer *r,
+ struct pipe_texture **textures,
+ int num_textures);
+void renderer_texture(struct xorg_renderer *r,
+ int *pos,
+ int width, int height,
+ struct pipe_texture **textures,
+ int num_textures,
+ float *src_matrix,
+ float *mask_matrix);
+
+void renderer_draw_flush(struct xorg_renderer *r);
+
+struct pipe_texture *
+renderer_clone_texture(struct xorg_renderer *r,
+ struct pipe_texture *src);
+
+void renderer_copy_prepare(struct xorg_renderer *r,
+ struct pipe_surface *dst_surface,
+ struct pipe_texture *src_texture);
+
+void renderer_copy_pixmap(struct xorg_renderer *r,
+ int dx, int dy,
+ int sx, int sy,
+ int width, int height,
+ float src_width,
+ float src_height);
+
#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 6130cf6621..4d5d4780dc 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -51,6 +51,8 @@
#define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
+struct kms_bo;
+struct kms_driver;
struct exa_context;
typedef struct
@@ -61,6 +63,8 @@ typedef struct
ScrnInfoPtr pScrn_2;
} EntRec, *EntPtr;
+#define XORG_NR_FENCES 3
+
typedef struct _modesettingRec
{
/* drm */
@@ -84,8 +88,19 @@ typedef struct _modesettingRec
unsigned int SaveGeneration;
void (*blockHandler)(int, pointer, pointer, pointer);
+ struct pipe_fence_handle *fence[XORG_NR_FENCES];
+
CreateScreenResourcesProcPtr createScreenResources;
+ /* for frontbuffer backing store */
+ Bool (*destroy_front_buffer)(ScrnInfoPtr pScrn);
+ Bool (*create_front_buffer)(ScrnInfoPtr pScrn);
+ Bool (*bind_front_buffer)(ScrnInfoPtr pScrn);
+
+ /* kms */
+ struct kms_driver *kms;
+ struct kms_bo *root_bo;
+
/* gallium */
struct drm_api *api;
struct pipe_screen *screen;
@@ -99,6 +114,13 @@ typedef struct _modesettingRec
Bool noEvict;
Bool debug_fallback;
+ /* winsys hocks */
+ Bool (*winsys_screen_init)(ScrnInfoPtr pScr);
+ Bool (*winsys_screen_close)(ScrnInfoPtr pScr);
+ Bool (*winsys_enter_vt)(ScrnInfoPtr pScr);
+ Bool (*winsys_leave_vt)(ScrnInfoPtr pScr);
+ void *winsys_priv;
+
#ifdef DRM_MODE_FEATURE_DIRTYFB
DamagePtr damage;
#endif
@@ -113,9 +135,6 @@ typedef struct _modesettingRec
struct pipe_texture *
xorg_exa_get_texture(PixmapPtr pPixmap);
-unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride);
-
int
xorg_exa_set_displayed_usage(PixmapPtr pPixmap);
@@ -131,7 +150,7 @@ xorg_exa_create_root_texture(ScrnInfoPtr pScrn,
int depth, int bpp);
void *
-xorg_exa_init(ScrnInfoPtr pScrn);
+xorg_exa_init(ScrnInfoPtr pScrn, Bool accel);
void
xorg_exa_close(ScrnInfoPtr pScrn);
@@ -141,33 +160,34 @@ xorg_exa_close(ScrnInfoPtr pScrn);
* xorg_dri2.c
*/
Bool
-driScreenInit(ScreenPtr pScreen);
+xorg_dri2_init(ScreenPtr pScreen);
void
-driCloseScreen(ScreenPtr pScreen);
+xorg_dri2_close(ScreenPtr pScreen);
/***********************************************************************
* xorg_crtc.c
*/
void
-crtc_init(ScrnInfoPtr pScrn);
+xorg_crtc_init(ScrnInfoPtr pScrn);
void
-crtc_cursor_destroy(xf86CrtcPtr crtc);
+xorg_crtc_cursor_destroy(xf86CrtcPtr crtc);
/***********************************************************************
* xorg_output.c
*/
void
-output_init(ScrnInfoPtr pScrn);
+xorg_output_init(ScrnInfoPtr pScrn);
+
/***********************************************************************
* xorg_xv.c
*/
void
-xorg_init_video(ScreenPtr pScreen);
+xorg_xv_init(ScreenPtr pScreen);
#endif /* _XORG_TRACKER_H_ */
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index 2b935c0f73..6b5a41a372 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -13,6 +13,8 @@
#include "pipe/p_screen.h"
#include "pipe/p_inlines.h"
+#include "util/u_format.h"
+
/*XXX get these from pipe's texture limits */
#define IMAGE_MAX_WIDTH 2048
#define IMAGE_MAX_HEIGHT 2048
@@ -73,10 +75,11 @@ static XF86VideoEncodingRec DummyEncoding[1] = {
}
};
-#define NUM_IMAGES 2
+#define NUM_IMAGES 3
static XF86ImageRec Images[NUM_IMAGES] = {
XVIMAGE_UYVY,
XVIMAGE_YUY2,
+ XVIMAGE_YV12,
};
struct xorg_xv_port_priv {
@@ -166,10 +169,9 @@ create_component_texture(struct pipe_context *pipe,
templ.target = PIPE_TEXTURE_2D;
templ.format = PIPE_FORMAT_L8_UNORM;
templ.last_level = 0;
- templ.width[0] = width;
- templ.height[0] = height;
- templ.depth[0] = 1;
- pf_get_block(PIPE_FORMAT_L8_UNORM, &templ.block);
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
tex = screen->texture_create(screen, &templ);
@@ -182,18 +184,18 @@ check_yuv_textures(struct xorg_xv_port_priv *priv, int width, int height)
{
struct pipe_texture **dst = priv->yuv[priv->current_set];
if (!dst[0] ||
- dst[0]->width[0] != width ||
- dst[0]->height[0] != height) {
+ dst[0]->width0 != width ||
+ dst[0]->height0 != height) {
pipe_texture_reference(&dst[0], NULL);
}
if (!dst[1] ||
- dst[1]->width[0] != width ||
- dst[1]->height[0] != height) {
+ dst[1]->width0 != width ||
+ dst[1]->height0 != height) {
pipe_texture_reference(&dst[1], NULL);
}
if (!dst[2] ||
- dst[2]->width[0] != width ||
- dst[2]->height[0] != height) {
+ dst[2]->width0 != width ||
+ dst[2]->height0 != height) {
pipe_texture_reference(&dst[2], NULL);
}
@@ -212,17 +214,67 @@ check_yuv_textures(struct xorg_xv_port_priv *priv, int width, int height)
return Success;
}
+static int
+query_image_attributes(ScrnInfoPtr pScrn,
+ int id,
+ unsigned short *w, unsigned short *h,
+ int *pitches, int *offsets)
+{
+ int size, tmp;
+
+ if (*w > IMAGE_MAX_WIDTH)
+ *w = IMAGE_MAX_WIDTH;
+ if (*h > IMAGE_MAX_HEIGHT)
+ *h = IMAGE_MAX_HEIGHT;
+
+ *w = (*w + 1) & ~1;
+ if (offsets)
+ offsets[0] = 0;
+
+ switch (id) {
+ case FOURCC_YV12:
+ *h = (*h + 1) & ~1;
+ size = (*w + 3) & ~3;
+ if (pitches) {
+ pitches[0] = size;
+ }
+ size *= *h;
+ if (offsets) {
+ offsets[1] = size;
+ }
+ tmp = ((*w >> 1) + 3) & ~3;
+ if (pitches) {
+ pitches[1] = pitches[2] = tmp;
+ }
+ tmp *= (*h >> 1);
+ size += tmp;
+ if (offsets) {
+ offsets[2] = size;
+ }
+ size += tmp;
+ break;
+ case FOURCC_UYVY:
+ case FOURCC_YUY2:
+ default:
+ size = *w << 1;
+ if (pitches)
+ pitches[0] = size;
+ size *= *h;
+ break;
+ }
+
+ return size;
+}
+
static void
copy_packed_data(ScrnInfoPtr pScrn,
struct xorg_xv_port_priv *port,
int id,
unsigned char *buf,
- int srcPitch,
int left,
int top,
- int w, int h)
+ unsigned short w, unsigned short h)
{
- unsigned char *src;
int i, j;
struct pipe_texture **dst = port->yuv[port->current_set];
struct pipe_transfer *ytrans, *utrans, *vtrans;
@@ -232,8 +284,6 @@ copy_packed_data(ScrnInfoPtr pScrn,
int yidx, uidx, vidx;
int y_array_size = w * h;
- src = buf + (top * srcPitch) + (left << 1);
-
ytrans = screen->get_tex_transfer(screen, dst[0],
0, 0, 0,
PIPE_TRANSFER_WRITE,
@@ -255,15 +305,22 @@ copy_packed_data(ScrnInfoPtr pScrn,
switch (id) {
case FOURCC_YV12: {
- for (i = 0; i < w; ++i) {
- for (j = 0; i < h; ++j) {
- /*XXX use src? */
- y1 = buf[j*w + i];
- u = buf[(j/2) * (w/2) + i/2 + y_array_size];
- v = buf[(j/2) * (w/2) + i/2 + y_array_size + y_array_size/4];
- ymap[yidx++] = y1;
- umap[uidx++] = u;
- vmap[vidx++] = v;
+ int pitches[3], offsets[3];
+ unsigned char *y, *u, *v;
+ query_image_attributes(pScrn, FOURCC_YV12,
+ &w, &h, pitches, offsets);
+
+ y = buf + offsets[0];
+ v = buf + offsets[1];
+ u = buf + offsets[2];
+ for (i = 0; i < h; ++i) {
+ for (j = 0; j < w; ++j) {
+ int yoffset = (w*i+j);
+ int ii = (i|1), jj = (j|1);
+ int vuoffset = (w/2)*(ii/2) + (jj/2);
+ ymap[yidx++] = y[yoffset];
+ umap[uidx++] = u[vuoffset];
+ vmap[vidx++] = v[vuoffset];
}
}
}
@@ -318,21 +375,6 @@ copy_packed_data(ScrnInfoPtr pScrn,
static void
-setup_vs_video_constants(struct xorg_renderer *r, struct exa_pixmap_priv *dst)
-{
- int width = dst->tex->width[0];
- int height = dst->tex->height[0];
- const int param_bytes = 8 * sizeof(float);
- float vs_consts[8] = {
- 2.f/width, 2.f/height, 1, 1,
- -1, -1, 0, 0
- };
-
- renderer_set_constants(r, PIPE_SHADER_VERTEX,
- vs_consts, param_bytes);
-}
-
-static void
setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv)
{
const int param_bytes = 12 * sizeof(float);
@@ -445,6 +487,12 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
Bool hdtv;
int x, y, w, h;
struct exa_pixmap_priv *dst = exaGetPixmapDriverPrivate(pPixmap);
+ struct pipe_surface *dst_surf = xorg_gpu_surface(pPriv->r->pipe->screen, dst);
+
+ if (dst && !dst->tex) {
+ xorg_exa_set_shared_usage(pPixmap);
+ pScrn->pScreen->ModifyPixmapHeader(pPixmap, 0, 0, 0, 0, 0, NULL);
+ }
if (!dst || !dst->tex)
XORG_FALLBACK("Xv destination %s", !dst ? "!dst" : "!dst->tex");
@@ -460,15 +508,17 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
pbox = REGION_RECTS(dstRegion);
nbox = REGION_NUM_RECTS(dstRegion);
- renderer_bind_framebuffer(pPriv->r, dst);
- renderer_bind_viewport(pPriv->r, dst);
+ renderer_bind_destination(pPriv->r, dst_surf,
+ dst_surf->width, dst_surf->height);
+
bind_blend_state(pPriv);
- renderer_bind_rasterizer(pPriv->r);
bind_shaders(pPriv);
bind_samplers(pPriv);
- setup_vs_video_constants(pPriv->r, dst);
setup_fs_video_constants(pPriv->r, hdtv);
+ exaMoveInPixmap(pPixmap);
+ DamageDamageRegion(&pPixmap->drawable, dstRegion);
+
while (nbox--) {
int box_x1 = pbox->x1;
int box_y1 = pbox->y1;
@@ -476,8 +526,8 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
int box_y2 = pbox->y2;
float diff_x = (float)src_w / (float)dst_w;
float diff_y = (float)src_h / (float)dst_h;
- int offset_x = box_x1 - dstX;
- int offset_y = box_y1 - dstY;
+ int offset_x = box_x1 - dstX + pPixmap->screen_x;
+ int offset_y = box_y1 - dstY + pPixmap->screen_y;
int offset_w;
int offset_h;
@@ -495,7 +545,9 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
pbox++;
}
- DamageDamageRegion(&pPixmap->drawable, dstRegion);
+ DamageRegionProcessPending(&pPixmap->drawable);
+
+ pipe_surface_reference(&dst_surf, NULL);
return TRUE;
}
@@ -515,7 +567,6 @@ put_image(ScrnInfoPtr pScrn,
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
PixmapPtr pPixmap;
INT32 x1, x2, y1, y2;
- int srcPitch;
BoxRec dstBox;
int ret;
@@ -534,20 +585,12 @@ put_image(ScrnInfoPtr pScrn,
width, height))
return Success;
- switch (id) {
- case FOURCC_UYVY:
- case FOURCC_YUY2:
- default:
- srcPitch = width << 1;
- break;
- }
-
ret = check_yuv_textures(pPriv, width, height);
if (ret)
return ret;
- copy_packed_data(pScrn, pPriv, id, buf, srcPitch,
+ copy_packed_data(pScrn, pPriv, id, buf,
src_x, src_y, width, height);
if (pDraw->type == DRAWABLE_WINDOW) {
@@ -565,37 +608,6 @@ put_image(ScrnInfoPtr pScrn,
return Success;
}
-static int
-query_image_attributes(ScrnInfoPtr pScrn,
- int id,
- unsigned short *w, unsigned short *h,
- int *pitches, int *offsets)
-{
- int size;
-
- if (*w > IMAGE_MAX_WIDTH)
- *w = IMAGE_MAX_WIDTH;
- if (*h > IMAGE_MAX_HEIGHT)
- *h = IMAGE_MAX_HEIGHT;
-
- *w = (*w + 1) & ~1;
- if (offsets)
- offsets[0] = 0;
-
- switch (id) {
- case FOURCC_UYVY:
- case FOURCC_YUY2:
- default:
- size = *w << 1;
- if (pitches)
- pitches[0] = size;
- size *= *h;
- break;
- }
-
- return size;
-}
-
static struct xorg_xv_port_priv *
port_priv_create(struct xorg_renderer *r)
{
@@ -678,7 +690,7 @@ xorg_setup_textured_adapter(ScreenPtr pScreen)
}
void
-xorg_init_video(ScreenPtr pScreen)
+xorg_xv_init(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
/*modesettingPtr ms = modesettingPTR(pScrn);*/
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
index bf9038f356..0e39a390c6 100644
--- a/src/gallium/state_trackers/xorg/xvmc/surface.c
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -1,8 +1,8 @@
/**************************************************************************
- *
+ *
* Copyright 2009 Younes Manton.
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -10,11 +10,11 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
@@ -22,7 +22,7 @@
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
+ *
**************************************************************************/
#include <assert.h>
@@ -103,10 +103,9 @@ CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, u
/* XXX: Needs to match the drawable's format? */
template.format = PIPE_FORMAT_X8R8G8B8_UNORM;
template.last_level = 0;
- template.width[0] = width;
- template.height[0] = height;
- template.depth[0] = 1;
- pf_get_block(template.format, &template.block);
+ template.width0 = width;
+ template.height0 = height;
+ template.depth0 = 1;
template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
tex = vpipe->screen->texture_create(vpipe->screen, &template);