diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_misc.cpp | 27 | ||||
-rw-r--r-- | src/gallium/auxiliary/os/os_thread.h | 9 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_vbuf_mgr.c | 7 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_program.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_shader_state.c | 8 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_state_validate.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/nv50/nv50_tgsi_to_nc.c | 27 | ||||
-rw-r--r-- | src/gallium/include/state_tracker/st_api.h | 24 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri/drm/dri2.c | 9 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/common/egl_g3d_image.c | 8 | ||||
-rw-r--r-- | src/gallium/state_trackers/egl/wayland/native_wayland.c | 38 | ||||
-rw-r--r-- | src/gallium/state_trackers/glx/xlib/glx_api.c | 202 | ||||
-rw-r--r-- | src/gallium/state_trackers/glx/xlib/xm_api.c | 16 | ||||
-rw-r--r-- | src/gallium/state_trackers/glx/xlib/xm_api.h | 5 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_bo.c | 24 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_priv.h | 2 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/radeon_bo.c | 4 |
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, |