diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.c b/src/gallium/auxiliary/gallivm/lp_bld_nir.c index ca56330f9ef0eb54dce65c3c1438f0e7915e5c66..6dbb840cd73f0ddacb53b09c9d239fd5f37279d5 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.c @@ -719,6 +719,7 @@ static LLVMValueRef do_alu_action(struct lp_build_nir_context *bld_base, result = lp_build_sub(flt_bld, src[0], tmp); break; } + case nir_op_fge: case nir_op_fge32: result = fcmp32(bld_base, PIPE_FUNC_GEQUAL, src_bit_size[0], src); break; @@ -1044,6 +1045,26 @@ static LLVMValueRef do_alu_action(struct lp_build_nir_context *bld_base, result = lp_build_shr(uint_bld, src[0], src[1]); break; } + case nir_op_bcsel: { + LLVMTypeRef src1_type = LLVMTypeOf(src[1]); + LLVMTypeRef src2_type = LLVMTypeOf(src[2]); + + if (LLVMGetTypeKind(src1_type) == LLVMPointerTypeKind && + LLVMGetTypeKind(src2_type) != LLVMPointerTypeKind) { + src[2] = LLVMBuildIntToPtr(builder, src[2], src1_type, ""); + } else if (LLVMGetTypeKind(src2_type) == LLVMPointerTypeKind && + LLVMGetTypeKind(src1_type) != LLVMPointerTypeKind) { + src[1] = LLVMBuildIntToPtr(builder, src[1], src2_type, ""); + } + + for (int i = 1; i <= 2; i++) { + LLVMTypeRef type = LLVMTypeOf(src[i]); + if (LLVMGetTypeKind(type) == LLVMPointerTypeKind) + break; + src[i] = LLVMBuildBitCast(builder, src[i], get_int_bld(bld_base, true, src_bit_size[i])->vec_type, ""); + } + return LLVMBuildSelect(builder, src[0], src[1], src[2], ""); + } default: assert(0); break; diff --git a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h index 5a15388291b28b2ff04cf0c40cafbc8e34cad93f..e3bf517b6d595328baabdeefe411a2c4fc1a0157 100644 --- a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h +++ b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h @@ -44,6 +44,7 @@ DRI_CONF_SECTION_DEBUG DRI_CONF_INDIRECT_GL_EXTENSION_OVERRIDE() DRI_CONF_DISABLE_PROTECTED_CONTENT_CHECK(false) DRI_CONF_IGNORE_MAP_UNSYNCHRONIZED(false) + DRI_CONF_FORCE_DIRECT_GLX_CONTEXT(false) DRI_CONF_SECTION_END DRI_CONF_SECTION_MISCELLANEOUS diff --git a/src/glx/create_context.c b/src/glx/create_context.c index 7e1cec98c6470d48396290360d0da720fdecc116..c44d579c95456a633478b5a3f5e723173b6739c5 100644 --- a/src/glx/create_context.c +++ b/src/glx/create_context.c @@ -92,6 +92,15 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, assert(screen == psc->scr); + /* Some application may request an indirect context but we may want to force a direct + * one because Xorg only allows indirect contexts if they were enabled. + */ + if (!direct && + psc->force_direct_context) { + direct = true; + } + + if (direct && psc->vtable->create_context_attribs) { /* GLX drops the error returned by the driver. The expectation is that * an error will also be returned by the server. The server's error diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index fbbfe1f6d57e3a72a512530b244c6dd8ba9c6a2e..4092842cccdfaf1fafeb1b8fdc8283378a6360ee 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -1280,6 +1280,14 @@ dri2CreateScreen(int screen, struct glx_display * priv) &tmp) == 0) __IndirectGlParseExtensionOverride(&psc->base, tmp); + if (psc->config->base.version > 1) { + uint8_t force = false; + if (psc->config->configQueryb(psc->driScreen, "force_direct_glx_context", + &force) == 0) { + psc->base.force_direct_context = force; + } + } + /* DRI2 supports SubBuffer through DRI2CopyRegion, so it's always * available.*/ psp->copySubBuffer = dri2CopySubBuffer; diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c index 3b3918cf6c1e220263e11a7ad6e96bcd7433f167..3c0d60bdf213fbc71a229d84ffcc474c3d90eb74 100644 --- a/src/glx/dri3_glx.c +++ b/src/glx/dri3_glx.c @@ -1014,6 +1014,14 @@ dri3_create_screen(int screen, struct glx_display * priv) &tmp) == 0) __IndirectGlParseExtensionOverride(&psc->base, tmp); + if (psc->config->base.version > 1) { + uint8_t force = false; + if (psc->config->configQueryb(psc->driScreen, "force_direct_glx_context", + &force) == 0) { + psc->base.force_direct_context = force; + } + } + free(driverName); tmp = getenv("LIBGL_SHOW_FPS"); diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 50aa4d892cb33feeeb1111ef44e49e85fb75b007..880f4fbaefa115c89a723d6dc5dac276cbacb293 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -521,6 +521,7 @@ struct glx_screen Display *dpy; int scr; + bool force_direct_context; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) /** diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index ecf94eeb04c604aa735aa616bdd6f5ebb22ed5c7..901de99f9425bf4cd5393da0e52f90738d619b71 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -339,6 +339,14 @@ CreateContext(Display *dpy, int generic_id, struct glx_config *config, if (generic_id == None) return NULL; + /* Some application may request an indirect context but we may want to force a direct + * one because Xorg only allows indirect contexts if they were enabled. + */ + if (!allowDirect && + psc->force_direct_context) { + allowDirect = 1; + } + gc = NULL; #ifdef GLX_USE_APPLEGL gc = applegl_create_context(psc, config, shareList, renderType); diff --git a/src/glx/tests/fake_glx_screen.h b/src/glx/tests/fake_glx_screen.h index 39b250ffc8fadb52c402f6232a54290ae524adb0..02b212ad7ecfefddf8da8de7ec0af472400ac66c 100644 --- a/src/glx/tests/fake_glx_screen.h +++ b/src/glx/tests/fake_glx_screen.h @@ -34,6 +34,7 @@ public: this->scr = num; this->visuals = 0; this->configs = 0; + this->force_direct_context = false; this->display = glx_dpy; this->dpy = (glx_dpy != NULL) ? glx_dpy->dpy : NULL; diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 6bcd3e965f20670dcdf595baf9c946758e07942f..e71613c93cff985f2e4385eddd49000d754a7828 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -168,8 +168,13 @@ copy_vertices(struct gl_context *ctx, assert(save->copied.buffer == NULL); save->copied.buffer = malloc(sizeof(fi_type) * sz * prim->count); - return vbo_copy_vertices(ctx, prim->mode, prim->start, &prim->count, - prim->begin, sz, true, save->copied.buffer, src); + unsigned r = vbo_copy_vertices(ctx, prim->mode, prim->start, &prim->count, + prim->begin, sz, true, save->copied.buffer, src); + if (!r) { + free(save->copied.buffer); + save->copied.buffer = NULL; + } + return r; } diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf index 295e95744a91a8487a074432fd9fcc2123dd10b1..a30abbb9ced336dcd67760f41e6ea36fe072f77c 100644 --- a/src/util/00-mesa-defaults.conf +++ b/src/util/00-mesa-defaults.conf @@ -341,6 +341,10 @@ TODO: document the other workarounds.