summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/dri
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/state_trackers/dri')
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c2
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c108
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.h9
-rw-r--r--src/gallium/state_trackers/dri/dri_extensions.c14
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c91
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h3
6 files changed, 155 insertions, 72 deletions
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index 45eaec4ed3..6c617197ec 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -69,7 +69,7 @@ dri_create_context(const __GLcontextModes * visual,
driParseConfigFiles(&ctx->optionCache,
&screen->optionCache, sPriv->myNum, "dri");
- ctx->pipe = drm_api_hooks.create_context(screen->pipe_screen);
+ ctx->pipe = screen->api->create_context(screen->api, screen->pipe_screen);
if (ctx->pipe == NULL)
goto fail;
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)
diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h
index 78a66624aa..2fbd5f1eb7 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/dri_drawable.h
@@ -46,6 +46,11 @@ struct dri_drawable
unsigned attachments[8];
unsigned num_attachments;
+ __DRIbuffer old[8];
+ unsigned old_num;
+ unsigned old_w;
+ unsigned old_h;
+
/* gallium */
struct st_framebuffer *stfb;
struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX];
@@ -53,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_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c
index 0c59d42d5c..7c04c2b970 100644
--- a/src/gallium/state_trackers/dri/dri_extensions.c
+++ b/src/gallium/state_trackers/dri/dri_extensions.c
@@ -36,9 +36,11 @@
#define need_GL_ARB_multisample
#define need_GL_ARB_occlusion_query
#define need_GL_ARB_point_parameters
+#define need_GL_ARB_shader_objects
#define need_GL_ARB_texture_compression
#define need_GL_ARB_vertex_buffer_object
#define need_GL_ARB_vertex_program
+#define need_GL_ARB_vertex_shader
#define need_GL_ARB_window_pos
#define need_GL_EXT_blend_color
#define need_GL_EXT_blend_equation_separate
@@ -50,16 +52,23 @@
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
#define need_GL_NV_vertex_program
+#define need_GL_VERSION_2_0
+#define need_GL_VERSION_2_1
#include "extension_helper.h"
/**
* Extension strings exported by the driver.
*/
const struct dri_extension card_extensions[] = {
+ {"GL_ARB_fragment_shader", NULL},
{"GL_ARB_multisample", GL_ARB_multisample_functions},
{"GL_ARB_multitexture", NULL},
{"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
+ {"GL_ARB_pixel_buffer_object", NULL},
{"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
+ {"GL_ARB_shading_language_100", GL_VERSION_2_0_functions },
+ {"GL_ARB_shading_language_120", GL_VERSION_2_1_functions },
+ {"GL_ARB_shader_objects", GL_ARB_shader_objects_functions},
{"GL_ARB_texture_border_clamp", NULL},
{"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
{"GL_ARB_texture_cube_map", NULL},
@@ -69,12 +78,11 @@ const struct dri_extension card_extensions[] = {
{"GL_ARB_texture_mirrored_repeat", NULL},
{"GL_ARB_texture_rectangle", NULL},
{"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
- {"GL_ARB_pixel_buffer_object", NULL},
+ {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions},
{"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
{"GL_ARB_window_pos", GL_ARB_window_pos_functions},
{"GL_EXT_blend_color", GL_EXT_blend_color_functions},
- {"GL_EXT_blend_equation_separate",
- GL_EXT_blend_equation_separate_functions},
+ {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
{"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
{"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
{"GL_EXT_blend_subtract", NULL},
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index d3392ee690..5f78b7264a 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_S8Z24_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;
+ } 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 = FALSE;
+ }
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;
}
@@ -170,6 +199,7 @@ dri_init_screen(__DRIscreenPrivate * sPriv)
if (!screen)
return NULL;
+ screen->api = drm_api_create();
screen->sPriv = sPriv;
screen->fd = sPriv->fd;
screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
@@ -187,7 +217,7 @@ dri_init_screen(__DRIscreenPrivate * sPriv)
dri_copy_version(&arg.drm_version, &sPriv->drm_version);
arg.api = NULL;
- screen->pipe_screen = drm_api_hooks.create_screen(screen->fd, &arg.base);
+ screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg.base);
if (!screen->pipe_screen || !arg.api) {
debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__);
@@ -200,7 +230,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;
@@ -230,13 +266,14 @@ dri_init_screen2(__DRIscreenPrivate * sPriv)
if (!screen)
goto fail;
+ screen->api = drm_api_create();
screen->sPriv = sPriv;
screen->fd = sPriv->fd;
sPriv->private = (void *)screen;
sPriv->extensions = dri_screen_extensions;
arg.mode = DRM_CREATE_NORMAL;
- screen->pipe_screen = drm_api_hooks.create_screen(screen->fd, &arg);
+ screen->pipe_screen = screen->api->create_screen(screen->api, screen->fd, &arg);
if (!screen->pipe_screen) {
debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
goto fail;
@@ -248,7 +285,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 100d9e50e0..f3335bb09f 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -60,8 +60,11 @@ struct dri_screen
drmLock *drmLock;
/* gallium */
+ struct drm_api *api;
struct pipe_winsys *pipe_winsys;
struct pipe_screen *pipe_screen;
+ boolean d_depth_bits_last;
+ boolean sd_depth_bits_last;
};
/** cast wrapper */