summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_misc.cpp27
-rw-r--r--src/gallium/auxiliary/os/os_thread.h9
-rw-r--r--src/gallium/auxiliary/util/u_vbuf_mgr.c7
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c3
-rw-r--r--src/gallium/drivers/nv50/nv50_shader_state.c8
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c3
-rw-r--r--src/gallium/drivers/nv50/nv50_tgsi_to_nc.c27
-rw-r--r--src/gallium/include/state_tracker/st_api.h24
-rw-r--r--src/gallium/state_trackers/dri/drm/dri2.c9
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_image.c8
-rw-r--r--src/gallium/state_trackers/egl/wayland/native_wayland.c38
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c202
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c16
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h5
-rw-r--r--src/gallium/winsys/r600/drm/r600_bo.c24
-rw-r--r--src/gallium/winsys/r600/drm/r600_priv.h2
-rw-r--r--src/gallium/winsys/r600/drm/radeon_bo.c4
17 files changed, 313 insertions, 103 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
index 843a14a500c..d2d7eccd92f 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -73,6 +73,19 @@ lp_set_target_options(void)
#endif
#endif
+ /*
+ * LLVM revision 123367 switched the default stack alignment to 16 bytes on
+ * Linux (and several other Unices in later revisions), to match recent gcc
+ * versions.
+ *
+ * However our drivers can be loaded by old binary applications, still
+ * maintaining a 4 bytes stack alignment. Therefore we must tell LLVM here
+ * to only assume a 4 bytes alignment for backwards compatibility.
+ */
+#if defined(PIPE_ARCH_X86)
+ llvm::StackAlignment = 4;
+#endif
+
#if defined(DEBUG) || defined(PROFILE)
llvm::NoFramePointerElim = true;
#endif
@@ -93,13 +106,23 @@ lp_set_target_options(void)
* See also:
* - http://llvm.org/bugs/show_bug.cgi?id=3287
* - http://l4.me.uk/post/2009/06/07/llvm-wrinkle-3-configuration-what-configuration/
+ *
+ * The -disable-mmx global option can be specified only once since we
+ * dynamically link against LLVM it will reside in a separate shared object,
+ * which may or not be delete when this shared object is, so we use the
+ * llvm::DisablePrettyStackTrace variable (which we set below and should
+ * reside in the same shared library) to determine whether the -disable-mmx
+ * option has been set or not.
+ *
+ * Thankfully this ugly hack is not necessary on LLVM 2.9 onwards.
*/
- static boolean first = TRUE;
- if (first) {
+ if (!llvm::DisablePrettyStackTrace) {
+ static boolean first = TRUE;
static const char* options[] = {
"prog",
"-disable-mmx"
};
+ assert(first);
llvm::cl::ParseCommandLineOptions(2, const_cast<char**>(options));
first = FALSE;
}
diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h
index 8173d4cc37f..6b4281ad661 100644
--- a/src/gallium/auxiliary/os/os_thread.h
+++ b/src/gallium/auxiliary/os/os_thread.h
@@ -56,7 +56,14 @@ typedef pthread_t pipe_thread;
static INLINE pipe_thread pipe_thread_create( void *(* routine)( void *), void *param )
{
pipe_thread thread;
- if (pthread_create( &thread, NULL, routine, param ))
+ sigset_t saved_set, new_set;
+ int ret;
+
+ sigfillset(&new_set);
+ pthread_sigmask(SIG_SETMASK, &new_set, &saved_set);
+ ret = pthread_create( &thread, NULL, routine, param );
+ pthread_sigmask(SIG_SETMASK, &saved_set, NULL);
+ if (ret)
return 0;
return thread;
}
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c
index a034483ee5c..04149525ea7 100644
--- a/src/gallium/auxiliary/util/u_vbuf_mgr.c
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c
@@ -581,7 +581,12 @@ static void u_vbuf_mgr_compute_max_index(struct u_vbuf_mgr_priv *mgr)
* for that when dividing by stride. */
unused = vb->stride -
(mgr->ve->ve[i].src_offset + mgr->ve->src_format_size[i]);
- assert(unused >= 0);
+
+ /* If src_offset is greater than stride (which means it's a buffer
+ * offset rather than a vertex offset)... */
+ if (unused < 0) {
+ unused = 0;
+ }
/* Compute the maximum index for this vertex element. */
max_index =
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 41d3e14dc0f..4def93d6b84 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -395,6 +395,9 @@ nv50_vertprog_prepare(struct nv50_translation_info *ti)
}
}
+ p->vp.clpd = p->max_out;
+ p->max_out += p->vp.clpd_nr;
+
for (i = 0; i < TGSI_SEMANTIC_COUNT; ++i) {
switch (ti->sysval_map[i]) {
case 2:
diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c
index 82c346cb5ea..5d3f52c38c1 100644
--- a/src/gallium/drivers/nv50/nv50_shader_state.c
+++ b/src/gallium/drivers/nv50/nv50_shader_state.c
@@ -170,6 +170,12 @@ nv50_vertprog_validate(struct nv50_context *nv50)
struct nouveau_channel *chan = nv50->screen->base.channel;
struct nv50_program *vp = nv50->vertprog;
+ if (nv50->clip.nr > vp->vp.clpd_nr) {
+ if (vp->translated)
+ nv50_program_destroy(nv50, vp);
+ vp->vp.clpd_nr = nv50->clip.nr;
+ }
+
if (!nv50_program_validate(nv50, vp))
return;
@@ -369,7 +375,7 @@ nv50_fp_linkage_validate(struct nv50_context *nv50)
m = nv50_vec4_map(map, 0, lin, &dummy, &vp->out[0]);
for (c = 0; c < vp->vp.clpd_nr; ++c)
- map[m++] |= vp->vp.clpd + c;
+ map[m++] = vp->vp.clpd + c;
colors |= m << 8; /* adjust BFC0 id */
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index cdf1a982fcc..11561f5a8e6 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -225,6 +225,9 @@ nv50_validate_clip(struct nv50_context *nv50)
BEGIN_RING(chan, RING_3D(VP_CLIP_DISTANCE_ENABLE), 1);
OUT_RING (chan, (1 << nv50->clip.nr) - 1);
+
+ if (nv50->vertprog && nv50->clip.nr > nv50->vertprog->vp.clpd_nr)
+ nv50->dirty |= NV50_NEW_VERTPROG;
}
static void
diff --git a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
index 25dcaaea14f..15aa40cddd1 100644
--- a/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
+++ b/src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
@@ -1552,6 +1552,8 @@ static void
bld_instruction(struct bld_context *bld,
const struct tgsi_full_instruction *insn)
{
+ struct nv50_program *prog = bld->ti->p;
+ const struct tgsi_full_dst_register *dreg = &insn->Dst[0];
struct nv_value *src0;
struct nv_value *src1;
struct nv_value *src2;
@@ -1990,6 +1992,31 @@ bld_instruction(struct bld_context *bld,
FOR_EACH_DST0_ENABLED_CHANNEL(c, insn)
emit_store(bld, insn, c, dst0[c]);
+
+ if (prog->type == PIPE_SHADER_VERTEX && prog->vp.clpd_nr &&
+ dreg->Register.File == TGSI_FILE_OUTPUT && !dreg->Register.Indirect &&
+ prog->out[dreg->Register.Index].sn == TGSI_SEMANTIC_POSITION) {
+
+ int p;
+ for (p = 0; p < prog->vp.clpd_nr; p++) {
+ struct nv_value *clipd = NULL;
+
+ for (c = 0; c < 4; c++) {
+ temp = new_value(bld->pc, NV_FILE_MEM_C(15), NV_TYPE_F32);
+ temp->reg.id = p * 4 + c;
+ temp = bld_insn_1(bld, NV_OP_LDA, temp);
+
+ clipd = clipd ?
+ bld_insn_3(bld, NV_OP_MAD, dst0[c], temp, clipd) :
+ bld_insn_2(bld, NV_OP_MUL, dst0[c], temp);
+ }
+
+ temp = bld_insn_1(bld, NV_OP_MOV, clipd);
+ temp->reg.file = NV_FILE_OUT;
+ temp->reg.id = bld->ti->p->vp.clpd + p;
+ temp->insn->fixed = 1;
+ }
+ }
}
static INLINE void
diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h
index d4973a10cc7..04fc7c6c5de 100644
--- a/src/gallium/include/state_tracker/st_api.h
+++ b/src/gallium/include/state_tracker/st_api.h
@@ -70,6 +70,15 @@ enum st_profile_type
#define ST_PROFILE_OPENGL_ES2_MASK (1 << ST_PROFILE_OPENGL_ES2)
/**
+ * New context flags for GL 3.0 and beyond.
+ */
+#define ST_CONTEXT_FLAG_CORE_PROFILE (1 << 0)
+#define ST_CONTEXT_FLAG_COMPATIBLE_PROFILE (1 << 1)
+#define ST_CONTEXT_FLAG_FORWARD_COMPATIBLE (1 << 2)
+#define ST_CONTEXT_FLAG_DEBUG (1 << 3)
+#define ST_CONTEXT_FLAG_ROBUST_ACCESS (1 << 4)
+
+/**
* Used in st_context_iface->teximage.
*/
enum st_texture_type {
@@ -207,21 +216,14 @@ struct st_context_attribs
* The profile and minimal version to support.
*
* The valid profiles and versions are rendering API dependent. The latest
- * version satisfying the request should be returned, unless
- * forward_compatiible is true.
+ * version satisfying the request should be returned, unless the
+ * ST_CONTEXT_FLAG_FORWARD_COMPATIBLE bit is set.
*/
enum st_profile_type profile;
int major, minor;
- /**
- * Enable debugging.
- */
- boolean debug;
-
- /**
- * Return the exact version and disallow the use of deprecated features.
- */
- boolean forward_compatible;
+ /** Mask of ST_CONTEXT_FLAG_x bits */
+ unsigned flags;
/**
* The visual of the framebuffers the context will be bound to.
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 30326a23d6c..e471e8e5be2 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -481,6 +481,15 @@ dri2_create_image(__DRIscreen *_screen,
enum pipe_format pf;
tex_usage = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
+ if (use & __DRI_IMAGE_USE_SCANOUT)
+ tex_usage |= PIPE_BIND_SCANOUT;
+ if (use & __DRI_IMAGE_USE_SHARE)
+ tex_usage |= PIPE_BIND_SHARED;
+ if (use & __DRI_IMAGE_USE_CURSOR) {
+ if (width != 64 || height != 64)
+ return NULL;
+ tex_usage |= PIPE_BIND_CURSOR;
+ }
switch (format) {
case __DRI_IMAGE_FORMAT_RGB565:
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
index 210b8c2ee82..ce72e27c3d5 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c
@@ -97,7 +97,8 @@ egl_g3d_create_drm_buffer(_EGLDisplay *dpy, _EGLImage *img,
}
valid_use = EGL_DRM_BUFFER_USE_SCANOUT_MESA |
- EGL_DRM_BUFFER_USE_SHARE_MESA;
+ EGL_DRM_BUFFER_USE_SHARE_MESA |
+ EGL_DRM_BUFFER_USE_CURSOR_MESA;
if (attrs.DRMBufferUseMESA & ~valid_use) {
_eglLog(_EGL_DEBUG, "bad image use bit 0x%04x",
attrs.DRMBufferUseMESA);
@@ -122,6 +123,11 @@ egl_g3d_create_drm_buffer(_EGLDisplay *dpy, _EGLImage *img,
templ.bind |= PIPE_BIND_SCANOUT;
if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_SHARE_MESA)
templ.bind |= PIPE_BIND_SHARED;
+ if (attrs.DRMBufferUseMESA & EGL_DRM_BUFFER_USE_CURSOR_MESA) {
+ if (attrs.Width != 64 || attrs.Height != 64)
+ return NULL;
+ templ.bind |= PIPE_BIND_CURSOR;
+ }
return screen->resource_create(screen, &templ);
}
diff --git a/src/gallium/state_trackers/egl/wayland/native_wayland.c b/src/gallium/state_trackers/egl/wayland/native_wayland.c
index e7ed9d64b7e..0292d5631d6 100644
--- a/src/gallium/state_trackers/egl/wayland/native_wayland.c
+++ b/src/gallium/state_trackers/egl/wayland/native_wayland.c
@@ -61,31 +61,35 @@ wayland_display_get_configs (struct native_display *ndpy, int *num_configs)
{
struct wayland_display *display = wayland_display(ndpy);
const struct native_config **configs;
+ int i;
if (!display->config) {
struct native_config *nconf;
- enum pipe_format format;
- display->config = CALLOC(1, sizeof(*display->config));
+ display->config = CALLOC(2, sizeof(*display->config));
if (!display->config)
return NULL;
- nconf = &display->config->base;
-
- nconf->buffer_mask =
- (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
- (1 << NATIVE_ATTACHMENT_BACK_LEFT);
- format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ for (i = 0; i < 2; ++i) {
+ nconf = &display->config[i].base;
+
+ nconf->buffer_mask =
+ (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
+ (1 << NATIVE_ATTACHMENT_BACK_LEFT);
+
+ nconf->window_bit = TRUE;
+ nconf->pixmap_bit = TRUE;
+ }
- nconf->color_format = format;
- nconf->window_bit = TRUE;
- nconf->pixmap_bit = TRUE;
+ display->config[0].base.color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+ display->config[1].base.color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
}
- configs = MALLOC(sizeof(*configs));
+ configs = MALLOC(2 * sizeof(*configs));
if (configs) {
- configs[0] = &display->config->base;
+ configs[0] = &display->config[0].base;
+ configs[1] = &display->config[1].base;
if (num_configs)
- *num_configs = 1;
+ *num_configs = 2;
}
return configs;
@@ -368,9 +372,9 @@ wayland_create_pixmap_surface(struct native_display *ndpy,
surface->type = WL_PIXMAP_SURFACE;
surface->pix = egl_pixmap;
- if (surface->pix->visual == wl_display_get_rgb_visual(display->dpy))
- surface->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
- else
+ if (nconf)
+ surface->color_format = nconf->color_format;
+ else /* FIXME: derive format from wl_visual */
surface->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
surface->attachment_mask = (1 << NATIVE_ATTACHMENT_FRONT_LEFT);
diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index 351267bae4d..6233fb81781 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_api.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -1018,15 +1018,18 @@ glXChooseVisual( Display *dpy, int screen, int *list )
}
-PUBLIC GLXContext
-glXCreateContext( Display *dpy, XVisualInfo *visinfo,
- GLXContext share_list, Bool direct )
+/**
+ * Helper function used by other glXCreateContext functions.
+ */
+static GLXContext
+create_context(Display *dpy, XMesaVisual xmvis,
+ XMesaContext shareCtx, Bool direct,
+ unsigned major, unsigned minor,
+ unsigned profileMask, unsigned contextFlags)
{
- XMesaVisual xmvis;
GLXContext glxCtx;
- GLXContext shareCtx = share_list;
- if (!dpy || !visinfo)
+ if (!dpy || !xmvis)
return 0;
glxCtx = CALLOC_STRUCT(__GLXcontextRec);
@@ -1038,19 +1041,8 @@ glXCreateContext( Display *dpy, XVisualInfo *visinfo,
XMesaGarbageCollect();
#endif
- xmvis = find_glx_visual( dpy, visinfo );
- if (!xmvis) {
- /* This visual wasn't found with glXChooseVisual() */
- xmvis = create_glx_visual( dpy, visinfo );
- if (!xmvis) {
- /* unusable visual */
- free(glxCtx);
- return NULL;
- }
- }
-
- glxCtx->xmesaContext = XMesaCreateContext(xmvis,
- shareCtx ? shareCtx->xmesaContext : NULL);
+ glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx, major, minor,
+ profileMask, contextFlags);
if (!glxCtx->xmesaContext) {
free(glxCtx);
return NULL;
@@ -1064,6 +1056,29 @@ glXCreateContext( Display *dpy, XVisualInfo *visinfo,
}
+PUBLIC GLXContext
+glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+ GLXContext shareCtx, Bool direct )
+{
+ XMesaVisual xmvis;
+
+ xmvis = find_glx_visual( dpy, visinfo );
+ if (!xmvis) {
+ /* This visual wasn't found with glXChooseVisual() */
+ xmvis = create_glx_visual( dpy, visinfo );
+ if (!xmvis) {
+ /* unusable visual */
+ return NULL;
+ }
+ }
+
+ return create_context(dpy, xmvis,
+ shareCtx ? shareCtx->xmesaContext : NULL,
+ direct,
+ 1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
+}
+
+
/* XXX these may have to be removed due to thread-safety issues. */
static GLXContext MakeCurrent_PrevContext = 0;
static GLXDrawable MakeCurrent_PrevDrawable = 0;
@@ -2084,35 +2099,18 @@ glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute,
PUBLIC GLXContext
glXCreateNewContext( Display *dpy, GLXFBConfig config,
- int renderType, GLXContext shareList, Bool direct )
+ int renderType, GLXContext shareCtx, Bool direct )
{
- GLXContext glxCtx;
- GLXContext shareCtx = shareList;
XMesaVisual xmvis = (XMesaVisual) config;
if (!dpy || !config ||
(renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
return 0;
- glxCtx = CALLOC_STRUCT(__GLXcontextRec);
- if (!glxCtx)
- return 0;
-
- /* deallocate unused windows/buffers */
- XMesaGarbageCollect();
-
- glxCtx->xmesaContext = XMesaCreateContext(xmvis,
- shareCtx ? shareCtx->xmesaContext : NULL);
- if (!glxCtx->xmesaContext) {
- free(glxCtx);
- return NULL;
- }
-
- glxCtx->isDirect = DEFAULT_DIRECT;
- glxCtx->currentDpy = dpy;
- glxCtx->xid = (XID) glxCtx; /* self pointer */
-
- return glxCtx;
+ return create_context(dpy, xmvis,
+ shareCtx ? shareCtx->xmesaContext : NULL,
+ direct,
+ 1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
}
@@ -2315,32 +2313,19 @@ glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
PUBLIC GLXContext
glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
- int render_type, GLXContext share_list,
+ int renderType, GLXContext shareCtx,
Bool direct)
{
XMesaVisual xmvis = (XMesaVisual) config;
- GLXContext glxCtx;
- GLXContext shareCtx = share_list;
- glxCtx = CALLOC_STRUCT(__GLXcontextRec);
- if (!glxCtx)
+ if (!dpy || !config ||
+ (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
return 0;
- /* deallocate unused windows/buffers */
- XMesaGarbageCollect();
-
- glxCtx->xmesaContext = XMesaCreateContext(xmvis,
- shareCtx ? shareCtx->xmesaContext : NULL);
- if (!glxCtx->xmesaContext) {
- free(glxCtx);
- return NULL;
- }
-
- glxCtx->isDirect = DEFAULT_DIRECT;
- glxCtx->currentDpy = dpy;
- glxCtx->xid = (XID) glxCtx; /* self pointer */
-
- return glxCtx;
+ return create_context(dpy, xmvis,
+ shareCtx ? shareCtx->xmesaContext : NULL,
+ direct,
+ 1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
}
@@ -2654,3 +2639,98 @@ glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
if (b)
XMesaReleaseTexImage(dpy, b, buffer);
}
+
+
+
+/*** GLX_ARB_create_context ***/
+
+GLXContext
+glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
+ GLXContext shareCtx, Bool direct,
+ const int *attrib_list)
+{
+ XMesaVisual xmvis = (XMesaVisual) config;
+ int majorVersion = 1, minorVersion = 0;
+ int contextFlags = 0x0;
+ int profileMask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+ int renderType = GLX_RGBA_TYPE;
+ unsigned i;
+ Bool done = False;
+ const int contextFlagsAll = (GLX_CONTEXT_DEBUG_BIT_ARB |
+ GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
+
+ /* parse attrib_list */
+ for (i = 0; !done && attrib_list[i]; i++) {
+ switch (attrib_list[i]) {
+ case GLX_CONTEXT_MAJOR_VERSION_ARB:
+ majorVersion = attrib_list[++i];
+ break;
+ case GLX_CONTEXT_MINOR_VERSION_ARB:
+ minorVersion = attrib_list[++i];
+ break;
+ case GLX_CONTEXT_FLAGS_ARB:
+ contextFlags = attrib_list[++i];
+ break;
+ case GLX_CONTEXT_PROFILE_MASK_ARB:
+ profileMask = attrib_list[++i];
+ break;
+ case GLX_RENDER_TYPE:
+ renderType = attrib_list[++i];
+ break;
+ case 0:
+ /* end of list */
+ done = True;
+ break;
+ default:
+ /* bad attribute */
+ /* XXX generate BadValue X Error */
+ return NULL;
+ }
+ }
+
+ /* check contextFlags */
+ if (contextFlags & ~contextFlagsAll) {
+ return NULL; /* generate BadValue X Error */
+ }
+
+ /* check profileMask */
+ if (profileMask != GLX_CONTEXT_CORE_PROFILE_BIT_ARB &&
+ profileMask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) {
+ return NULL; /* generate BadValue X Error */
+ }
+
+ /* check version (generate BadMatch if bad) */
+ switch (majorVersion) {
+ case 1:
+ if (minorVersion < 0 || minorVersion > 5)
+ return NULL;
+ break;
+ case 2:
+ if (minorVersion < 0 || minorVersion > 1)
+ return NULL;
+ break;
+ case 3:
+ if (minorVersion < 0 || minorVersion > 2)
+ return NULL;
+ break;
+ case 4:
+ if (minorVersion < 0 || minorVersion > 0)
+ return NULL;
+ break;
+ default:
+ return NULL;
+ }
+
+ if ((contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
+ majorVersion < 3)
+ return NULL; /* generate GLXBadProfileARB */
+
+ if (renderType == GLX_COLOR_INDEX_TYPE && majorVersion >= 3)
+ return NULL; /* generate BadMatch */
+
+ return create_context(dpy, xmvis,
+ shareCtx ? shareCtx->xmesaContext : NULL,
+ direct,
+ majorVersion, minorVersion,
+ profileMask, contextFlags);
+}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index 3b35cbc890c..ab4f6753e11 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -853,7 +853,9 @@ xmesa_init( Display *display )
* \return an XMesaContext or NULL if error.
*/
PUBLIC
-XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
+XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list,
+ GLuint major, GLuint minor,
+ GLuint profileMask, GLuint contextFlags)
{
XMesaDisplay xmdpy = xmesa_init_display(v->display);
struct st_context_attribs attribs;
@@ -874,6 +876,18 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
memset(&attribs, 0, sizeof(attribs));
attribs.profile = ST_PROFILE_DEFAULT;
attribs.visual = v->stvis;
+ attribs.major = major;
+ attribs.minor = minor;
+ if (contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
+ attribs.flags |= ST_CONTEXT_FLAG_FORWARD_COMPATIBLE;
+ if (contextFlags & GLX_CONTEXT_DEBUG_BIT_ARB)
+ attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
+ if (contextFlags & GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB)
+ attribs.flags |= ST_CONTEXT_FLAG_ROBUST_ACCESS;
+ if (profileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB)
+ attribs.flags |= ST_CONTEXT_FLAG_CORE_PROFILE;
+ if (profileMask & GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB)
+ attribs.flags |= ST_CONTEXT_FLAG_COMPATIBLE_PROFILE;
c->st = stapi->create_context(stapi, xmdpy->smapi,
&attribs, (share_list) ? share_list->st : NULL);
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index 4ea42dc3755..57571fe2d13 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -140,7 +140,10 @@ extern void XMesaDestroyVisual( XMesaVisual v );
* Return: an XMesaContext or NULL if error.
*/
extern XMesaContext XMesaCreateContext( XMesaVisual v,
- XMesaContext share_list );
+ XMesaContext share_list,
+ GLuint major, GLuint minor,
+ GLuint profileMask,
+ GLuint contextFlags);
/*
diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c
index 100ee7cdb37..63d5f0bf9bb 100644
--- a/src/gallium/winsys/r600/drm/r600_bo.c
+++ b/src/gallium/winsys/r600/drm/r600_bo.c
@@ -38,7 +38,8 @@ struct r600_bo *r600_bo(struct radeon *radeon,
{
struct r600_bo *bo;
struct radeon_bo *rbo;
-
+ uint32_t initial_domain;
+
if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) {
bo = r600_bomgr_bo_create(radeon->bomgr, size, alignment, *radeon->cfence);
if (bo) {
@@ -46,7 +47,24 @@ struct r600_bo *r600_bo(struct radeon *radeon,
}
}
- rbo = radeon_bo(radeon, 0, size, alignment);
+ if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) {
+ initial_domain = RADEON_GEM_DOMAIN_GTT;
+ } else {
+ switch(usage) {
+ case PIPE_USAGE_DYNAMIC:
+ case PIPE_USAGE_STREAM:
+ case PIPE_USAGE_STAGING:
+ initial_domain = RADEON_GEM_DOMAIN_GTT;
+ break;
+ case PIPE_USAGE_DEFAULT:
+ case PIPE_USAGE_STATIC:
+ case PIPE_USAGE_IMMUTABLE:
+ default:
+ initial_domain = RADEON_GEM_DOMAIN_VRAM;
+ break;
+ }
+ }
+ rbo = radeon_bo(radeon, 0, size, alignment, initial_domain);
if (rbo == NULL) {
return NULL;
}
@@ -93,7 +111,7 @@ struct r600_bo *r600_bo_handle(struct radeon *radeon,
struct r600_bo *bo = calloc(1, sizeof(struct r600_bo));
struct radeon_bo *rbo;
- rbo = bo->bo = radeon_bo(radeon, handle, 0, 0);
+ rbo = bo->bo = radeon_bo(radeon, handle, 0, 0, 0);
if (rbo == NULL) {
free(bo);
return NULL;
diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h
index 4f7e60c3413..78b8190d6f5 100644
--- a/src/gallium/winsys/r600/drm/r600_priv.h
+++ b/src/gallium/winsys/r600/drm/r600_priv.h
@@ -132,7 +132,7 @@ unsigned radeon_family_from_device(unsigned device);
* radeon_bo.c
*/
struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
- unsigned size, unsigned alignment);
+ unsigned size, unsigned alignment, unsigned initial_domain);
void radeon_bo_reference(struct radeon *radeon, struct radeon_bo **dst,
struct radeon_bo *src);
int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo);
diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c
index cd817fc240b..45cf6f09671 100644
--- a/src/gallium/winsys/r600/drm/radeon_bo.c
+++ b/src/gallium/winsys/r600/drm/radeon_bo.c
@@ -71,7 +71,7 @@ static void radeon_bo_fixed_unmap(struct radeon *radeon, struct radeon_bo *bo)
}
struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
- unsigned size, unsigned alignment)
+ unsigned size, unsigned alignment, unsigned initial_domain)
{
struct radeon_bo *bo;
int r;
@@ -115,7 +115,7 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
args.size = size;
args.alignment = alignment;
- args.initial_domain = RADEON_GEM_DOMAIN_CPU;
+ args.initial_domain = initial_domain;
args.flags = 0;
args.handle = 0;
r = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_CREATE,