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:
@@ -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 *
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user