summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorBen Skeggs <[email protected]>2008-07-11 00:05:53 +1000
committerBen Skeggs <[email protected]>2008-07-11 00:05:53 +1000
commit19171ab1d30f14ac0d39894125a3d53a91ca5b89 (patch)
tree7adb5b8317f9acfe1f4f0ba2e10dd79b228cd57d /src/gallium
parent225863aeb5f2dfe4980ae5887f5623ecb05e9ced (diff)
parent64f92e00c8292113f9a6372959febe903af09db6 (diff)
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos_io.c2
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer.h2
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_dump.c3
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c15
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c38
-rw-r--r--src/gallium/winsys/common/intel_drm/intel_be_device.c33
-rw-r--r--src/gallium/winsys/common/intel_drm/intel_be_device.h13
-rw-r--r--src/gallium/winsys/dri/intel/intel_screen.c22
-rw-r--r--src/gallium/winsys/egl_drm/intel/Makefile2
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_context.c30
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_context.h4
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_device.c (renamed from src/gallium/winsys/egl_drm/intel/intel_screen.c)52
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_device.h (renamed from src/gallium/winsys/egl_drm/intel/intel_screen.h)2
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_egl.c174
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_egl.h13
-rw-r--r--src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c4
-rw-r--r--src/gallium/winsys/egl_xlib/egl_xlib.c1
19 files changed, 319 insertions, 97 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c
index 9140faeea9d..85a75525c8b 100644
--- a/src/gallium/auxiliary/draw/draw_pt.c
+++ b/src/gallium/auxiliary/draw/draw_pt.c
@@ -37,6 +37,8 @@
static unsigned trim( unsigned count, unsigned first, unsigned incr )
{
+ if (count < first)
+ return 0;
return count - (count - first) % incr;
}
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
index 6b928118707..8e834501a4c 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c
@@ -184,7 +184,6 @@ boolean aos_fetch_inputs( struct aos_compilation *cp, boolean linear )
if (!load_input( cp, i, linear ))
return FALSE;
cp->insn_counter++;
- debug_printf("\n");
}
return TRUE;
@@ -316,7 +315,6 @@ boolean aos_emit_outputs( struct aos_compilation *cp )
aos_release_xmm_reg( cp, data.idx );
cp->insn_counter++;
- debug_printf("\n");
}
return TRUE;
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
index 83ea0be74b8..8505d333bda 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h
@@ -221,7 +221,7 @@ pb_check_alignment(size_t requested, size_t provided)
static INLINE boolean
pb_check_usage(unsigned requested, unsigned provided)
{
- return (requested & provided) == provided ? TRUE : FALSE;
+ return (requested & provided) == requested ? TRUE : FALSE;
}
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
index 92aff889259..a395c630cc7 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_dump.c
@@ -573,7 +573,8 @@ tgsi_dump_declaration(
if (decl->Declaration.Semantic) {
TXT( ", " );
ENM( decl->Semantic.SemanticName, TGSI_SEMANTICS_SHORT );
- if (decl->Semantic.SemanticIndex != 0) {
+ if (decl->Semantic.SemanticIndex != 0 ||
+ decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC) {
CHR( '[' );
UID( decl->Semantic.SemanticIndex );
CHR( ']' );
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index 2815e61345c..cf4964b26b3 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -581,6 +581,7 @@ i915_texture_create(struct pipe_screen *screen,
struct i915_screen *i915screen = i915_screen(screen);
struct pipe_winsys *ws = screen->winsys;
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
+ size_t tex_size;
if (!tex)
return NULL;
@@ -600,14 +601,22 @@ i915_texture_create(struct pipe_screen *screen,
goto fail;
}
+ tex_size = tex->stride * tex->total_nblocksy;
+
tex->buffer = ws->buffer_create(ws, 64,
PIPE_BUFFER_USAGE_PIXEL,
- tex->stride *
- tex->total_nblocksy);
+ tex_size);
if (!tex->buffer)
goto fail;
+#if 0
+ void *ptr = ws->buffer_map(ws, tex->buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ memset(ptr, 0x80, tex_size);
+ ws->buffer_unmap(ws, tex->buffer);
+#endif
+
return &tex->base;
fail:
@@ -710,6 +719,8 @@ i915_texture_blanket(struct pipe_screen * screen,
return NULL;
tex->base = *base;
+ tex->base.refcount = 1;
+ tex->base.screen = screen;
tex->stride = stride[0];
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index 24b91fbc794..901c8f83e75 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -154,8 +154,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
/* note: reference counting */
pipe_buffer_reference(ws,
&softpipe->constants[shader].buffer,
- buf->buffer);
- softpipe->constants[shader].size = buf->size;
+ buf ? buf->buffer : NULL);
+ softpipe->constants[shader].size = buf ? buf->size : 0;
softpipe->dirty |= SP_NEW_CONSTANTS;
}
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 4db045cdc3d..f775591352b 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -122,8 +122,10 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
/* Now extract the goodies:
*/
- spt->buffer = surf.buffer;
+ spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);
+ spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);
spt->stride[0] = surf.stride;
+ spt->buffer = surf.buffer;
return spt->buffer != NULL;
}
@@ -162,6 +164,39 @@ softpipe_texture_create(struct pipe_screen *screen,
}
+static struct pipe_texture *
+softpipe_texture_blanket(struct pipe_screen * screen,
+ const struct pipe_texture *base,
+ const unsigned *stride,
+ struct pipe_buffer *buffer)
+{
+ struct softpipe_texture *spt;
+ assert(screen);
+
+ /* Only supports one type */
+ if (base->target != PIPE_TEXTURE_2D ||
+ base->last_level != 0 ||
+ base->depth[0] != 1) {
+ return NULL;
+ }
+
+ spt = CALLOC_STRUCT(softpipe_texture);
+ if (!spt)
+ return NULL;
+
+ spt->base = *base;
+ spt->base.refcount = 1;
+ spt->base.screen = screen;
+ spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);
+ spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);
+ spt->stride[0] = stride[0];
+
+ pipe_buffer_reference(screen->winsys, &spt->buffer, buffer);
+
+ return &spt->base;
+}
+
+
static void
softpipe_texture_release(struct pipe_screen *screen,
struct pipe_texture **pt)
@@ -309,6 +344,7 @@ void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create;
+ screen->texture_blanket = softpipe_texture_blanket;
screen->texture_release = softpipe_texture_release;
screen->get_tex_surface = softpipe_get_tex_surface;
diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.c b/src/gallium/winsys/common/intel_drm/intel_be_device.c
index efb57a394e4..8db03296156 100644
--- a/src/gallium/winsys/common/intel_drm/intel_be_device.c
+++ b/src/gallium/winsys/common/intel_drm/intel_be_device.c
@@ -125,6 +125,37 @@ intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned byte
return &buffer->base;
}
+struct pipe_buffer *
+intel_be_buffer_from_handle(struct intel_be_device *device,
+ const char* name, unsigned handle)
+{
+ struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf));
+ struct pipe_buffer *buffer;
+
+ if (!be_buf)
+ goto err;
+
+ memset(be_buf, 0, sizeof(*be_buf));
+
+ driGenBuffers(device->staticPool, name, 1, &be_buf->driBO, 0, 0, 0);
+ driBOSetReferenced(be_buf->driBO, handle);
+
+ if (0) /** XXX TODO check error */
+ goto err_bo;
+
+ buffer = &be_buf->base;
+ buffer->refcount = 1;
+ buffer->alignment = 0;
+ buffer->usage = 0;
+ buffer->size = driBOSize(be_buf->driBO);
+
+ return buffer;
+err_bo:
+ free(be_buf);
+err:
+ return NULL;
+}
+
/*
* Surface functions.
@@ -157,6 +188,7 @@ intel_i915_surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
assert((size_t)"intel_i915_surface_release is deprecated" & 0);
}
+
/*
* Fence functions
*/
@@ -189,6 +221,7 @@ intel_be_fence_finish( struct pipe_winsys *sws,
return driFenceFinish((struct _DriFenceObject *)fence, flag, 0);
}
+
/*
* Misc functions
*/
diff --git a/src/gallium/winsys/common/intel_drm/intel_be_device.h b/src/gallium/winsys/common/intel_drm/intel_be_device.h
index abf02539171..3f8b3f585c7 100644
--- a/src/gallium/winsys/common/intel_drm/intel_be_device.h
+++ b/src/gallium/winsys/common/intel_drm/intel_be_device.h
@@ -48,14 +48,23 @@ struct intel_be_buffer {
struct _DriBufferObject *driBO;
};
+/**
+ * Create a be buffer from a drm bo handle
+ *
+ * Takes a reference
+ */
+struct pipe_buffer *
+intel_be_buffer_from_handle(struct intel_be_device *device,
+ const char* name, unsigned handle);
+
static INLINE struct intel_be_buffer *
-intel_be_buffer( struct pipe_buffer *buf )
+intel_be_buffer(struct pipe_buffer *buf)
{
return (struct intel_be_buffer *)buf;
}
static INLINE struct _DriBufferObject *
-dri_bo( struct pipe_buffer *buf )
+dri_bo(struct pipe_buffer *buf)
{
return intel_be_buffer(buf)->driBO;
}
diff --git a/src/gallium/winsys/dri/intel/intel_screen.c b/src/gallium/winsys/dri/intel/intel_screen.c
index cfecebdb8c7..f2412217f36 100644
--- a/src/gallium/winsys/dri/intel/intel_screen.c
+++ b/src/gallium/winsys/dri/intel/intel_screen.c
@@ -49,28 +49,22 @@ intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys,
static void
intelCreateSurface(struct intel_screen *intelScreen, struct pipe_winsys *winsys, unsigned handle)
{
- struct intel_be_buffer *be_buf = malloc(sizeof(*be_buf));
struct pipe_screen *screen = intelScreen->base.screen;
struct pipe_texture *texture;
struct pipe_texture templat;
struct pipe_surface *surface;
- struct pipe_buffer *buffer = &be_buf->base;
+ struct pipe_buffer *buffer;
unsigned pitch;
assert(intelScreen->front.cpp == 4);
- /* XXX create a intel_be function for this */
- {
- driGenBuffers(intelScreen->base.staticPool, "front", 1, &intelScreen->front.buffer, 0, 0, 0);
- driBOSetReferenced(intelScreen->front.buffer, handle);
-
- memset(be_buf, 0, sizeof(*be_buf));
- buffer->refcount = 1;
- buffer->alignment = 0;
- buffer->usage = 0;
- buffer->size = driBOSize(intelScreen->front.buffer);
- be_buf->driBO = intelScreen->front.buffer;
- }
+ buffer = intel_be_buffer_from_handle(&intelScreen->base,
+ "front", handle);
+
+ if (!buffer)
+ return;
+
+ intelScreen->front.buffer = dri_bo(buffer);
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
diff --git a/src/gallium/winsys/egl_drm/intel/Makefile b/src/gallium/winsys/egl_drm/intel/Makefile
index 9c7ff065ffb..e67b49f3ada 100644
--- a/src/gallium/winsys/egl_drm/intel/Makefile
+++ b/src/gallium/winsys/egl_drm/intel/Makefile
@@ -12,7 +12,7 @@ PIPE_DRIVERS = \
DRIVER_SOURCES = \
intel_swapbuffers.c \
intel_context.c \
- intel_screen.c \
+ intel_device.c \
intel_egl.c
C_SOURCES = \
diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.c b/src/gallium/winsys/egl_drm/intel/intel_context.c
index 7205fa4483a..927addb834c 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_context.c
+++ b/src/gallium/winsys/egl_drm/intel/intel_context.c
@@ -27,7 +27,7 @@
#include "i915simple/i915_screen.h"
-#include "intel_screen.h"
+#include "intel_device.h"
#include "intel_context.h"
#include "intel_batchbuffer.h"
@@ -147,13 +147,13 @@ int
intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate)
{
struct intel_context *intel = CALLOC_STRUCT(intel_context);
- struct intel_screen *screen = (struct intel_screen *)egl_context->device->priv;
+ struct intel_device *device = (struct intel_device *)egl_context->device->priv;
struct pipe_context *pipe;
struct st_context *st_share = NULL;
egl_context->priv = intel;
- intel->intel_screen = screen;
+ intel->intel_device = device;
intel->egl_context = egl_context;
intel->egl_device = egl_context->device;
@@ -161,23 +161,37 @@ intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes
intel->base.hardware_unlock = intel_unlock_hardware;
intel->base.hardware_locked = intel_locked_hardware;
- intel_be_init_context(&intel->base, &screen->base);
+ intel_be_init_context(&intel->base, &device->base);
#if 0
pipe = intel_create_softpipe(intel, screen->winsys);
#else
- pipe = i915_create_context(screen->pipe, &screen->base.base, &intel->base.base);
+ pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base);
#endif
pipe->priv = intel;
intel->st = st_create_context(pipe, visual, st_share);
- screen->dummy = intel;
+ device->dummy = intel;
return TRUE;
}
+int
+intel_destroy_context(struct egl_drm_context *egl_context)
+{
+ struct intel_context *intel = egl_context->priv;
+
+ if (intel->intel_device->dummy == intel)
+ intel->intel_device->dummy = NULL;
+
+ st_destroy_context(intel->st);
+ intel_be_destroy_context(&intel->base);
+ free(intel);
+ return TRUE;
+}
+
void
intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read)
{
@@ -206,7 +220,7 @@ intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *dra
void
intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front)
{
- struct intel_screen *intelScreen = (struct intel_screen *)draw->device->priv;
+ struct intel_device *device = (struct intel_device *)draw->device->priv;
struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv;
if (draw_fb->front_buffer)
@@ -221,7 +235,7 @@ intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer
draw_fb->front = front;
- driGenBuffers(intelScreen->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0);
+ driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0);
driBOSetReferenced(draw_fb->front_buffer, front->handle);
st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h);
diff --git a/src/gallium/winsys/egl_drm/intel/intel_context.h b/src/gallium/winsys/egl_drm/intel/intel_context.h
index f05a213ff06..dfa4720b081 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_context.h
+++ b/src/gallium/winsys/egl_drm/intel/intel_context.h
@@ -47,7 +47,7 @@ struct intel_context
struct st_context *st;
- struct intel_screen *intel_screen;
+ struct intel_device *intel_device;
/* new egl stuff */
struct egl_drm_device *egl_device;
@@ -64,7 +64,7 @@ struct intel_framebuffer
{
struct st_framebuffer *stfb;
- struct intel_screen *screen;
+ struct intel_device *device;
struct _DriBufferObject *front_buffer;
struct egl_drm_frontbuffer *front;
};
diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.c b/src/gallium/winsys/egl_drm/intel/intel_device.c
index 2818b9676c5..b9649cbec71 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_screen.c
+++ b/src/gallium/winsys/egl_drm/intel/intel_device.c
@@ -32,7 +32,7 @@
#include "i915simple/i915_screen.h"
#include "intel_context.h"
-#include "intel_screen.h"
+#include "intel_device.h"
#include "intel_batchbuffer.h"
#include "intel_egl.h"
@@ -41,24 +41,23 @@ extern const struct dri_extension card_extensions[];
int
-intel_init_driver(struct egl_drm_device *device)
+intel_create_device(struct egl_drm_device *device)
{
- struct intel_screen *intel_screen;
+ struct intel_device *intel_device;
/* Allocate the private area */
- intel_screen = CALLOC_STRUCT(intel_screen);
- if (!intel_screen)
+ intel_device = CALLOC_STRUCT(intel_device);
+ if (!intel_device)
return FALSE;
- device->priv = (void *)intel_screen;
- intel_screen->device = device;
+ device->priv = (void *)intel_device;
+ intel_device->device = device;
- /** TODO JB: ugly hack */
- intel_screen->deviceID = PCI_CHIP_I945_GM;
+ intel_device->deviceID = device->deviceID;
- intel_be_init_device(&intel_screen->base, device->drmFD, PCI_CHIP_I945_GM);
+ intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID);
- intel_screen->pipe = i915_create_screen(&intel_screen->base.base, intel_screen->deviceID);
+ intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID);
/* hack */
driInitExtensions(NULL, card_extensions, GL_FALSE);
@@ -67,6 +66,19 @@ intel_init_driver(struct egl_drm_device *device)
}
int
+intel_destroy_device(struct egl_drm_device *device)
+{
+ struct intel_device *intel_device = (struct intel_device *)device->priv;
+
+ intel_be_destroy_device(&intel_device->base);
+
+ free(intel_device);
+ device->priv = NULL;
+
+ return TRUE;
+}
+
+int
intel_create_drawable(struct egl_drm_drawable *drawable,
const __GLcontextModes * visual)
{
@@ -76,7 +88,7 @@ intel_create_drawable(struct egl_drm_drawable *drawable,
if (!intelfb)
return GL_FALSE;
- intelfb->screen = drawable->device->priv;
+ intelfb->device = drawable->device->priv;
if (visual->redBits == 5)
colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
@@ -108,6 +120,18 @@ intel_create_drawable(struct egl_drm_drawable *drawable,
return GL_FALSE;
}
- drawable->priv = (void *) intelfb;
- return GL_TRUE;
+ drawable->priv = (void *) intelfb;
+ return GL_TRUE;
+}
+
+int
+intel_destroy_drawable(struct egl_drm_drawable *drawable)
+{
+ struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv;
+ drawable->priv = NULL;
+
+ assert(intelfb->stfb);
+ st_unreference_framebuffer(&intelfb->stfb);
+ free(intelfb);
+ return TRUE;
}
diff --git a/src/gallium/winsys/egl_drm/intel/intel_screen.h b/src/gallium/winsys/egl_drm/intel/intel_device.h
index 9b990b48e77..2f9d4f887e5 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_screen.h
+++ b/src/gallium/winsys/egl_drm/intel/intel_device.h
@@ -36,7 +36,7 @@ struct pipe_screen;
struct egl_drm_device;
struct intel_context;
-struct intel_screen
+struct intel_device
{
struct intel_be_device base;
struct pipe_screen *pipe;
diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.c b/src/gallium/winsys/egl_drm/intel/intel_egl.c
index 6865bfa3d4f..55f4d92afb3 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_egl.c
+++ b/src/gallium/winsys/egl_drm/intel/intel_egl.c
@@ -13,6 +13,7 @@
#include "eglmode.h"
#include "eglscreen.h"
#include "eglsurface.h"
+#include "egllog.h"
#include "intel_egl.h"
@@ -23,18 +24,43 @@
#include "state_tracker/st_public.h"
-struct egl_drm_device* egl_drm_create_device(int drmFD);
+#define MAX_SCREENS 16
-struct egl_drm_device*
+static void
+drm_get_device_id(struct egl_drm_device *device)
+{
+ char path[512];
+ FILE *file;
+
+ /* TODO get the real minor */
+ int minor = 0;
+
+ snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor);
+ file = fopen(path, "r");
+ if (!file) {
+ _eglLog(_EGL_WARNING, "Could not retrive device ID\n");
+ return;
+ }
+
+ fgets(path, sizeof( path ), file);
+ sscanf(path, "%x", &device->deviceID);
+ fclose(file);
+}
+
+static struct egl_drm_device*
egl_drm_create_device(int drmFD)
{
struct egl_drm_device *device = malloc(sizeof(*device));
memset(device, 0, sizeof(*device));
device->drmFD = drmFD;
- if (!intel_init_driver(device)) {
- printf("EGL: failed to initalize device\n");
+ device->version = drmGetVersion(device->drmFD);
+
+ drm_get_device_id(device);
+
+ if (!intel_create_device(device)) {
free(device);
+ return NULL;
}
return device;
@@ -42,11 +68,17 @@ egl_drm_create_device(int drmFD)
__GLcontextModes* _gl_context_modes_create( unsigned count, size_t minimum_size );
+struct drm_screen;
+
struct drm_driver
{
_EGLDriver base; /* base class/object */
drmModeResPtr res;
+
+ struct drm_screen *screens[MAX_SCREENS];
+ size_t count_screens;
+
struct egl_drm_device *device;
};
@@ -68,17 +100,26 @@ struct drm_screen
{
_EGLScreen base;
- /* backing buffer and crtc */
+ /* currently only support one connector */
+ drmModeConnectorPtr connector;
+ uint32_t connectorID;
+
+ /* Has this screen been shown */
+ int shown;
+
+ /* Surface that is currently attached to this screen */
+ struct drm_surface *surf;
+
+ /* backing buffer */
drmBO buffer;
+
+ /* framebuffer */
drmModeFBPtr fb;
uint32_t fbID;
- drmModeCrtcPtr crtc;
- /* currently only support one connector */
- drmModeConnectorPtr connector;
- drmModeEncoderPtr encoder;
- uint32_t connectorID;
- uint32_t encoderID;
+ /* crtc and mode used */
+ drmModeCrtcPtr crtc;
+ uint32_t crtcID;
struct drm_mode_modeinfo *mode;
@@ -105,28 +146,17 @@ drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
}
}
-static void
-print_modes(drmModeConnectorPtr connector)
-{
- struct drm_mode_modeinfo *m;
- int i;
-
- for (i = 0; i < connector->count_modes; i++) {
- m = &connector->modes[i];
- printf("dfm %p %i %i %i\n", m, m->hdisplay, m->vdisplay, m->vrefresh);
- }
-}
static EGLBoolean
drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
{
- printf("%s enter\n", __FUNCTION__);
_EGLDisplay *disp = _eglLookupDisplay(dpy);
struct drm_driver *drm_drv = (struct drm_driver *)drv;
struct drm_screen *screen = NULL;
drmModeConnectorPtr connector = NULL;
drmModeResPtr res = NULL;
unsigned count_connectors = 0;
+ int num_screens = 0;
EGLint i;
int fd;
@@ -147,13 +177,13 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
if (res)
count_connectors = res->count_connectors;
- for(i = 0; i < count_connectors; i++) {
+ for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
connector = drmModeGetConnector(fd, res->connectors[i]);
if (!connector)
continue;
- if (connector->connection == DRM_MODE_DISCONNECTED) {
+ if (connector->connection != DRM_MODE_CONNECTED) {
drmModeFreeConnector(connector);
continue;
}
@@ -165,7 +195,9 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
_eglInitScreen(&screen->base);
_eglAddScreen(disp, &screen->base);
drm_add_modes_from_connector(&screen->base, connector);
+ drm_drv->screens[num_screens++] = screen;
}
+ drm_drv->count_screens = num_screens;
/* for now we only have one config */
_EGLConfig *config = calloc(1, sizeof(*config));
@@ -184,17 +216,64 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
drv->Initialized = EGL_TRUE;
*major = 1;
- *minor = 0;
+ *minor = 4;
return EGL_TRUE;
}
+static void
+drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
+{
+ struct drm_driver *drm_drv = (struct drm_driver *)drv;
+
+ intel_bind_frontbuffer(screen->surf->drawable, NULL);
+ screen->surf = NULL;
+
+ drmModeSetCrtc(
+ drm_drv->device->drmFD,
+ drm_drv->res->crtcs[1],
+ 0, // FD
+ 0, 0,
+ NULL, 0, // List of output ids
+ NULL);
+
+ drmModeRmFB(drm_drv->device->drmFD, screen->fbID);
+ drmModeFreeFB(screen->fb);
+ screen->fb = NULL;
+
+ drmBOUnreference(drm_drv->device->drmFD, &screen->buffer);
+
+ screen->shown = 0;
+}
static EGLBoolean
drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
{
- /* TODO: clean up */
- free(drv);
+ struct drm_driver *drm_drv = (struct drm_driver *)drv;
+ struct drm_screen *screen;
+ int i = 0;
+
+ intel_destroy_device(drm_drv->device);
+ drmFreeVersion(drm_drv->device->version);
+
+ for (i = 0; i < drm_drv->count_screens; i++) {
+ screen = drm_drv->screens[i];
+
+ if (screen->shown)
+ drm_takedown_shown_screen(drv, screen);
+
+ drmModeFreeConnector(screen->connector);
+ _eglDestroyScreen(&screen->base);
+ drm_drv->screens[i] = NULL;
+ }
+
+ drmClose(drm_drv->device->drmFD);
+
+ free(drm_drv->device);
+
+ _eglCleanupDisplay(_eglLookupDisplay(dpy));
+ free(drm_drv);
+
return EGL_TRUE;
}
@@ -237,7 +316,9 @@ visual_from_config(_EGLConfig *conf)
visual->doubleBufferMode = 1;
visual->depthBits = 24;
+ visual->haveDepthBuffer = visual->depthBits > 0;
visual->stencilBits = 8;
+ visual->haveStencilBuffer = visual->stencilBits > 0;
return visual;
}
@@ -314,6 +395,8 @@ drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
if (fc->base.IsBound) {
fc->base.DeletePending = EGL_TRUE;
} else {
+ intel_destroy_context(fc->context);
+ free(fc->context);
free(fc);
}
return EGL_TRUE;
@@ -333,6 +416,7 @@ drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, Nat
return EGL_NO_SURFACE;
}
+
static EGLSurface
drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
@@ -480,7 +564,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
size_t size = mode->Height * pitch;
int ret;
- /* TODO if allready shown take down */
+ if (scrn->shown)
+ drm_takedown_shown_screen(drv, scrn);
ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0,
DRM_BO_FLAG_READ |
@@ -490,10 +575,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
DRM_BO_FLAG_NO_EVICT,
DRM_BO_HINT_DONT_FENCE, &scrn->buffer);
- if (ret) {
- printf("failed to create framebuffer (ret %d)\n", ret);
+ if (ret)
return EGL_FALSE;
- }
prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch);
@@ -510,10 +593,8 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
goto err_bo;
scrn->mode = drm_find_mode(scrn->connector, mode);
- if (!scrn->mode) {
- printf("oh noes, no matching mode found\n");
+ if (!scrn->mode)
goto err_fb;
- }
ret = drmModeSetCrtc(
drm_drv->device->drmFD,
@@ -529,8 +610,11 @@ drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
scrn->front.width = mode->Width;
scrn->front.height = mode->Height;
+ scrn->surf = surf;
intel_bind_frontbuffer(surf->drawable, &scrn->front);
+ scrn->shown = 1;
+
return EGL_TRUE;
err_fb:
@@ -549,14 +633,15 @@ drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
if (fs->base.IsBound) {
fs->base.DeletePending = EGL_TRUE;
} else {
+ intel_bind_frontbuffer(fs->drawable, NULL);
+ intel_destroy_drawable(fs->drawable);
+ free(fs->drawable);
free(fs);
}
return EGL_TRUE;
}
-
-
static EGLBoolean
drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
{
@@ -569,12 +654,15 @@ drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface re
if (!b)
return EGL_FALSE;
- /* XXX this is where we'd do the hardware context switch */
- (void) drawSurf;
- (void) readSurf;
- (void) ctx;
+ if (ctx) {
+ if (!drawSurf || !readSurf)
+ return EGL_FALSE;
+
+ intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable);
+ } else {
+ intel_make_current(NULL, NULL, NULL);
+ }
- intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable);
return EGL_TRUE;
}
@@ -602,7 +690,6 @@ _EGLDriver *
_eglMain(_EGLDisplay *dpy, const char *args)
{
struct drm_driver *drm;
- printf("%s enter\n", __FUNCTION__);
drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver));
if (!drm) {
@@ -626,6 +713,7 @@ _eglMain(_EGLDisplay *dpy, const char *args)
drm->base.API.SwapBuffers = drm_swap_buffers;
drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
+ drm->base.Name = "DRM/Gallium";
/* enable supported extensions */
drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
diff --git a/src/gallium/winsys/egl_drm/intel/intel_egl.h b/src/gallium/winsys/egl_drm/intel/intel_egl.h
index 18e84e8eeab..1ee27e0847a 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_egl.h
+++ b/src/gallium/winsys/egl_drm/intel/intel_egl.h
@@ -2,10 +2,15 @@
#ifndef _INTEL_EGL_H_
#define _INTEL_EGL_H_
+#include <xf86drm.h>
+
struct egl_drm_device
{
void *priv;
int drmFD;
+
+ drmVersionPtr version;
+ int deviceID;
};
struct egl_drm_context
@@ -32,9 +37,15 @@ struct egl_drm_frontbuffer
#include "GL/internal/glcore.h"
-int intel_init_driver(struct egl_drm_device *device);
+int intel_create_device(struct egl_drm_device *device);
+int intel_destroy_device(struct egl_drm_device *device);
+
int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate);
+int intel_destroy_context(struct egl_drm_context *context);
+
int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual);
+int intel_destroy_drawable(struct egl_drm_drawable *drawable);
+
void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read);
void intel_swap_buffers(struct egl_drm_drawable *draw);
void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front);
diff --git a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c
index bfff6f935fd..2edcbc79fff 100644
--- a/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c
+++ b/src/gallium/winsys/egl_drm/intel/intel_swapbuffers.c
@@ -25,7 +25,7 @@
*
**************************************************************************/
-#include "intel_screen.h"
+#include "intel_device.h"
#include "intel_context.h"
#include "intel_batchbuffer.h"
#include "intel_reg.h"
@@ -69,7 +69,7 @@ intel_display_surface(struct egl_drm_drawable *draw,
//const int srcWidth = surf->width;
//const int srcHeight = surf->height;
- intel = intel_fb->screen->dummy;
+ intel = intel_fb->device->dummy;
if (!intel) {
printf("No dummy context\n");
return;
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index 83b8bb95b18..708a58b781f 100644
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -535,6 +535,7 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
surf->Base.DeletePending = EGL_TRUE;
}
else {
+ XFreeGC(surf->Dpy, surf->Gc);
st_unreference_framebuffer(&surf->Framebuffer);
free(surf);
}