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/common/dri_context.c22
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.c2
-rw-r--r--src/gallium/state_trackers/dri/common/dri_drawable.h3
-rw-r--r--src/gallium/state_trackers/dri/common/dri_screen.c30
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c95
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2_buffer.h22
-rw-r--r--src/gallium/state_trackers/dri/sw/drisw.c3
7 files changed, 155 insertions, 22 deletions
diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c
index 3d5d24e692..e23c1bcafa 100644
--- a/src/gallium/state_trackers/dri/common/dri_context.c
+++ b/src/gallium/state_trackers/dri/common/dri_context.c
@@ -141,12 +141,18 @@ GLboolean
dri_unbind_context(__DRIcontext * cPriv)
{
/* dri_util.c ensures cPriv is not null */
+ struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
struct dri_context *ctx = dri_context(cPriv);
+ struct dri_drawable *draw = dri_drawable(ctx->dPriv);
+ struct dri_drawable *read = dri_drawable(ctx->rPriv);
+ struct st_api *stapi = screen->st_api;
if (--ctx->bind_count == 0) {
if (ctx->st == ctx->stapi->get_current(ctx->stapi)) {
- ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- ctx->stapi->make_current(ctx->stapi, NULL, NULL, NULL);
+ ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
+ stapi->make_current(stapi, NULL, NULL, NULL);
+ draw->context = NULL;
+ read->context = NULL;
}
}
@@ -165,21 +171,27 @@ dri_make_current(__DRIcontext * cPriv,
struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi);
if (old_st && old_st != ctx->st)
- old_st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ old_st->flush(old_st, ST_FLUSH_FRONT, NULL);
++ctx->bind_count;
+ if (!driDrawPriv && !driReadPriv)
+ return ctx->stapi->make_current(ctx->stapi, ctx->st, NULL, NULL);
+ else if (!driDrawPriv || !driReadPriv)
+ return GL_FALSE;
+
+ draw->context = ctx;
if (ctx->dPriv != driDrawPriv) {
ctx->dPriv = driDrawPriv;
draw->texture_stamp = driDrawPriv->lastStamp - 1;
}
+ read->context = ctx;
if (ctx->rPriv != driReadPriv) {
ctx->rPriv = driReadPriv;
read->texture_stamp = driReadPriv->lastStamp - 1;
}
- ctx->stapi->make_current(ctx->stapi, ctx->st,
- (draw) ? &draw->base : NULL, (read) ? &read->base : NULL);
+ ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base);
return GL_TRUE;
}
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
index 5fd6e7863c..28a33ac7d0 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -132,6 +132,7 @@ dri_create_buffer(__DRIscreen * sPriv,
drawable->base.validate = dri_st_framebuffer_validate;
drawable->base.st_manager_private = (void *) drawable;
+ drawable->screen = screen;
drawable->sPriv = sPriv;
drawable->dPriv = dPriv;
dPriv->driverPrivate = (void *)drawable;
@@ -233,6 +234,7 @@ const __DRItexBufferExtension driTexBufferExtension = {
{ __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
dri_set_tex_buffer,
dri_set_tex_buffer2,
+ NULL,
};
/**
diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h
index 2ff6b71329..7f1aa512ca 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.h
@@ -41,6 +41,9 @@ struct dri_drawable
struct st_framebuffer_iface base;
struct st_visual stvis;
+ struct dri_screen *screen;
+ struct dri_context *context;
+
/* dri */
__DRIdrawable *dPriv;
__DRIscreen *sPriv;
diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c
index f6e22c74b4..5931df993b 100644
--- a/src/gallium/state_trackers/dri/common/dri_screen.c
+++ b/src/gallium/state_trackers/dri/common/dri_screen.c
@@ -81,34 +81,34 @@ dri_fill_in_modes(struct dri_screen *screen,
pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET, 0);
+ PIPE_BIND_RENDER_TARGET);
pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET, 0);
+ PIPE_BIND_RENDER_TARGET);
pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_RENDER_TARGET, 0);
+ PIPE_BIND_RENDER_TARGET);
/* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */
if (dri_with_format(screen->sPriv)) {
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
PIPE_TEXTURE_2D, 0,
- PIPE_BIND_DEPTH_STENCIL, 0);
+ PIPE_BIND_DEPTH_STENCIL);
} else {
pf_z16 = FALSE;
pf_z32 = FALSE;
@@ -142,7 +142,7 @@ dri_fill_in_modes(struct dri_screen *screen,
for (i = 1; i < 5; i++) {
if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM,
PIPE_TEXTURE_2D, i*2,
- PIPE_BIND_RENDER_TARGET, 0)) {
+ PIPE_BIND_RENDER_TARGET)) {
msaa_samples_array[msaa_samples_factor] = i * 2;
msaa_samples_factor++;
}
@@ -161,7 +161,7 @@ dri_fill_in_modes(struct dri_screen *screen,
for (i = 1; i < 5; i++) {
if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM,
PIPE_TEXTURE_2D, i*2,
- PIPE_BIND_RENDER_TARGET, 0)) {
+ PIPE_BIND_RENDER_TARGET)) {
msaa_samples_array[msaa_samples_factor] = i * 2;
msaa_samples_factor++;
}
@@ -183,7 +183,7 @@ dri_fill_in_modes(struct dri_screen *screen,
for (i = 1; i < 5; i++) {
if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM,
PIPE_TEXTURE_2D, i*2,
- PIPE_BIND_RENDER_TARGET, 0)) {
+ PIPE_BIND_RENDER_TARGET)) {
msaa_samples_array[msaa_samples_factor] = i * 2;
msaa_samples_factor++;
}
@@ -235,7 +235,6 @@ dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
return;
stvis->samples = mode->samples;
- stvis->render_buffer = ST_ATTACHMENT_INVALID;
if (mode->redBits == 8) {
if (mode->alphaBits == 8)
@@ -274,8 +273,11 @@ dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
- if (mode->doubleBufferMode)
+ stvis->render_buffer = ST_ATTACHMENT_FRONT_LEFT;
+ if (mode->doubleBufferMode) {
stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
+ stvis->render_buffer = ST_ATTACHMENT_BACK_LEFT;
+ }
if (mode->stereoMode) {
stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
if (mode->doubleBufferMode)
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index a9d05a80fb..30326a23d6 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -38,6 +38,7 @@
#include "dri_screen.h"
#include "dri_context.h"
#include "dri_drawable.h"
+#include "dri2_buffer.h"
/**
* DRI2 flush extension.
@@ -51,7 +52,7 @@ static void
dri2_invalidate_drawable(__DRIdrawable *dPriv)
{
struct dri_drawable *drawable = dri_drawable(dPriv);
- struct dri_context *ctx = dri_context(dPriv->driContextPriv);
+ struct dri_context *ctx = drawable->context;
dri2InvalidateDrawable(dPriv);
drawable->dPriv->lastStamp = *drawable->dPriv->pStamp;
@@ -259,6 +260,92 @@ dri2_drawable_process_buffers(struct dri_drawable *drawable,
memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
}
+static __DRIbuffer *
+dri2_allocate_buffer(__DRIscreen *sPriv,
+ unsigned attachment, unsigned format,
+ int width, int height)
+{
+ struct dri_screen *screen = dri_screen(sPriv);
+ struct dri2_buffer *buffer;
+ struct pipe_resource templ;
+ enum st_attachment_type statt;
+ enum pipe_format pf;
+ unsigned bind = 0;
+ struct winsys_handle whandle;
+
+ switch (attachment) {
+ case __DRI_BUFFER_FRONT_LEFT:
+ case __DRI_BUFFER_FAKE_FRONT_LEFT:
+ statt = ST_ATTACHMENT_FRONT_LEFT;
+ bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ break;
+ case __DRI_BUFFER_BACK_LEFT:
+ statt = ST_ATTACHMENT_BACK_LEFT;
+ bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ break;
+ case __DRI_BUFFER_DEPTH:
+ case __DRI_BUFFER_DEPTH_STENCIL:
+ case __DRI_BUFFER_STENCIL:
+ statt = ST_ATTACHMENT_DEPTH_STENCIL;
+ bind = PIPE_BIND_DEPTH_STENCIL; /* XXX sampler? */
+ break;
+ default:
+ statt = ST_ATTACHMENT_INVALID;
+ break;
+ }
+
+ switch (format) {
+ case 32:
+ pf = PIPE_FORMAT_B8G8R8X8_UNORM;
+ break;
+ case 16:
+ pf = PIPE_FORMAT_Z16_UNORM;
+ break;
+ default:
+ return NULL;
+ }
+
+ buffer = CALLOC_STRUCT(dri2_buffer);
+ if (!buffer)
+ return NULL;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.bind = bind;
+ templ.format = pf;
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.depth0 = 1;
+ templ.array_size = 1;
+
+ buffer->resource =
+ screen->base.screen->resource_create(screen->base.screen, &templ);
+ if (!buffer->resource)
+ return NULL;
+
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_SHARED;
+ screen->base.screen->resource_get_handle(screen->base.screen,
+ buffer->resource, &whandle);
+
+ buffer->base.attachment = attachment;
+ buffer->base.name = whandle.handle;
+ buffer->base.cpp = util_format_get_blocksize(pf);
+ buffer->base.pitch = whandle.stride;
+
+ return &buffer->base;
+}
+
+static void
+dri2_release_buffer(__DRIscreen *sPriv, __DRIbuffer *bPriv)
+{
+ struct dri2_buffer *buffer = dri2_buffer(bPriv);
+
+ pipe_resource_reference(&buffer->resource, NULL);
+ FREE(buffer);
+}
+
/*
* Backend functions for st_framebuffer interface.
*/
@@ -373,7 +460,7 @@ static __DRIimage *
dri2_create_image_from_renderbuffer(__DRIcontext *context,
int renderbuffer, void *loaderPrivate)
{
- struct dri_context *ctx = dri_context(context->driverPrivate);
+ struct dri_context *ctx = dri_context(context);
if (!ctx->st->get_resource_for_egl_image)
return NULL;
@@ -424,6 +511,7 @@ dri2_create_image(__DRIscreen *_screen,
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
+ templ.array_size = 1;
img->texture = screen->base.screen->resource_create(screen->base.screen, &templ);
if (!img->texture) {
@@ -601,6 +689,9 @@ const struct __DriverAPIRec driDriverAPI = {
.SwapBuffers = NULL,
.CopySubBuffer = NULL,
+
+ .AllocateBuffer = dri2_allocate_buffer,
+ .ReleaseBuffer = dri2_release_buffer,
};
/* This is the table of extensions that the loader will dlsym() for. */
diff --git a/src/gallium/state_trackers/dri/drm/dri2_buffer.h b/src/gallium/state_trackers/dri/drm/dri2_buffer.h
new file mode 100644
index 0000000000..1cd8dbbda2
--- /dev/null
+++ b/src/gallium/state_trackers/dri/drm/dri2_buffer.h
@@ -0,0 +1,22 @@
+#ifndef DRI2_BUFFER_H
+#define DRI2_BUFFER_H
+
+#include "dri_wrapper.h"
+
+struct pipe_surface;
+
+struct dri2_buffer
+{
+ __DRIbuffer base;
+ struct pipe_resource *resource;
+};
+
+static INLINE struct dri2_buffer *
+dri2_buffer(__DRIbuffer * driBufferPriv)
+{
+ return (struct dri2_buffer *) driBufferPriv;
+}
+
+#endif
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c
index 30088b0968..ac11f7c47f 100644
--- a/src/gallium/state_trackers/dri/sw/drisw.c
+++ b/src/gallium/state_trackers/dri/sw/drisw.c
@@ -139,7 +139,7 @@ drisw_swap_buffers(__DRIdrawable *dPriv)
ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];
if (ptex) {
- ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);
drisw_copy_to_front(dPriv, ptex);
}
@@ -233,6 +233,7 @@ drisw_allocate_textures(struct dri_drawable *drawable,
*/
static const __DRIextension *drisw_screen_extensions[] = {
+ &driTexBufferExtension.base,
NULL
};