summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/dri/dri_drawable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/dri/dri_drawable.c')
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c108
1 files changed, 67 insertions, 41 deletions
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 5846390d02..1d91fbb89f 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -53,7 +53,8 @@ dri_copy_to_front(__DRIdrawablePrivate * dPriv,
}
static struct pipe_surface *
-dri_surface_from_handle(struct pipe_screen *screen,
+dri_surface_from_handle(struct drm_api *api,
+ struct pipe_screen *screen,
unsigned handle,
enum pipe_format format,
unsigned width, unsigned height, unsigned pitch)
@@ -63,7 +64,7 @@ dri_surface_from_handle(struct pipe_screen *screen,
struct pipe_texture templat;
struct pipe_buffer *buf = NULL;
- buf = drm_api_hooks.buffer_from_handle(screen, "dri2 buffer", handle);
+ buf = api->buffer_from_handle(api, screen, "dri2 buffer", handle);
if (!buf)
return NULL;
@@ -100,12 +101,14 @@ dri_surface_from_handle(struct pipe_screen *screen,
void
dri_get_buffers(__DRIdrawablePrivate * dPriv)
{
+
struct dri_drawable *drawable = dri_drawable(dPriv);
struct pipe_surface *surface = NULL;
struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
__DRIbuffer *buffers = NULL;
__DRIscreen *dri_screen = drawable->sPriv;
__DRIdrawable *dri_drawable = drawable->dPriv;
+ struct drm_api *api = ((struct dri_screen*)(dri_screen->private))->api;
boolean have_depth = FALSE;
int i, count;
@@ -138,6 +141,18 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
+ if (drawable->old_num == count &&
+ drawable->old_w == dri_drawable->w &&
+ drawable->old_h == dri_drawable->h &&
+ memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0) {
+ return;
+ } else {
+ drawable->old_num = count;
+ drawable->old_w = dri_drawable->w;
+ drawable->old_h = dri_drawable->h;
+ memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
+ }
+
for (i = 0; i < count; i++) {
enum pipe_format format = 0;
int index = 0;
@@ -145,29 +160,28 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
switch (buffers[i].attachment) {
case __DRI_BUFFER_FRONT_LEFT:
index = ST_SURFACE_FRONT_LEFT;
- format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ format = drawable->color_format;
break;
case __DRI_BUFFER_FAKE_FRONT_LEFT:
index = ST_SURFACE_FRONT_LEFT;
- format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ format = drawable->color_format;
break;
case __DRI_BUFFER_BACK_LEFT:
index = ST_SURFACE_BACK_LEFT;
- format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ format = drawable->color_format;
break;
case __DRI_BUFFER_DEPTH:
index = ST_SURFACE_DEPTH;
- format = PIPE_FORMAT_Z24S8_UNORM;
+ format = drawable->depth_format;
break;
case __DRI_BUFFER_STENCIL:
index = ST_SURFACE_DEPTH;
- format = PIPE_FORMAT_Z24S8_UNORM;
+ format = drawable->stencil_format;
break;
case __DRI_BUFFER_ACCUM:
default:
assert(0);
}
- assert(buffers[i].cpp == 4);
if (index == ST_SURFACE_DEPTH) {
if (have_depth)
@@ -176,7 +190,8 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
have_depth = TRUE;
}
- surface = dri_surface_from_handle(screen,
+ surface = dri_surface_from_handle(api,
+ screen,
buffers[i].name,
format,
dri_drawable->w,
@@ -206,10 +221,8 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
__DRIdrawablePrivate * dPriv,
const __GLcontextModes * visual, boolean isPixmap)
{
- enum pipe_format colorFormat, depthFormat, stencilFormat;
struct dri_screen *screen = sPriv->private;
struct dri_drawable *drawable = NULL;
- struct pipe_screen *pscreen = screen->pipe_screen;
int i;
if (isPixmap)
@@ -219,39 +232,52 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
if (drawable == NULL)
goto fail;
- /* XXX: todo: use the pipe_screen queries to figure out which
- * render targets are supportable.
- */
- assert(visual->redBits == 8);
- assert(visual->depthBits == 24 || visual->depthBits == 0);
- assert(visual->stencilBits == 8 || visual->stencilBits == 0);
-
- colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
+ drawable->color_format = (visual->redBits == 8) ?
+ PIPE_FORMAT_A8R8G8B8_UNORM : PIPE_FORMAT_R5G6B5_UNORM;
+
+ debug_printf("Red bits is %d\n", visual->redBits);
+
+ switch(visual->depthBits) {
+ default:
+ case 0:
+ debug_printf("Depth buffer 0.\n");
+ drawable->depth_format = PIPE_FORMAT_NONE;
+ break;
+ case 16:
+ debug_printf("Depth buffer 16.\n");
+ drawable->depth_format = PIPE_FORMAT_Z16_UNORM;
+ break;
+ case 24:
+ if (visual->stencilBits == 0) {
+ debug_printf("Depth buffer 24. Stencil 0.\n");
+ drawable->depth_format = (screen->d_depth_bits_last) ?
+ PIPE_FORMAT_X8Z24_UNORM:
+ PIPE_FORMAT_Z24X8_UNORM;
+ } else {
+ debug_printf("Combined depth stencil 24 / 8.\n");
+ drawable->depth_format = (screen->sd_depth_bits_last) ?
+ PIPE_FORMAT_S8Z24_UNORM:
+ PIPE_FORMAT_Z24S8_UNORM;
+ }
+ break;
+ }
- if (visual->depthBits) {
- if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0))
- depthFormat = PIPE_FORMAT_Z24S8_UNORM;
- else
- depthFormat = PIPE_FORMAT_S8Z24_UNORM;
- } else
- depthFormat = PIPE_FORMAT_NONE;
-
- if (visual->stencilBits) {
- if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0))
- stencilFormat = PIPE_FORMAT_Z24S8_UNORM;
- else
- stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
- } else
- stencilFormat = PIPE_FORMAT_NONE;
+ switch(visual->stencilBits) {
+ default:
+ case 0:
+ drawable->stencil_format = PIPE_FORMAT_NONE;
+ break;
+ case 8:
+ drawable->stencil_format = (screen->sd_depth_bits_last) ?
+ PIPE_FORMAT_S8Z24_UNORM:
+ PIPE_FORMAT_Z24S8_UNORM;
+ break;
+ }
drawable->stfb = st_create_framebuffer(visual,
- colorFormat,
- depthFormat,
- stencilFormat,
+ drawable->color_format,
+ drawable->depth_format,
+ drawable->stencil_format,
dPriv->w,
dPriv->h, (void *)drawable);
if (drawable->stfb == NULL)