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 <thellstrom@vmware.com>
This commit is contained in:
Thomas Hellstrom
2009-06-17 01:08:25 +02:00
parent c9f19571da
commit 0342229289
4 changed files with 111 additions and 60 deletions
+46 -36
View File
@@ -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);
drawable->color_format = (visual->redBits == 8) ?
PIPE_FORMAT_A8R8G8B8_UNORM : PIPE_FORMAT_R5G6B5_UNORM;
colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
debug_printf("Red bits is %d\n", visual->redBits);
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;
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->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)
@@ -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 *
+59 -24
View File
@@ -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;
depth_buffer_factor = 1;
stencil_bits_array[0] = 0; /* no depth or stencil */
stencil_bits_array[1] = 0; /* z24x8 */
stencil_bits_array[2] = 8; /* z24s8 */
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;
}
@@ -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 */