summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThomas Hellstrom <[email protected]>2009-06-17 01:08:25 +0200
committerThomas Hellstrom <[email protected]>2009-06-17 03:07:01 +0200
commit0342229289c3bd5ed7bc595db4fc88003430209e (patch)
tree7b9b3add41596fbbe345705a6268d2f187b840eb /src
parentc9f19571da2673a934f6f97aeea92c5414c28925 (diff)
gallium dri st: Probe the driver for supported surface formats.
This is done when constructing the fbconfigs, and the result is saved for window system framebuffer creation. Note: For dri2 the server needs to have an identical format selection logic. Otherwise the dri state-tracker and the xorg driver (state-tracker) will disagree on which format to use for the attachments. Some more work is needed in this area. Signed-off-by: Thomas Hellstrom <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c86
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.h4
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c85
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h2
4 files changed, 114 insertions, 63 deletions
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 09cd3091d22..815055b15b9 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -157,29 +157,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)
@@ -218,10 +217,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)
@@ -231,39 +228,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)
diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h
index 0f654d804a7..2fbd5f1eb7c 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/dri_drawable.h
@@ -58,6 +58,10 @@ struct dri_drawable
unsigned int tail;
unsigned int desired_fences;
unsigned int cur_fences;
+
+ enum pipe_format color_format;
+ enum pipe_format depth_format;
+ enum pipe_format stencil_format;
};
static INLINE struct dri_drawable *
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index d3392ee690b..c36bfe30ff8 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -69,39 +69,65 @@ PUBLIC const char __driConfigOptions[] =
struct dri1_api *__dri1_api_hooks = NULL;
static const __DRIconfig **
-dri_fill_in_modes(__DRIscreenPrivate * psp,
- unsigned pixel_bits, unsigned depth_bits,
- unsigned stencil_bits, GLboolean have_back_buffer)
+dri_fill_in_modes(struct dri_screen *screen,
+ unsigned pixel_bits)
{
__DRIconfig **configs;
- __GLcontextModes *m;
unsigned num_modes;
- uint8_t depth_bits_array[3];
- uint8_t stencil_bits_array[3];
+ uint8_t depth_bits_array[4];
+ uint8_t stencil_bits_array[4];
uint8_t msaa_samples_array[1];
unsigned depth_buffer_factor;
unsigned back_buffer_factor;
unsigned msaa_samples_factor;
GLenum fb_format;
GLenum fb_type;
- int i;
+ struct pipe_screen *p_screen = screen->pipe_screen;
static const GLenum back_buffer_modes[] = {
GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
};
- /* TODO probe the hardware of what is supports */
depth_bits_array[0] = 0;
- depth_bits_array[1] = 24;
- depth_bits_array[2] = 24;
-
- stencil_bits_array[0] = 0; /* no depth or stencil */
- stencil_bits_array[1] = 0; /* z24x8 */
- stencil_bits_array[2] = 8; /* z24s8 */
+ stencil_bits_array[0] = 0;
+ depth_buffer_factor = 1;
+
+ if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) {
+ depth_bits_array[depth_buffer_factor] = 16;
+ stencil_bits_array[depth_buffer_factor++] = 0;
+ }
+ if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) {
+ depth_bits_array[depth_buffer_factor] = 24;
+ stencil_bits_array[depth_buffer_factor++] = 0;
+ screen->d_depth_bits_last = TRUE;
+ } else if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL,
+ 0)) {
+ depth_bits_array[depth_buffer_factor] = 24;
+ stencil_bits_array[depth_buffer_factor++] = 0;
+ screen->d_depth_bits_last = FALSE;
+ }
+ if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) {
+ depth_bits_array[depth_buffer_factor] = 24;
+ stencil_bits_array[depth_buffer_factor++] = 8;
+ screen->sd_depth_bits_last = FALSE;
+ } else if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL,
+ 0)) {
+ depth_bits_array[depth_buffer_factor] = 24;
+ stencil_bits_array[depth_buffer_factor++] = 8;
+ screen->sd_depth_bits_last = TRUE;
+ }
msaa_samples_array[0] = 0;
-
- depth_buffer_factor = 3;
back_buffer_factor = 3;
msaa_samples_factor = 1;
@@ -109,9 +135,19 @@ dri_fill_in_modes(__DRIscreenPrivate * psp,
depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
if (pixel_bits == 16) {
+ if (!p_screen->is_format_supported(p_screen,
+ PIPE_FORMAT_R5G6B5_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+ return NULL;
fb_format = GL_RGB;
fb_type = GL_UNSIGNED_SHORT_5_6_5;
} else {
+ if (!p_screen->is_format_supported(p_screen,
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+ return NULL;
fb_format = GL_BGRA;
fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
}
@@ -126,13 +162,6 @@ dri_fill_in_modes(__DRIscreenPrivate * psp,
return NULL;
}
- for (i = 0; configs[i]; i++) {
- m = &configs[i]->modes;
- if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
- m->visualRating = GLX_SLOW_CONFIG;
- }
- }
-
return (const const __DRIconfig **)configs;
}
@@ -200,7 +229,13 @@ dri_init_screen(__DRIscreenPrivate * sPriv)
driParseOptionInfo(&screen->optionCache,
__driConfigOptions, __driNConfigOptions);
- configs = dri_fill_in_modes(sPriv, sPriv->fbBPP, 24, 8, 1);
+ /**
+ * FIXME: If the driver supports format conversion swapbuffer blits, we might
+ * want to support other color bit depths than the server is currently
+ * using.
+ */
+
+ configs = dri_fill_in_modes(screen, sPriv->fbBPP);
if (!configs)
goto out_no_configs;
@@ -248,7 +283,7 @@ dri_init_screen2(__DRIscreenPrivate * sPriv)
driParseOptionInfo(&screen->optionCache,
__driConfigOptions, __driNConfigOptions);
- return dri_fill_in_modes(sPriv, 4 * 8, 24, 8, 1);
+ return dri_fill_in_modes(screen, 32);
fail:
return NULL;
}
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index 100d9e50e07..090f9fee7c5 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -62,6 +62,8 @@ struct dri_screen
/* gallium */
struct pipe_winsys *pipe_winsys;
struct pipe_screen *pipe_screen;
+ boolean d_depth_bits_last;
+ boolean sd_depth_bits_last;
};
/** cast wrapper */