summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.common.mk27
-rw-r--r--Android.mk7
-rw-r--r--CleanSpec.mk1
-rw-r--r--include/GL/internal/dri_interface.h10
-rw-r--r--src/amd/common/radeon_llvm_init.h51
-rw-r--r--src/compiler/glsl/ast_array_index.cpp2
-rw-r--r--src/egl/Android.mk1
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c1
-rw-r--r--src/egl/drivers/dri2/platform_android.c402
-rw-r--r--src/gallium/Android.common.mk2
-rw-r--r--src/gallium/Android.mk2
-rw-r--r--src/gallium/auxiliary/Android.mk2
-rw-r--r--src/gallium/auxiliary/os/os_misc.c12
-rw-r--r--src/gallium/auxiliary/pipe-loader/pipe_loader.h3
-rw-r--r--src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c9
-rw-r--r--src/gallium/auxiliary/util/u_debug.c2
-rw-r--r--src/gallium/drivers/llvmpipe/Android.mk37
-rw-r--r--src/gallium/drivers/nouveau/nouveau_buffer.c33
-rw-r--r--src/gallium/drivers/nouveau/nouveau_fence.c18
-rw-r--r--src/gallium/drivers/nouveau/nouveau_fence.h5
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c12
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h3
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_clear.c22
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_context.c6
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_draw.c20
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_fragprog.c4
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_miptree.c13
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_query.c9
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_vbo.c5
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_compute.c4
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_context.c11
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_context.h5
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_miptree.c7
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_query.c14
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_query_hw.c25
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c8
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_surface.c43
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_transfer.c6
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_vbo.c5
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_compute.c6
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_context.c15
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_context.h5
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_query.c14
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c21
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c8
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_screen.c2
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_surface.c49
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c56
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c4
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nve4_compute.c4
-rw-r--r--src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c9
-rw-r--r--src/gallium/drivers/svga/svga_format.c6
-rw-r--r--src/gallium/include/state_tracker/drm_driver.h10
-rw-r--r--src/gallium/state_trackers/dri/dri2.c14
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c2
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c2
-rw-r--r--src/gallium/state_trackers/dri/drisw.c55
-rw-r--r--src/gallium/targets/dri/Android.mk23
-rw-r--r--src/gallium/targets/dri/dri.sym1
-rw-r--r--src/gallium/winsys/sw/dri/Android.mk2
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.c64
-rw-r--r--src/gallium/winsys/virgl/drm/virgl_drm_winsys.c2
-rw-r--r--src/intel/Android.genxml.mk45
-rw-r--r--src/mapi/Android.mk3
-rw-r--r--src/mesa/Android.gen.mk27
-rw-r--r--src/mesa/Android.libmesa_dricore.mk20
-rw-r--r--src/mesa/Android.libmesa_sse41.mk5
-rw-r--r--src/mesa/Android.libmesa_st_mesa.mk22
-rw-r--r--src/mesa/Android.mesa_gen_matypes.mk7
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c4
-rw-r--r--src/mesa/drivers/dri/common/dri_util.h2
-rw-r--r--src/mesa/drivers/dri/i915/i830_texstate.c1
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.c1
-rw-r--r--src/mesa/drivers/dri/i915/i915_fragprog.c1
-rw-r--r--src/mesa/drivers/dri/i915/i915_state.c1
-rw-r--r--src/mesa/drivers/dri/i915/i915_tex_layout.c2
-rw-r--r--src/mesa/drivers/dri/i915/i915_texstate.c3
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c1
-rw-r--r--src/mesa/drivers/dri/i915/intel_extensions.c1
-rw-r--r--src/mesa/drivers/dri/i965/Android.mk5
-rw-r--r--src/mesa/drivers/dri/i965/intel_tex_image.c2
-rw-r--r--src/mesa/main/errors.c8
-rw-r--r--src/mesa/main/extensions_table.h3
83 files changed, 1222 insertions, 165 deletions
diff --git a/Android.common.mk b/Android.common.mk
index 9f64c220f8..ebd76f8cfb 100644
--- a/Android.common.mk
+++ b/Android.common.mk
@@ -43,6 +43,7 @@ LOCAL_CFLAGS += \
-DANDROID_VERSION=0x0$(MESA_ANDROID_MAJOR_VERSION)0$(MESA_ANDROID_MINOR_VERSION)
LOCAL_CFLAGS += \
+ -D__STDC_CONSTANT_MACROS \
-D__STDC_LIMIT_MACROS \
-DHAVE___BUILTIN_EXPECT \
-DHAVE___BUILTIN_FFS \
@@ -59,6 +60,7 @@ LOCAL_CFLAGS += \
-DHAVE___BUILTIN_UNREACHABLE \
-DHAVE_PTHREAD=1 \
-DHAVE_DLOPEN \
+ -DTEXTURE_FLOAT_ENABLED \
-fvisibility=hidden \
-Wno-sign-compare
@@ -66,17 +68,32 @@ LOCAL_CFLAGS += \
LOCAL_CONLYFLAGS += \
-std=c99
+x86_flags := \
+ -DUSE_SSE41 \
+
+x86_64_flags := \
+ -DUSE_SSE41 \
+
ifeq ($(strip $(MESA_ENABLE_ASM)),true)
-ifeq ($(TARGET_ARCH),x86)
-LOCAL_CFLAGS += \
+x86_flags += \
-DUSE_X86_ASM \
+ -DUSE_MMX_ASM \
+ -DUSE_3DNOW_ASM \
+ -DUSE_SSE_ASM \
+
+x86_64_flags += \
+ -DUSE_X86_64_ASM \
endif
-endif
+
+LOCAL_ASFLAGS_x86 += $(x86_flags)
+LOCAL_ASFLAGS_x86_64 += $(x86_64_flags)
+LOCAL_CFLAGS_x86 += $(x86_flags)
+LOCAL_CFLAGS_x86_64 += $(x86_64_flags)
ifeq ($(MESA_ENABLE_LLVM),true)
LOCAL_CFLAGS += \
- -DHAVE_LLVM=0x0305 -DMESA_LLVM_VERSION_PATCH=2 \
+ -DHAVE_LLVM=0x030$(if $(filter 5,$(MESA_ANDROID_MAJOR_VERSION)),5,$(if $(filter 6,$(MESA_ANDROID_MAJOR_VERSION)),7,8)) -DMESA_LLVM_VERSION_PATCH=0 \
-D__STDC_CONSTANT_MACROS \
-D__STDC_FORMAT_MACROS \
-D__STDC_LIMIT_MACROS
@@ -91,7 +108,7 @@ endif
endif
LOCAL_CPPFLAGS += \
- $(if $(filter true,$(MESA_LOLLIPOP_BUILD)),-D_USING_LIBCXX) \
+ $(if $(filter true,$(MESA_LOLLIPOP_BUILD)),-std=c++11) \
-Wno-error=non-virtual-dtor \
-Wno-non-virtual-dtor
diff --git a/Android.mk b/Android.mk
index fb29105a60..e97307d275 100644
--- a/Android.mk
+++ b/Android.mk
@@ -63,12 +63,7 @@ $(warning invalid GPU drivers: $(invalid_drivers))
MESA_GPU_DRIVERS := $(filter-out $(invalid_drivers), $(MESA_GPU_DRIVERS))
endif
-# host and target must be the same arch to generate matypes.h
-ifeq ($(TARGET_ARCH),$(HOST_ARCH))
-MESA_ENABLE_ASM := true
-else
MESA_ENABLE_ASM := false
-endif
ifneq ($(filter $(classic_drivers), $(MESA_GPU_DRIVERS)),)
MESA_BUILD_CLASSIC := true
@@ -82,7 +77,7 @@ else
MESA_BUILD_GALLIUM := false
endif
-MESA_ENABLE_LLVM := $(if $(filter radeonsi,$(MESA_GPU_DRIVERS)),true,false)
+MESA_ENABLE_LLVM := $(if $(filter radeonsi swrast,$(MESA_GPU_DRIVERS)),true,false)
# add subdirectories
ifneq ($(strip $(MESA_GPU_DRIVERS)),)
diff --git a/CleanSpec.mk b/CleanSpec.mk
index d08b0def7d..d0fcc723c5 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -14,3 +14,4 @@ $(call add-clean-step, rm -rf $(HOST_OUT_release)/*/EXECUTABLES/mesa_*_intermedi
$(call add-clean-step, rm -rf $(HOST_OUT_release)/*/EXECUTABLES/glsl_compiler_intermediates)
$(call add-clean-step, rm -rf $(HOST_OUT_release)/*/STATIC_LIBRARIES/libmesa_*_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/*/SHARED_LIBRARIES/*_dri_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/*/SHARED_LIBRARIES/*_dri_intermediates)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index d0b1bc6683..69591f697b 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -62,6 +62,7 @@ typedef struct __DRIdrawableRec __DRIdrawable;
typedef struct __DRIconfigRec __DRIconfig;
typedef struct __DRIframebufferRec __DRIframebuffer;
typedef struct __DRIversionRec __DRIversion;
+typedef struct __DRIimageRec __DRIimage;
typedef struct __DRIcoreExtensionRec __DRIcoreExtension;
typedef struct __DRIextensionRec __DRIextension;
@@ -819,7 +820,9 @@ struct __DRIlegacyExtensionRec {
* conjunction with the core extension.
*/
#define __DRI_SWRAST "DRI_SWRast"
-#define __DRI_SWRAST_VERSION 4
+#define __DRI_SWRAST_VERSION 5
+
+struct winsys_handle;
struct __DRIswrastExtensionRec {
__DRIextension base;
@@ -867,6 +870,10 @@ struct __DRIswrastExtensionRec {
const __DRIconfig ***driver_configs,
void *loaderPrivate);
+ __DRIimage *(*createImageFromWinsys)(__DRIscreen *_screen,
+ int width, int height, int format,
+ int num_handles, struct winsys_handle *whandle,
+ void *loaderPrivate);
};
/** Common DRI function definitions, shared among DRI2 and Image extensions
@@ -1264,7 +1271,6 @@ enum __DRIChromaSiting {
#define __BLIT_FLAG_FLUSH 0x0001
#define __BLIT_FLAG_FINISH 0x0002
-typedef struct __DRIimageRec __DRIimage;
typedef struct __DRIimageExtensionRec __DRIimageExtension;
struct __DRIimageExtensionRec {
__DRIextension base;
diff --git a/src/amd/common/radeon_llvm_init.h b/src/amd/common/radeon_llvm_init.h
new file mode 100644
index 0000000000..659b36b7de
--- /dev/null
+++ b/src/amd/common/radeon_llvm_init.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 Android-x86 Open Source Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors: Chih-Wei Huang <cwhuang@linux.org.tw>
+ *
+ */
+
+#ifndef RADEON_LLVM_INIT_H
+#define RADEON_LLVM_INIT_H
+
+#if HAVE_LLVM < 0x0307
+
+extern void LLVMInitializeR600TargetInfo();
+extern void LLVMInitializeR600Target();
+extern void LLVMInitializeR600TargetMC();
+extern void LLVMInitializeR600AsmPrinter();
+
+#define LLVMInitializeAMDGPUTargetInfo LLVMInitializeR600TargetInfo
+#define LLVMInitializeAMDGPUTarget LLVMInitializeR600Target
+#define LLVMInitializeAMDGPUTargetMC LLVMInitializeR600TargetMC
+#define LLVMInitializeAMDGPUAsmPrinter LLVMInitializeR600AsmPrinter
+
+#else
+
+extern void LLVMInitializeAMDGPUTargetInfo();
+extern void LLVMInitializeAMDGPUTarget();
+extern void LLVMInitializeAMDGPUTargetMC();
+extern void LLVMInitializeAMDGPUAsmPrinter();
+
+#endif
+
+#endif /* RADEON_LLVM_INIT_H */
diff --git a/src/compiler/glsl/ast_array_index.cpp b/src/compiler/glsl/ast_array_index.cpp
index e29dafb790..f236fbfddc 100644
--- a/src/compiler/glsl/ast_array_index.cpp
+++ b/src/compiler/glsl/ast_array_index.cpp
@@ -292,7 +292,7 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
!state->EXT_gpu_shader5_enable &&
!state->OES_gpu_shader5_enable) {
if (state->is_version(130, 300))
- _mesa_glsl_error(&loc, state,
+ _mesa_glsl_warning(&loc, state,
"sampler arrays indexed with non-constant "
"expressions are forbidden in GLSL %s "
"and later",
diff --git a/src/egl/Android.mk b/src/egl/Android.mk
index bfd56a744d..a309bb7bbb 100644
--- a/src/egl/Android.mk
+++ b/src/egl/Android.mk
@@ -46,6 +46,7 @@ LOCAL_CFLAGS := \
LOCAL_C_INCLUDES := \
$(MESA_TOP)/src/egl/main \
$(MESA_TOP)/src/egl/drivers/dri2 \
+ $(MESA_TOP)/src/gallium/include \
LOCAL_STATIC_LIBRARIES := \
libmesa_loader
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index d9e2ad701b..b12c26cd2b 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -401,6 +401,7 @@ static const struct dri2_extension_match swrast_driver_extensions[] = {
static const struct dri2_extension_match swrast_core_extensions[] = {
{ __DRI_TEX_BUFFER, 2, offsetof(struct dri2_egl_display, tex_buffer) },
+ { __DRI_IMAGE, 1, offsetof(struct dri2_egl_display, image) },
{ NULL, 0, 0 }
};
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index cf60f1d6ba..67f799c812 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -39,7 +39,9 @@
#include "loader.h"
#include "egl_dri2.h"
#include "egl_dri2_fallbacks.h"
+#include "state_tracker/drm_driver.h"
#include "gralloc_drm.h"
+#include "gralloc_drm_handle.h"
#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))
@@ -116,9 +118,12 @@ get_native_buffer_fd(struct ANativeWindowBuffer *buf)
static int
get_native_buffer_name(struct ANativeWindowBuffer *buf)
{
- return gralloc_drm_get_gem_handle(buf->handle);
+ struct gralloc_drm_handle_t *handle = gralloc_drm_handle(buf->handle);
+ return (handle) ? handle->name : 0;
}
+static const gralloc_module_t *gr_module = NULL;
+
static EGLBoolean
droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf)
{
@@ -300,9 +305,14 @@ droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
if (!config)
goto cleanup_surface;
- dri2_surf->dri_drawable =
- (*dri2_dpy->dri2->createNewDrawable)(dri2_dpy->dri_screen, config,
- dri2_surf);
+ if (dri2_dpy->dri2) {
+ dri2_surf->dri_drawable =
+ dri2_dpy->dri2->createNewDrawable(dri2_dpy->dri_screen, config, dri2_surf);
+ } else {
+ dri2_surf->dri_drawable =
+ dri2_dpy->swrast->createNewDrawable(dri2_dpy->dri_screen, config, dri2_surf);
+ }
+
if (dri2_surf->dri_drawable == NULL) {
_eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable");
goto cleanup_surface;
@@ -807,20 +817,268 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
return (count != 0);
}
+static int swrastUpdateBuffer(struct dri2_egl_surface *dri2_surf)
+{
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
+ if (!dri2_surf->buffer && !droid_window_dequeue_buffer(dri2_surf)) {
+ _eglLog(_EGL_WARNING, "failed to dequeue buffer for window");
+ return 1;
+ }
+ dri2_surf->base.Width = dri2_surf->buffer->width;
+ dri2_surf->base.Height = dri2_surf->buffer->height;
+ }
+ return 0;
+}
+
+static void
+swrastGetDrawableInfo(__DRIdrawable * draw,
+ int *x, int *y, int *w, int *h,
+ void *loaderPrivate)
+{
+ struct dri2_egl_surface *dri2_surf = loaderPrivate;
+
+ swrastUpdateBuffer(dri2_surf);
+
+ *x = 0;
+ *y = 0;
+ *w = dri2_surf->base.Width;
+ *h = dri2_surf->base.Height;
+}
+
+static void
+swrastPutImage2(__DRIdrawable * draw, int op,
+ int x, int y, int w, int h, int stride,
+ char *data, void *loaderPrivate)
+{
+ struct dri2_egl_surface *dri2_surf = loaderPrivate;
+ struct _EGLDisplay *egl_dpy = dri2_surf->base.Resource.Display;
+ char *dstPtr, *srcPtr;
+ size_t BPerPixel, dstStride, copyWidth, xOffset;
+
+// _eglLog(_EGL_WARNING, "calling swrastPutImage with draw=%p, private=%p, x=%d, y=%d, w=%d, h=%d",
+// draw, loaderPrivate, x, y, w, h);
+
+ if (swrastUpdateBuffer(dri2_surf)) {
+ return;
+ }
+
+ BPerPixel = get_format_bpp(dri2_surf->buffer->format);
+ dstStride = BPerPixel * dri2_surf->buffer->stride;
+ copyWidth = BPerPixel * w;
+ xOffset = BPerPixel * x;
+
+ /* drivers expect we do these checks (and some rely on it) */
+ if (copyWidth > dstStride - xOffset)
+ copyWidth = dstStride - xOffset;
+ if (h > dri2_surf->base.Height - y)
+ h = dri2_surf->base.Height - y;
+
+ if (gr_module->lock(gr_module, dri2_surf->buffer->handle, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ 0, 0, dri2_surf->buffer->width, dri2_surf->buffer->height, (void**)&dstPtr)) {
+ _eglLog(_EGL_WARNING, "can not lock window buffer");
+ return;
+ }
+
+ dstPtr += y * dstStride + xOffset;
+ srcPtr = data;
+
+ if (xOffset == 0 && copyWidth == stride && copyWidth == dstStride) {
+ memcpy(dstPtr, srcPtr, copyWidth * h);
+ } else {
+ for (; h>0; h--) {
+ memcpy(dstPtr, srcPtr, copyWidth);
+ srcPtr += stride;
+ dstPtr += dstStride;
+ }
+ }
+
+ if (gr_module->unlock(gr_module, dri2_surf->buffer->handle)) {
+ _eglLog(_EGL_WARNING, "unlock buffer failed");
+ }
+
+ droid_window_enqueue_buffer(egl_dpy, dri2_surf);
+}
+
+static void
+swrastPutImage(__DRIdrawable * draw, int op,
+ int x, int y, int w, int h,
+ char *data, void *loaderPrivate)
+{
+ struct dri2_egl_surface *dri2_surf = loaderPrivate;
+ int stride;
+
+ if (swrastUpdateBuffer(dri2_surf)) {
+ return;
+ }
+
+ stride = get_format_bpp(dri2_surf->buffer->format) * w;
+ swrastPutImage2(draw, op, x, y, w, h, stride, data, loaderPrivate);
+}
+
+static void
+swrastGetImage(__DRIdrawable * read,
+ int x, int y, int w, int h,
+ char *data, void *loaderPrivate)
+{
+ struct dri2_egl_surface *dri2_surf = loaderPrivate;
+ size_t BPerPixel, srcStride, copyWidth, xOffset;
+ char *dstPtr, *srcPtr;
+
+ _eglLog(_EGL_WARNING, "calling swrastGetImage with read=%p, private=%p, w=%d, h=%d", read, loaderPrivate, w, h);
+
+ if (swrastUpdateBuffer(dri2_surf)) {
+ _eglLog(_EGL_WARNING, "swrastGetImage failed data unchanged");
+ return;
+ }
+
+ BPerPixel = get_format_bpp(dri2_surf->buffer->format);
+ srcStride = BPerPixel * dri2_surf->buffer->stride;
+ copyWidth = BPerPixel * w;
+ xOffset = BPerPixel * x;
+
+ if (gr_module->lock(gr_module, dri2_surf->buffer->handle, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ 0, 0, dri2_surf->buffer->width, dri2_surf->buffer->height, (void**)&srcPtr)) {
+ _eglLog(_EGL_WARNING, "can not lock window buffer");
+ memset(data, 0, copyWidth * h);
+ return;
+ }
+
+ srcPtr += y * srcStride + xOffset;
+ dstPtr = data;
+
+ if (xOffset == 0 && copyWidth == srcStride) {
+ memcpy(dstPtr, srcPtr, copyWidth * h);
+ } else {
+ for (; h>0; h--) {
+ memcpy(dstPtr, srcPtr, copyWidth);
+ srcPtr += srcStride;
+ dstPtr += copyWidth;
+ }
+ }
+
+ if (gr_module->unlock(gr_module, dri2_surf->buffer->handle)) {
+ _eglLog(_EGL_WARNING, "unlock buffer failed");
+ }
+}
+
+static EGLBoolean
+swrast_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+
+ dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
+
+ return EGL_TRUE;
+}
+
+static _EGLImage *
+swrast_create_image_android_native_buffer(_EGLDisplay *disp, _EGLContext *ctx,
+ struct ANativeWindowBuffer *buf)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_image *dri2_img;
+ struct winsys_handle whandle;
+ EGLint format;
+
+ if (ctx != NULL) {
+ /* From the EGL_ANDROID_image_native_buffer spec:
+ *
+ * * If <target> is EGL_NATIVE_BUFFER_ANDROID and <ctx> is not
+ * EGL_NO_CONTEXT, the error EGL_BAD_CONTEXT is generated.
+ */
+ _eglError(EGL_BAD_CONTEXT, "eglCreateEGLImageKHR: for "
+ "EGL_NATIVE_BUFFER_ANDROID, the context must be "
+ "EGL_NO_CONTEXT");
+ return NULL;
+ }
+
+ if (!buf || buf->common.magic != ANDROID_NATIVE_BUFFER_MAGIC ||
+ buf->common.version != sizeof(*buf)) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+ return NULL;
+ }
+
+ /* see the table in droid_add_configs_for_visuals */
+ format = get_format(buf->format);
+ if (format < 0)
+ return NULL;
+
+ dri2_img = calloc(1, sizeof(*dri2_img));
+ if (!dri2_img) {
+ _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
+ return NULL;
+ }
+
+ if (!_eglInitImage(&dri2_img->base, disp)) {
+ free(dri2_img);
+ return NULL;
+ }
+
+ memset(&whandle, 0, sizeof(whandle));
+ whandle.type = DRM_API_HANDLE_TYPE_BUFFER;
+ whandle.externalBuffer = buf;
+ whandle.stride = buf->stride * get_format_bpp(buf->format);
+
+ dri2_img->dri_image =
+ dri2_dpy->swrast->createImageFromWinsys(dri2_dpy->dri_screen,
+ buf->width,
+ buf->height,
+ format,
+ 1, &whandle,
+ dri2_img);
+
+ if (!dri2_img->dri_image) {
+ free(dri2_img);
+ _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
+ return NULL;
+ }
+
+ return &dri2_img->base;
+}
+
+static _EGLImage *
+swrast_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLContext *ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ switch (target) {
+ case EGL_NATIVE_BUFFER_ANDROID:
+ return swrast_create_image_android_native_buffer(disp, ctx,
+ (struct ANativeWindowBuffer *) buffer);
+ default:
+ return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
+ }
+}
+
static int
-droid_open_device(void)
+load_gralloc(void)
{
const hw_module_t *mod;
- int fd = -1, err;
+ int err;
err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod);
if (!err) {
- const gralloc_module_t *gr = (gralloc_module_t *) mod;
-
- err = -EINVAL;
- if (gr->perform)
- err = gr->perform(gr, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd);
+ gr_module = (gralloc_module_t *) mod;
+ } else {
+ _eglLog(_EGL_WARNING, "fail to load gralloc");
}
+ return err;
+}
+
+static int
+is_drm_gralloc(void)
+{
+ /* need a cleaner way to distinguish drm_gralloc and gralloc.default */
+ return !!gr_module->perform;
+}
+
+static int
+droid_open_device(void)
+{
+ int fd = -1, err;
+
+ err = gr_module->perform(gr_module, GRALLOC_MODULE_PERFORM_GET_DRM_FD, &fd);
if (err || fd < 0) {
_eglLog(_EGL_WARNING, "fail to get drm fd");
fd = -1;
@@ -896,6 +1154,15 @@ static const __DRIimageLoaderExtension droid_image_loader_extension = {
.flushFrontBuffer = droid_flush_front_buffer,
};
+static const __DRIswrastLoaderExtension droid_swrast_loader_extension = {
+ .base = { __DRI_SWRAST_LOADER, 2 },
+
+ .getDrawableInfo = swrastGetDrawableInfo,
+ .putImage = swrastPutImage,
+ .getImage = swrastGetImage,
+ .putImage2 = swrastPutImage2,
+};
+
static const __DRIextension *droid_dri2_loader_extensions[] = {
&droid_dri2_loader_extension.base,
&image_lookup_extension.base,
@@ -910,8 +1177,14 @@ static const __DRIextension *droid_image_loader_extensions[] = {
NULL,
};
-EGLBoolean
-dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy)
+static const __DRIextension *droid_swrast_loader_extensions[] = {
+ &droid_swrast_loader_extension.base,
+ &image_lookup_extension.base,
+ NULL,
+};
+
+static EGLBoolean
+dri2_initialize_android_drm(_EGLDriver *drv, _EGLDisplay *dpy)
{
struct dri2_egl_display *dri2_dpy;
const char *err;
@@ -987,3 +1260,106 @@ cleanup_display:
return _eglError(EGL_NOT_INITIALIZED, err);
}
+
+/* differs with droid_display_vtbl in create_image, swap_buffers */
+static struct dri2_egl_display_vtbl swrast_display_vtbl = {
+ .authenticate = NULL,
+ .create_window_surface = droid_create_window_surface,
+ .create_pixmap_surface = dri2_fallback_create_pixmap_surface,
+ .create_pbuffer_surface = droid_create_pbuffer_surface,
+ .destroy_surface = droid_destroy_surface,
+ .create_image = swrast_create_image_khr,
+ .swap_interval = dri2_fallback_swap_interval,
+ .swap_buffers = swrast_swap_buffers,
+ .swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage,
+ .swap_buffers_region = dri2_fallback_swap_buffers_region,
+ .post_sub_buffer = dri2_fallback_post_sub_buffer,
+ .copy_buffers = dri2_fallback_copy_buffers,
+ .query_buffer_age = dri2_fallback_query_buffer_age,
+ .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
+ .get_sync_values = dri2_fallback_get_sync_values,
+ .get_dri_drawable = dri2_surface_get_dri_drawable,
+};
+
+static EGLBoolean
+dri2_initialize_android_swrast(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ struct dri2_egl_display *dri2_dpy;
+ const char *err = "";
+ const hw_module_t *mod;
+
+ _eglSetLogProc(droid_log);
+
+ loader_set_logger(_eglLog);
+
+ dri2_dpy = calloc(1, sizeof(*dri2_dpy));
+ if (!dri2_dpy)
+ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+ dpy->DriverData = (void *) dri2_dpy;
+
+ dri2_dpy->driver_name = strdup("swrast");
+ if (!dri2_load_driver_swrast(dpy)) {
+ err = "DRISW: failed to load swrast driver";
+ goto cleanup_driver_name;
+ }
+
+ dri2_dpy->loader_extensions = droid_swrast_loader_extensions;
+
+ if (!dri2_create_screen(dpy)) {
+ err = "DRISW: failed to create screen";
+ goto cleanup_driver;
+ }
+
+ if (!droid_add_configs_for_visuals(drv, dpy)) {
+ err = "DRISW: failed to add configs";
+ goto cleanup_screen;
+ }
+
+ dpy->Extensions.ANDROID_framebuffer_target = EGL_TRUE;
+ dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
+ dpy->Extensions.ANDROID_recordable = EGL_TRUE;
+ dpy->Extensions.KHR_image_base = EGL_TRUE;
+
+ /* Fill vtbl last to prevent accidentally calling virtual function during
+ * initialization.
+ */
+ dri2_dpy->vtbl = &swrast_display_vtbl;
+
+ return EGL_TRUE;
+
+cleanup_screen:
+ dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
+cleanup_driver:
+ dlclose(dri2_dpy->driver);
+cleanup_driver_name:
+ free(dri2_dpy->driver_name);
+ free(dri2_dpy);
+
+ return _eglError(EGL_NOT_INITIALIZED, err);
+}
+
+EGLBoolean
+dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ EGLBoolean initialized = EGL_TRUE;
+
+ if (load_gralloc()) {
+ return EGL_FALSE;
+ }
+
+ int droid_hw_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL) && is_drm_gralloc();
+
+ if (droid_hw_accel) {
+ if (!dri2_initialize_android_drm(drv, dpy)) {
+ initialized = dri2_initialize_android_swrast(drv, dpy);
+ if (initialized) {
+ _eglLog(_EGL_INFO, "Android: Fallback to software renderer");
+ }
+ }
+ } else {
+ initialized = dri2_initialize_android_swrast(drv, dpy);
+ }
+
+ return initialized;
+}
diff --git a/src/gallium/Android.common.mk b/src/gallium/Android.common.mk
index 7c6c7ac682..b40b8c6f4e 100644
--- a/src/gallium/Android.common.mk
+++ b/src/gallium/Android.common.mk
@@ -34,7 +34,7 @@ LOCAL_C_INCLUDES += \
external/llvm/include \
external/llvm/device/include \
external/libcxx/include \
- external/elfutils/$(if $(filter true,$(MESA_LOLLIPOP_BUILD)),0.153/)libelf
+ external/elfutils/$(if $(filter 5,$(MESA_ANDROID_MAJOR_VERSION)),0.153/,$(if $(filter 6,$(MESA_ANDROID_MAJOR_VERSION)),src/))libelf
endif
include $(MESA_COMMON_MK)
diff --git a/src/gallium/Android.mk b/src/gallium/Android.mk
index 2b469b65ee..690b289181 100644
--- a/src/gallium/Android.mk
+++ b/src/gallium/Android.mk
@@ -35,7 +35,7 @@ SUBDIRS += auxiliary/pipe-loader
# swrast
ifneq ($(filter swrast,$(MESA_GPU_DRIVERS)),)
-SUBDIRS += winsys/sw/dri drivers/softpipe
+SUBDIRS += winsys/sw/dri drivers/llvmpipe drivers/softpipe
endif
# freedreno
diff --git a/src/gallium/auxiliary/Android.mk b/src/gallium/auxiliary/Android.mk
index f5b5a0cccc..b279c3bfb7 100644
--- a/src/gallium/auxiliary/Android.mk
+++ b/src/gallium/auxiliary/Android.mk
@@ -46,7 +46,7 @@ endif
# We need libmesa_nir to get NIR's generated include directories.
LOCAL_MODULE := libmesa_gallium
-LOCAL_STATIC_LIBRARIES += libmesa_nir
+LOCAL_STATIC_LIBRARIES := libmesa_nir libLLVMCore
# generate sources
LOCAL_MODULE_CLASS := STATIC_LIBRARIES
diff --git a/src/gallium/auxiliary/os/os_misc.c b/src/gallium/auxiliary/os/os_misc.c
index 09d4400e08..a4d962868a 100644
--- a/src/gallium/auxiliary/os/os_misc.c
+++ b/src/gallium/auxiliary/os/os_misc.c
@@ -46,8 +46,10 @@
#endif
-
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_ANDROID)
+# define LOG_TAG "gallium"
+# include <log/log.h>
+#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS)
# include <unistd.h>
#elif defined(PIPE_OS_APPLE) || defined(PIPE_OS_BSD)
# include <sys/sysctl.h>
@@ -100,6 +102,12 @@ os_log_message(const char *message)
fflush(fout);
}
#else /* !PIPE_SUBSYSTEM_WINDOWS */
+#if defined(PIPE_OS_ANDROID)
+ if (fout == stderr) {
+ ALOGD("%s", message);
+ return;
+ }
+#endif
fflush(stdout);
fputs(message, fout);
fflush(fout);
diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader.h b/src/gallium/auxiliary/pipe-loader/pipe_loader.h
index 690d088ed8..19d269fe75 100644
--- a/src/gallium/auxiliary/pipe-loader/pipe_loader.h
+++ b/src/gallium/auxiliary/pipe-loader/pipe_loader.h
@@ -180,6 +180,9 @@ pipe_loader_drm_probe(struct pipe_loader_device **devs, int ndev);
bool
pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd);
+struct pipe_screen *
+load_pipe_screen(struct pipe_loader_device **dev, int fd);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c
index 2b7ab2757a..f72a94fd87 100644
--- a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c
+++ b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c
@@ -294,3 +294,12 @@ static const struct pipe_loader_ops pipe_loader_drm_ops = {
.configuration = pipe_loader_drm_configuration,
.release = pipe_loader_drm_release
};
+
+PUBLIC struct pipe_screen *load_pipe_screen(struct pipe_loader_device **dev, int fd)
+{
+ struct pipe_screen *pscreen = NULL;
+ if (pipe_loader_drm_probe_fd(dev, fd)) {
+ pscreen = pipe_loader_create_screen(*dev);
+ }
+ return pscreen;
+}
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index dd3e16791d..6ccc4f6ece 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -55,7 +55,7 @@ void
_debug_vprintf(const char *format, va_list ap)
{
static char buf[4096] = {'\0'};
-#if defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_EMBEDDED)
+#if defined(PIPE_OS_WINDOWS) || defined(PIPE_OS_ANDROID) || defined(PIPE_SUBSYSTEM_EMBEDDED)
/* We buffer until we find a newline. */
size_t len = strlen(buf);
int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap);
diff --git a/src/gallium/drivers/llvmpipe/Android.mk b/src/gallium/drivers/llvmpipe/Android.mk
new file mode 100644
index 0000000000..b074e34a68
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/Android.mk
@@ -0,0 +1,37 @@
+# Mesa 3-D graphics library
+#
+# Copyright (C) 2015-2016 Zhen Wu <wuzhen@jidemail.com>
+# Copyright (C) 2015-2016 Jide Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+LOCAL_PATH := $(call my-dir)
+
+# get C_SOURCES
+include $(LOCAL_PATH)/Makefile.sources
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ $(C_SOURCES)
+
+LOCAL_MODULE := libmesa_pipe_llvmpipe
+
+include $(GALLIUM_COMMON_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c
index 17052b26e9..b164953c38 100644
--- a/src/gallium/drivers/nouveau/nouveau_buffer.c
+++ b/src/gallium/drivers/nouveau/nouveau_buffer.c
@@ -80,6 +80,8 @@ release_allocation(struct nouveau_mm_allocation **mm,
inline void
nouveau_buffer_release_gpu_storage(struct nv04_resource *buf)
{
+ if (buf->fence)
+ pipe_mutex_lock(buf->fence->screen->push_mutex);
if (buf->fence && buf->fence->state < NOUVEAU_FENCE_STATE_FLUSHED) {
nouveau_fence_work(buf->fence, nouveau_fence_unref_bo, buf->bo);
buf->bo = NULL;
@@ -89,6 +91,8 @@ nouveau_buffer_release_gpu_storage(struct nv04_resource *buf)
if (buf->mm)
release_allocation(&buf->mm, buf->fence);
+ if (buf->fence)
+ pipe_mutex_unlock(buf->fence->screen->push_mutex);
if (buf->domain == NOUVEAU_BO_VRAM)
NOUVEAU_DRV_STAT_RES(buf, buf_obj_current_bytes_vid, -(uint64_t)buf->base.width0);
@@ -380,6 +384,7 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
struct pipe_transfer **ptransfer)
{
struct nouveau_context *nv = nouveau_context(pipe);
+ struct nouveau_screen *screen = nv->screen;
struct nv04_resource *buf = nv04_resource(resource);
struct nouveau_transfer *tx = MALLOC_STRUCT(nouveau_transfer);
uint8_t *map;
@@ -427,14 +432,19 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
buf->data = NULL;
}
nouveau_transfer_staging(nv, tx, false);
+ pipe_mutex_lock(screen->push_mutex);
nouveau_transfer_read(nv, tx);
+ pipe_mutex_unlock(screen->push_mutex);
} else {
/* The buffer is currently idle. Create a staging area for writes,
* and make sure that the cached data is up-to-date. */
if (usage & PIPE_TRANSFER_WRITE)
nouveau_transfer_staging(nv, tx, true);
- if (!buf->data)
+ if (!buf->data) {
+ pipe_mutex_lock(screen->push_mutex);
nouveau_buffer_cache(nv, buf);
+ pipe_mutex_unlock(screen->push_mutex);
+ }
}
}
return buf->data ? (buf->data + box->x) : tx->map;
@@ -479,7 +489,9 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
if (unlikely(usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)) {
/* Discarding was not possible, must sync because
* subsequent transfers might use UNSYNCHRONIZED. */
+ pipe_mutex_lock(screen->push_mutex);
nouveau_buffer_sync(nv, buf, usage & PIPE_TRANSFER_READ_WRITE);
+ pipe_mutex_unlock(screen->push_mutex);
} else
if (usage & PIPE_TRANSFER_DISCARD_RANGE) {
/* The whole range is being discarded, so it doesn't matter what was
@@ -488,10 +500,13 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
map = tx->map;
} else
if (nouveau_buffer_busy(buf, PIPE_TRANSFER_READ)) {
- if (usage & PIPE_TRANSFER_DONTBLOCK)
+ if (usage & PIPE_TRANSFER_DONTBLOCK) {
map = NULL;
- else
+ } else {
+ pipe_mutex_lock(screen->push_mutex);
nouveau_buffer_sync(nv, buf, usage & PIPE_TRANSFER_READ_WRITE);
+ pipe_mutex_unlock(screen->push_mutex);
+ }
} else {
/* It is expected that the returned buffer be a representation of the
* data in question, so we must copy it over from the buffer. */
@@ -515,9 +530,13 @@ nouveau_buffer_transfer_flush_region(struct pipe_context *pipe,
{
struct nouveau_transfer *tx = nouveau_transfer(transfer);
struct nv04_resource *buf = nv04_resource(transfer->resource);
+ struct nouveau_screen *screen = nouveau_context(pipe)->screen;
- if (tx->map)
+ if (tx->map) {
+ pipe_mutex_lock(screen->push_mutex);
nouveau_transfer_write(nouveau_context(pipe), tx, box->x, box->width);
+ pipe_mutex_unlock(screen->push_mutex);
+ }
util_range_add(&buf->valid_buffer_range,
tx->base.box.x + box->x,
@@ -537,11 +556,15 @@ nouveau_buffer_transfer_unmap(struct pipe_context *pipe,
struct nouveau_context *nv = nouveau_context(pipe);
struct nouveau_transfer *tx = nouveau_transfer(transfer);
struct nv04_resource *buf = nv04_resource(transfer->resource);
+ struct nouveau_screen *screen = nouveau_context(pipe)->screen;
if (tx->base.usage & PIPE_TRANSFER_WRITE) {
if (!(tx->base.usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
- if (tx->map)
+ if (tx->map) {
+ pipe_mutex_lock(screen->push_mutex);
nouveau_transfer_write(nv, tx, 0, tx->base.box.width);
+ pipe_mutex_unlock(screen->push_mutex);
+ }
util_range_add(&buf->valid_buffer_range,
tx->base.box.x, tx->base.box.x + tx->base.box.width);
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c
index 691553ae7e..9cbfc2aeee 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.c
+++ b/src/gallium/drivers/nouveau/nouveau_fence.c
@@ -71,12 +71,14 @@ nouveau_fence_emit(struct nouveau_fence *fence)
++fence->ref;
+ pipe_mutex_lock(screen->fence.list_mutex);
if (screen->fence.tail)
screen->fence.tail->next = fence;
else
screen->fence.head = fence;
screen->fence.tail = fence;
+ pipe_mutex_unlock(screen->fence.list_mutex);
screen->fence.emit(&screen->base, &fence->sequence);
@@ -90,6 +92,9 @@ nouveau_fence_del(struct nouveau_fence *fence)
struct nouveau_fence *it;
struct nouveau_screen *screen = fence->screen;
+ /* XXX This can race against fence_update. But fence_update can also call
+ * into this, so ... be have to be careful.
+ */
if (fence->state == NOUVEAU_FENCE_STATE_EMITTED ||
fence->state == NOUVEAU_FENCE_STATE_FLUSHED) {
if (fence == screen->fence.head) {
@@ -123,6 +128,7 @@ nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
return;
screen->fence.sequence_ack = sequence;
+ pipe_mutex_lock(screen->fence.list_mutex);
for (fence = screen->fence.head; fence; fence = next) {
next = fence->next;
sequence = fence->sequence;
@@ -144,6 +150,7 @@ nouveau_fence_update(struct nouveau_screen *screen, bool flushed)
if (fence->state == NOUVEAU_FENCE_STATE_EMITTED)
fence->state = NOUVEAU_FENCE_STATE_FLUSHED;
}
+ pipe_mutex_unlock(screen->fence.list_mutex);
}
#define NOUVEAU_FENCE_MAX_SPINS (1 << 31)
@@ -198,18 +205,27 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct pipe_debug_callback *debu
uint32_t spins = 0;
int64_t start = 0;
+ /* Fast-path for the case where the fence is already signaled to avoid
+ * messing around with mutexes and timing.
+ */
+ if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
+ return true;
+
if (debug && debug->debug_message)
start = os_time_get_nano();
if (!nouveau_fence_kick(fence))
return false;
+ pipe_mutex_unlock(screen->push_mutex);
+
do {
if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) {
if (debug && debug->debug_message)
pipe_debug_message(debug, PERF_INFO,
"stalled %.3f ms waiting for fence",
(os_time_get_nano() - start) / 1000000.f);
+ pipe_mutex_lock(screen->push_mutex);
return true;
}
if (!spins)
@@ -227,6 +243,8 @@ nouveau_fence_wait(struct nouveau_fence *fence, struct pipe_debug_callback *debu
fence->sequence,
screen->fence.sequence_ack, screen->fence.sequence);
+ pipe_mutex_lock(screen->push_mutex);
+
return false;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_fence.h b/src/gallium/drivers/nouveau/nouveau_fence.h
index f10016da82..98d021e4cd 100644
--- a/src/gallium/drivers/nouveau/nouveau_fence.h
+++ b/src/gallium/drivers/nouveau/nouveau_fence.h
@@ -2,6 +2,7 @@
#ifndef __NOUVEAU_FENCE_H__
#define __NOUVEAU_FENCE_H__
+#include "util/u_atomic.h"
#include "util/u_inlines.h"
#include "util/list.h"
@@ -47,10 +48,10 @@ static inline void
nouveau_fence_ref(struct nouveau_fence *fence, struct nouveau_fence **ref)
{
if (fence)
- ++fence->ref;
+ p_atomic_inc(&fence->ref);
if (*ref) {
- if (--(*ref)->ref == 0)
+ if (p_atomic_dec_zero(&(*ref)->ref))
nouveau_fence_del(*ref);
}
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index f59e101caf..1a2fe7ded0 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -74,10 +74,14 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *pfence,
uint64_t timeout)
{
+ bool ret;
if (!timeout)
return nouveau_fence_signalled(nouveau_fence(pfence));
- return nouveau_fence_wait(nouveau_fence(pfence), NULL);
+ pipe_mutex_lock(nouveau_screen(screen)->push_mutex);
+ ret = nouveau_fence_wait(nouveau_fence(pfence), NULL);
+ pipe_mutex_unlock(nouveau_screen(screen)->push_mutex);
+ return ret;
}
@@ -154,6 +158,9 @@ nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
if (nv_dbg)
nouveau_mesa_debug = atoi(nv_dbg);
+ pipe_mutex_init(screen->push_mutex);
+ pipe_mutex_init(screen->fence.list_mutex);
+
/* These must be set before any failure is possible, as the cleanup
* paths assume they're responsible for deleting them.
*/
@@ -254,6 +261,9 @@ nouveau_screen_fini(struct nouveau_screen *screen)
nouveau_device_del(&screen->device);
nouveau_drm_del(&screen->drm);
close(fd);
+
+ pipe_mutex_destroy(screen->push_mutex);
+ pipe_mutex_destroy(screen->fence.list_mutex);
}
static void
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index 28c4760af2..28c862096f 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -3,6 +3,7 @@
#include "pipe/p_screen.h"
#include "util/u_memory.h"
+#include "os/os_thread.h"
#ifdef DEBUG
# define NOUVEAU_ENABLE_DRIVER_STATISTICS
@@ -22,6 +23,7 @@ struct nouveau_screen {
struct nouveau_object *channel;
struct nouveau_client *client;
struct nouveau_pushbuf *pushbuf;
+ pipe_mutex push_mutex;
int refcount;
@@ -39,6 +41,7 @@ struct nouveau_screen {
struct nouveau_fence *head;
struct nouveau_fence *tail;
struct nouveau_fence *current;
+ pipe_mutex list_mutex;
u32 sequence;
u32 sequence_ack;
void (*emit)(struct pipe_screen *, u32 *sequence);
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_clear.c b/src/gallium/drivers/nouveau/nv30/nv30_clear.c
index 4217bca6da..b0ab91a2fd 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_clear.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_clear.c
@@ -58,8 +58,11 @@ nv30_clear(struct pipe_context *pipe, unsigned buffers,
struct pipe_framebuffer_state *fb = &nv30->framebuffer;
uint32_t colr = 0, zeta = 0, mode = 0;
- if (!nv30_state_validate(nv30, NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR, true))
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
+ if (!nv30_state_validate(nv30, NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR, true)) {
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
+ }
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
colr = pack_rgba(fb->cbufs[0]->format, color->f);
@@ -96,6 +99,7 @@ nv30_clear(struct pipe_context *pipe, unsigned buffers,
PUSH_DATA (push, mode);
nv30_state_release(nv30);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
}
static void
@@ -126,11 +130,15 @@ nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
rt_format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
}
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
+
refn.bo = mt->base.bo;
refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
if (nouveau_pushbuf_space(push, 16, 1, 0) ||
- nouveau_pushbuf_refn (push, &refn, 1))
+ nouveau_pushbuf_refn (push, &refn, 1)) {
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
+ }
BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);
@@ -155,6 +163,8 @@ nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps,
NV30_3D_CLEAR_BUFFERS_COLOR_B |
NV30_3D_CLEAR_BUFFERS_COLOR_A);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
+
nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
}
@@ -191,11 +201,15 @@ nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,
if (buffers & PIPE_CLEAR_STENCIL)
mode |= NV30_3D_CLEAR_BUFFERS_STENCIL;
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
+
refn.bo = mt->base.bo;
refn.flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
if (nouveau_pushbuf_space(push, 32, 1, 0) ||
- nouveau_pushbuf_refn (push, &refn, 1))
+ nouveau_pushbuf_refn (push, &refn, 1)) {
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
+ }
BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
PUSH_DATA (push, 0);
@@ -221,6 +235,8 @@ nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps,
BEGIN_NV04(push, NV30_3D(CLEAR_BUFFERS), 1);
PUSH_DATA (push, mode);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
+
nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR;
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_context.c b/src/gallium/drivers/nouveau/nv30/nv30_context.c
index 3ed088912e..fbc41367f6 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_context.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_context.c
@@ -201,6 +201,8 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
if (!nv30)
return NULL;
+ pipe_mutex_lock(screen->base.push_mutex);
+
nv30->screen = screen;
nv30->base.screen = &screen->base;
nv30->base.copy_data = nv30_transfer_copy_data;
@@ -226,6 +228,7 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
ret = nouveau_bufctx_new(nv30->base.client, 64, &nv30->bufctx);
if (ret) {
nv30_context_destroy(pipe);
+ pipe_mutex_unlock(screen->base.push_mutex);
return NULL;
}
@@ -259,10 +262,13 @@ nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
nv30->blitter = util_blitter_create(pipe);
if (!nv30->blitter) {
nv30_context_destroy(pipe);
+ pipe_mutex_unlock(screen->base.push_mutex);
return NULL;
}
nouveau_context_init_vdec(&nv30->base);
+ pipe_mutex_unlock(screen->base.push_mutex);
+
return pipe;
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_draw.c b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
index 10c9f56fad..c5761a35b4 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_draw.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_draw.c
@@ -127,6 +127,8 @@ nv30_render_draw_elements(struct vbuf_render *render,
struct nouveau_pushbuf *push = nv30->screen->base.pushbuf;
unsigned i;
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
+
BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
for (i = 0; i < r->vertex_info.num_attribs; i++) {
PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
@@ -134,8 +136,10 @@ nv30_render_draw_elements(struct vbuf_render *render,
NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
}
- if (!nv30_state_validate(nv30, ~0, false))
+ if (!nv30_state_validate(nv30, ~0, false)) {
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
+ }
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
PUSH_DATA (push, r->prim);
@@ -160,6 +164,8 @@ nv30_render_draw_elements(struct vbuf_render *render,
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
PUSH_RESET(push, BUFCTX_VTXTMP);
+
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
}
static void
@@ -172,6 +178,8 @@ nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
unsigned ps = fn + (pn ? 1 : 0);
unsigned i;
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
+
BEGIN_NV04(push, NV30_3D(VTXBUF(0)), r->vertex_info.num_attribs);
for (i = 0; i < r->vertex_info.num_attribs; i++) {
PUSH_RESRC(push, NV30_3D(VTXBUF(i)), BUFCTX_VTXTMP,
@@ -179,8 +187,10 @@ nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
NOUVEAU_BO_LOW | NOUVEAU_BO_RD, 0, NV30_3D_VTXBUF_DMA1);
}
- if (!nv30_state_validate(nv30, ~0, false))
+ if (!nv30_state_validate(nv30, ~0, false)) {
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
+ }
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
PUSH_DATA (push, r->prim);
@@ -197,6 +207,8 @@ nv30_render_draw_arrays(struct vbuf_render *render, unsigned start, uint nr)
BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
PUSH_RESET(push, BUFCTX_VTXTMP);
+
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
}
static void
@@ -386,6 +398,8 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv30_render_validate(nv30);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
+
if (nv30->draw_dirty & NV30_NEW_VIEWPORT)
draw_set_viewport_states(draw, 0, 1, &nv30->viewport);
if (nv30->draw_dirty & NV30_NEW_RASTERIZER)
@@ -451,6 +465,8 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
if (transfer[i])
pipe_buffer_unmap(pipe, transfer[i]);
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
+
nv30->draw_dirty = 0;
nv30_state_release(nv30);
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
index 6de61bcc1c..fd21f99be5 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
@@ -38,6 +38,8 @@ nv30_fragprog_upload(struct nv30_context *nv30)
struct nv30_fragprog *fp = nv30->fragprog.program;
struct pipe_context *pipe = &nv30->base.pipe;
+ pipe_mutex_unlock(nv->screen->push_mutex);
+
if (unlikely(!fp->buffer))
fp->buffer = pipe_buffer_create(pipe->screen, 0, 0, fp->insn_len * 4);
@@ -60,6 +62,8 @@ nv30_fragprog_upload(struct nv30_context *nv30)
if (nv04_resource(fp->buffer)->domain != NOUVEAU_BO_VRAM)
nouveau_buffer_migrate(nv, nv04_resource(fp->buffer), NOUVEAU_BO_VRAM);
+
+ pipe_mutex_lock(nv->screen->push_mutex);
}
void
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
index 165b8f29b4..b748e49417 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_miptree.c
@@ -130,10 +130,12 @@ nv30_resource_copy_region(struct pipe_context *pipe,
struct nv30_context *nv30 = nv30_context(pipe);
struct nv30_rect src, dst;
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
if (dstres->target == PIPE_BUFFER && srcres->target == PIPE_BUFFER) {
nouveau_copy_buffer(&nv30->base,
nv04_resource(dstres), dstx,
nv04_resource(srcres), src_box->x, src_box->width);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
}
@@ -143,6 +145,7 @@ nv30_resource_copy_region(struct pipe_context *pipe,
src_box->width, src_box->height, &dst);
nv30_transfer_rect(nv30, NEAREST, &src, &dst);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
}
static void
@@ -163,6 +166,7 @@ nv30_resource_resolve(struct nv30_context *nv30,
y1 = src.y1;
/* On nv3x we must use sifm which is restricted to 1024x1024 tiles */
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
for (y = src.y0; y < y1; y += h) {
h = y1 - y;
if (h > 1024)
@@ -193,6 +197,7 @@ nv30_resource_resolve(struct nv30_context *nv30,
nv30_transfer_rect(nv30, BILINEAR, &src, &dst);
}
}
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
}
void
@@ -308,8 +313,12 @@ nv30_miptree_transfer_map(struct pipe_context *pipe, struct pipe_resource *pt,
tx->tmp.y1 = tx->tmp.h;
tx->tmp.z = 0;
- if (usage & PIPE_TRANSFER_READ)
+ if (usage & PIPE_TRANSFER_READ) {
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
nv30_transfer_rect(nv30, NEAREST, &tx->img, &tx->tmp);
+ PUSH_KICK(nv30->base.pushbuf);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
+ }
if (tx->tmp.bo->map) {
*ptransfer = &tx->base;
@@ -340,11 +349,13 @@ nv30_miptree_transfer_unmap(struct pipe_context *pipe,
struct nv30_transfer *tx = nv30_transfer(ptx);
if (ptx->usage & PIPE_TRANSFER_WRITE) {
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
nv30_transfer_rect(nv30, NEAREST, &tx->tmp, &tx->img);
/* Allow the copies above to finish executing before freeing the source */
nouveau_fence_work(nv30->screen->base.fence.current,
nouveau_fence_unref_bo, tx->tmp.bo);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
} else {
nouveau_bo_ref(NULL, &tx->tmp.bo);
}
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_query.c b/src/gallium/drivers/nouveau/nv30/nv30_query.c
index aa9a12fe3b..a047e15e36 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_query.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_query.c
@@ -152,6 +152,7 @@ nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
struct nv30_query *q = nv30_query(pq);
struct nouveau_pushbuf *push = nv30->base.pushbuf;
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
switch (q->type) {
case PIPE_QUERY_TIME_ELAPSED:
q->qo[0] = nv30_query_object_new(nv30->screen);
@@ -161,7 +162,7 @@ nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
}
break;
case PIPE_QUERY_TIMESTAMP:
- return true;
+ break;
default:
BEGIN_NV04(push, NV30_3D(QUERY_RESET), 1);
PUSH_DATA (push, q->report);
@@ -172,6 +173,7 @@ nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
BEGIN_NV04(push, SUBC_3D(q->enable), 1);
PUSH_DATA (push, 1);
}
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return true;
}
@@ -183,6 +185,7 @@ nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq)
struct nv30_query *q = nv30_query(pq);
struct nouveau_pushbuf *push = nv30->base.pushbuf;
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
q->qo[1] = nv30_query_object_new(screen);
if (q->qo[1]) {
BEGIN_NV04(push, NV30_3D(QUERY_GET), 1);
@@ -194,6 +197,7 @@ nv30_query_end(struct pipe_context *pipe, struct pipe_query *pq)
PUSH_DATA (push, 0);
}
PUSH_KICK (push);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return true;
}
@@ -248,9 +252,11 @@ nv40_query_render_condition(struct pipe_context *pipe,
nv30->render_cond_mode = mode;
nv30->render_cond_cond = condition;
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
if (!pq) {
BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
PUSH_DATA (push, 0x01000000);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
}
@@ -262,6 +268,7 @@ nv40_query_render_condition(struct pipe_context *pipe,
BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
PUSH_DATA (push, 0x02000000 | q->qo[1]->hw->start);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
}
static void
diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
index bc9b9a16ea..8e3fdee211 100644
--- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c
@@ -563,6 +563,8 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
if (nv30->vbo_push_hint != !!nv30->vbo_fifo)
nv30->dirty |= NV30_NEW_ARRAYS;
+ pipe_mutex_lock(nv30->screen->base.push_mutex);
+
push->user_priv = &nv30->bufctx;
if (nv30->vbo_user && !(nv30->dirty & (NV30_NEW_VERTEX | NV30_NEW_ARRAYS)))
nv30_update_user_vbufs(nv30);
@@ -570,10 +572,12 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv30_state_validate(nv30, ~0, true);
if (nv30->draw_flags) {
nv30_render_vbo(pipe, info);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
} else
if (nv30->vbo_fifo) {
nv30_push_vbo(nv30, info);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
return;
}
@@ -630,6 +634,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv30_state_release(nv30);
nv30_release_user_vbufs(nv30);
+ pipe_mutex_unlock(nv30->screen->base.push_mutex);
}
void
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_compute.c b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
index d781f6fd7d..3c174e419e 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_compute.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_compute.c
@@ -249,9 +249,11 @@ nv50_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
struct nv50_program *cp = nv50->compprog;
bool ret;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
ret = !nv50_state_validate_cp(nv50, ~0);
if (ret) {
NOUVEAU_ERR("Failed to launch grid !\n");
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
}
@@ -284,6 +286,8 @@ nv50_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
BEGIN_NV04(push, SUBC_CP(NV50_GRAPH_SERIALIZE), 1);
PUSH_DATA (push, 0);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
+
/* bind a compute shader clobbers fragment shader state */
nv50->dirty_3d |= NV50_NEW_3D_FRAGPROG;
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.c b/src/gallium/drivers/nouveau/nv50/nv50_context.c
index fc852d7068..84b5e3f5db 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.c
@@ -37,7 +37,9 @@ nv50_flush(struct pipe_context *pipe,
if (fence)
nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
+ pipe_mutex_lock(screen->push_mutex);
PUSH_KICK(screen->pushbuf);
+ pipe_mutex_unlock(screen->push_mutex);
nouveau_context_update_frame_stats(nouveau_context(pipe));
}
@@ -47,10 +49,12 @@ nv50_texture_barrier(struct pipe_context *pipe)
{
struct nouveau_pushbuf *push = nv50_context(pipe)->base.pushbuf;
+ pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
BEGIN_NV04(push, SUBC_3D(NV50_GRAPH_SERIALIZE), 1);
PUSH_DATA (push, 0);
BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
PUSH_DATA (push, 0x20);
+ pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
}
static void
@@ -107,6 +111,7 @@ nv50_emit_string_marker(struct pipe_context *pipe, const char *str, int len)
data_words = string_words;
else
data_words = string_words + !!(len & 3);
+ pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
BEGIN_NI04(push, SUBC_3D(NV04_GRAPH_NOP), data_words);
if (string_words)
PUSH_DATAp(push, str, string_words);
@@ -115,6 +120,7 @@ nv50_emit_string_marker(struct pipe_context *pipe, const char *str, int len)
memcpy(&data, &str[string_words * 4], len & 3);
PUSH_DATA (push, data);
}
+ pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
}
void
@@ -291,6 +297,8 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
return NULL;
pipe = &nv50->base.pipe;
+ pipe_mutex_lock(screen->base.push_mutex);
+
if (!nv50_blitctx_create(nv50))
goto out_err;
@@ -384,9 +392,12 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
util_dynarray_init(&nv50->global_residents);
+ pipe_mutex_unlock(screen->base.push_mutex);
+
return pipe;
out_err:
+ pipe_mutex_unlock(screen->base.push_mutex);
if (nv50->bufctx_3d)
nouveau_bufctx_del(&nv50->bufctx_3d);
if (nv50->bufctx_cp)
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_context.h b/src/gallium/drivers/nouveau/nv50/nv50_context.h
index cca44f5bb2..4c8a4e5387 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_context.h
+++ b/src/gallium/drivers/nouveau/nv50/nv50_context.h
@@ -222,6 +222,11 @@ void nv50_default_kick_notify(struct nouveau_pushbuf *);
/* nv50_draw.c */
extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *);
+/* nv50_query.c */
+void nv50_render_condition(struct pipe_context *pipe,
+ struct pipe_query *pq,
+ boolean condition, uint mode);
+
/* nv50_shader_state.c */
void nv50_vertprog_validate(struct nv50_context *);
void nv50_gmtyprog_validate(struct nv50_context *);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
index f2e304fde6..7f281f993e 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
@@ -163,10 +163,13 @@ nv50_miptree_destroy(struct pipe_screen *pscreen, struct pipe_resource *pt)
{
struct nv50_miptree *mt = nv50_miptree(pt);
- if (mt->base.fence && mt->base.fence->state < NOUVEAU_FENCE_STATE_FLUSHED)
+ if (mt->base.fence && mt->base.fence->state < NOUVEAU_FENCE_STATE_FLUSHED) {
+ pipe_mutex_lock(nouveau_screen(pscreen)->push_mutex);
nouveau_fence_work(mt->base.fence, nouveau_fence_unref_bo, mt->base.bo);
- else
+ pipe_mutex_unlock(nouveau_screen(pscreen)->push_mutex);
+ } else {
nouveau_bo_ref(NULL, &mt->base.bo);
+ }
nouveau_fence_ref(NULL, &mt->base.fence);
nouveau_fence_ref(NULL, &mt->base.fence_wr);
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query.c b/src/gallium/drivers/nouveau/nv50/nv50_query.c
index 9a1397a986..c90e20e1de 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query.c
@@ -70,7 +70,7 @@ nv50_get_query_result(struct pipe_context *pipe, struct pipe_query *pq,
return q->funcs->get_query_result(nv50_context(pipe), q, wait, result);
}
-static void
+void
nv50_render_condition(struct pipe_context *pipe,
struct pipe_query *pq,
boolean condition, uint mode)
@@ -145,6 +145,16 @@ nv50_render_condition(struct pipe_context *pipe,
}
static void
+nv50_render_condition_locked(struct pipe_context *pipe,
+ struct pipe_query *pq,
+ boolean condition, uint mode)
+{
+ pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
+ nv50_render_condition(pipe, pq, condition, mode);
+ pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
+}
+
+static void
nv50_set_active_query_state(struct pipe_context *pipe, boolean enable)
{
}
@@ -160,7 +170,7 @@ nv50_init_query_functions(struct nv50_context *nv50)
pipe->end_query = nv50_end_query;
pipe->get_query_result = nv50_get_query_result;
pipe->set_active_query_state = nv50_set_active_query_state;
- pipe->render_condition = nv50_render_condition;
+ pipe->render_condition = nv50_render_condition_locked;
nv50->cond_condmode = NV50_3D_COND_MODE_ALWAYS;
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
index 727b509372..d2ad72e797 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
@@ -56,9 +56,12 @@ nv50_hw_query_allocate(struct nv50_context *nv50, struct nv50_query *q,
if (hq->mm) {
if (hq->state == NV50_HW_QUERY_STATE_READY)
nouveau_mm_free(hq->mm);
- else
+ else {
+ pipe_mutex_lock(screen->base.push_mutex);
nouveau_fence_work(screen->base.fence.current,
nouveau_mm_free_work, hq->mm);
+ pipe_mutex_unlock(screen->base.push_mutex);
+ }
}
}
if (size) {
@@ -129,6 +132,7 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q)
{
struct nouveau_pushbuf *push = nv50->base.pushbuf;
struct nv50_hw_query *hq = nv50_hw_query(q);
+ bool ret = true;
if (hq->funcs && hq->funcs->begin_query)
return hq->funcs->begin_query(nv50, hq);
@@ -154,6 +158,7 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q)
if (!hq->is64bit)
hq->data[0] = hq->sequence++; /* the previously used one */
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
@@ -193,10 +198,13 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q)
break;
default:
assert(0);
- return false;
+ ret = false;
+ break;
}
- hq->state = NV50_HW_QUERY_STATE_ACTIVE;
- return true;
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
+ if (ret)
+ hq->state = NV50_HW_QUERY_STATE_ACTIVE;
+ return ret;
}
static void
@@ -212,6 +220,7 @@ nv50_hw_end_query(struct nv50_context *nv50, struct nv50_query *q)
hq->state = NV50_HW_QUERY_STATE_ENDED;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
@@ -264,6 +273,7 @@ nv50_hw_end_query(struct nv50_context *nv50, struct nv50_query *q)
assert(0);
break;
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
if (hq->is64bit)
nouveau_fence_ref(nv50->screen->base.fence.current, &hq->fence);
}
@@ -286,16 +296,21 @@ nv50_hw_get_query_result(struct nv50_context *nv50, struct nv50_query *q,
nv50_hw_query_update(q);
if (hq->state != NV50_HW_QUERY_STATE_READY) {
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
if (!wait) {
/* for broken apps that spin on GL_QUERY_RESULT_AVAILABLE */
if (hq->state != NV50_HW_QUERY_STATE_FLUSHED) {
hq->state = NV50_HW_QUERY_STATE_FLUSHED;
PUSH_KICK(nv50->base.pushbuf);
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return false;
}
- if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nv50->screen->base.client))
+ if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nv50->screen->base.client)) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return false;
+ }
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
}
hq->state = NV50_HW_QUERY_STATE_READY;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
index bcfba9f5a8..31445eb508 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
@@ -176,6 +176,7 @@ nv50_hw_sm_begin_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
return false;
}
+ pipe_mutex_lock(screen->base.push_mutex);
assert(cfg->num_counters <= 4);
PUSH_SPACE(push, 4 * 4);
@@ -208,6 +209,7 @@ nv50_hw_sm_begin_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
BEGIN_NV04(push, NV50_CP(MP_PM_SET(c)), 1);
PUSH_DATA (push, 0);
}
+ pipe_mutex_unlock(screen->base.push_mutex);
return true;
}
@@ -237,6 +239,7 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
screen->pm.prog = prog;
}
+ pipe_mutex_lock(screen->base.push_mutex);
/* disable all counting */
PUSH_SPACE(push, 8);
for (c = 0; c < 4; c++) {
@@ -260,6 +263,7 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
PUSH_SPACE(push, 2);
BEGIN_NV04(push, SUBC_CP(NV50_GRAPH_SERIALIZE), 1);
PUSH_DATA (push, 0);
+ pipe_mutex_unlock(screen->base.push_mutex);
pipe->bind_compute_state(pipe, screen->pm.prog);
input[0] = hq->bo->offset + hq->base_offset;
@@ -276,6 +280,7 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
nouveau_bufctx_reset(nv50->bufctx_cp, NV50_BIND_CP_QUERY);
+ pipe_mutex_lock(screen->base.push_mutex);
/* re-active other counters */
PUSH_SPACE(push, 8);
mask = 0;
@@ -302,6 +307,7 @@ nv50_hw_sm_end_query(struct nv50_context *nv50, struct nv50_hw_query *hq)
| cfg->ctr[i].unit | cfg->ctr[i].mode);
}
}
+ pipe_mutex_unlock(screen->base.push_mutex);
}
static inline bool
@@ -343,7 +349,9 @@ nv50_hw_sm_get_query_result(struct nv50_context *nv50, struct nv50_hw_query *hq,
cfg = nv50_hw_sm_query_get_cfg(nv50, hq);
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
ret = nv50_hw_sm_query_read_data(count, nv50, wait, hq, cfg, mp_count);
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
if (!ret)
return false;
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
index a6c0bbc267..c0f77dc765 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c
@@ -204,10 +204,13 @@ nv50_resource_copy_region(struct pipe_context *pipe,
bool m2mf;
unsigned dst_layer = dstz, src_layer = src_box->z;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
nouveau_copy_buffer(&nv50->base,
nv04_resource(dst), dstx,
nv04_resource(src), src_box->x, src_box->width);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
}
@@ -247,6 +250,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
else
srect.base += src_mt->layer_stride;
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
}
@@ -270,6 +274,7 @@ nv50_resource_copy_region(struct pipe_context *pipe,
break;
}
nouveau_bufctx_reset(nv50->bufctx, NV50_BIND_2D);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
}
static void
@@ -289,14 +294,18 @@ nv50_clear_render_target(struct pipe_context *pipe,
assert(dst->texture->target != PIPE_BUFFER);
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
BEGIN_NV04(push, NV50_3D(CLEAR_COLOR(0)), 4);
PUSH_DATAf(push, color->f[0]);
PUSH_DATAf(push, color->f[1]);
PUSH_DATAf(push, color->f[2]);
PUSH_DATAf(push, color->f[3]);
- if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0))
+ if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0)) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
+ }
PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
@@ -358,6 +367,8 @@ nv50_clear_render_target(struct pipe_context *pipe,
PUSH_DATA (push, nv50->cond_condmode);
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
+
nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR;
}
@@ -382,6 +393,8 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
assert(dst->texture->target != PIPE_BUFFER);
assert(nouveau_bo_memtype(bo)); /* ZETA cannot be linear */
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
if (clear_flags & PIPE_CLEAR_DEPTH) {
BEGIN_NV04(push, NV50_3D(CLEAR_DEPTH), 1);
PUSH_DATAf(push, depth);
@@ -394,8 +407,10 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
mode |= NV50_3D_CLEAR_BUFFERS_S;
}
- if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0))
+ if (nouveau_pushbuf_space(push, 32 + sf->depth, 1, 0)) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
+ }
PUSH_REFN(push, bo, mt->base.domain | NOUVEAU_BO_WR);
@@ -446,6 +461,8 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
PUSH_DATA (push, nv50->cond_condmode);
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
+
nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR;
}
@@ -534,9 +551,12 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
unsigned i, j, k;
uint32_t mode = 0;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
/* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
- if (!nv50_state_validate_3d(nv50, NV50_NEW_3D_FRAMEBUFFER))
+ if (!nv50_state_validate_3d(nv50, NV50_NEW_3D_FRAMEBUFFER)) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
+ }
/* We have to clear ALL of the layers, not up to the min number of layers
* of any attachment. */
@@ -602,6 +622,7 @@ nv50_clear(struct pipe_context *pipe, unsigned buffers,
/* restore the array mode */
BEGIN_NV04(push, NV50_3D(RT_ARRAY_MODE), 1);
PUSH_DATA (push, nv50->rt_array_mode);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
}
static void
@@ -729,14 +750,18 @@ nv50_clear_buffer(struct pipe_context *pipe,
assert(size % data_size == 0);
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
if (offset & 0xff) {
unsigned fixup_size = MIN2(size, align(offset, 0x100) - offset);
assert(fixup_size % data_size == 0);
nv50_clear_buffer_push(pipe, res, offset, fixup_size, data, data_size);
offset += fixup_size;
size -= fixup_size;
- if (!size)
+ if (!size) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
+ }
}
elements = size / data_size;
@@ -752,8 +777,10 @@ nv50_clear_buffer(struct pipe_context *pipe,
PUSH_DATAf(push, color.f[2]);
PUSH_DATAf(push, color.f[3]);
- if (nouveau_pushbuf_space(push, 32, 1, 0))
+ if (nouveau_pushbuf_space(push, 32, 1, 0)) {
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
+ }
PUSH_REFN(push, buf->bo, buf->domain | NOUVEAU_BO_WR);
@@ -808,6 +835,8 @@ nv50_clear_buffer(struct pipe_context *pipe,
data, data_size);
}
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
+
nv50->dirty_3d |= NV50_NEW_3D_FRAMEBUFFER | NV50_NEW_3D_SCISSOR;
}
@@ -1724,6 +1753,8 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
info->src.box.height != -info->dst.box.height))
eng3d = true;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
if (nv50->screen->num_occlusion_queries_active) {
BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
PUSH_DATA (push, 0);
@@ -1738,6 +1769,8 @@ nv50_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
BEGIN_NV04(push, NV50_3D(SAMPLECNT_ENABLE), 1);
PUSH_DATA (push, 1);
}
+
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
}
static void
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
index 8209f1f1e8..c751ade345 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c
@@ -304,6 +304,7 @@ nv50_miptree_transfer_map(struct pipe_context *pctx,
unsigned base = tx->rect[0].base;
unsigned z = tx->rect[0].z;
unsigned i;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
for (i = 0; i < box->depth; ++i) {
nv50_m2mf_transfer_rect(nv50, &tx->rect[1], &tx->rect[0],
tx->nblocksx, tx->nblocksy);
@@ -313,6 +314,9 @@ nv50_miptree_transfer_map(struct pipe_context *pctx,
tx->rect[0].base += mt->layer_stride;
tx->rect[1].base += size;
}
+ /* Kick these reads out so we don't have to reacquire a lock below */
+ PUSH_KICK(nv50->base.pushbuf);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
tx->rect[0].z = z;
tx->rect[0].base = base;
tx->rect[1].base = 0;
@@ -349,6 +353,7 @@ nv50_miptree_transfer_unmap(struct pipe_context *pctx,
unsigned i;
if (tx->base.usage & PIPE_TRANSFER_WRITE) {
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
for (i = 0; i < tx->base.box.depth; ++i) {
nv50_m2mf_transfer_rect(nv50, &tx->rect[0], &tx->rect[1],
tx->nblocksx, tx->nblocksy);
@@ -362,6 +367,7 @@ nv50_miptree_transfer_unmap(struct pipe_context *pctx,
/* Allow the copies above to finish executing before freeing the source */
nouveau_fence_work(nv50->screen->base.fence.current,
nouveau_fence_unref_bo, tx->rect[1].bo);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
} else {
nouveau_bo_ref(NULL, &tx->rect[1].bo);
}
diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
index a11cdf847b..f73329cedc 100644
--- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c
@@ -767,6 +767,8 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
bool tex_dirty = false;
int s;
+ pipe_mutex_lock(nv50->screen->base.push_mutex);
+
/* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
nv50->vb_elt_first = info->min_index + info->index_bias;
nv50->vb_elt_limit = info->max_index - info->min_index;
@@ -827,6 +829,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv50_push_vbo(nv50, info);
push->kick_notify = nv50_default_kick_notify;
nouveau_pushbuf_bufctx(push, NULL);
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
return;
}
@@ -886,4 +889,6 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nv50_release_user_vbufs(nv50);
nouveau_pushbuf_bufctx(push, NULL);
+
+ pipe_mutex_unlock(nv50->screen->base.push_mutex);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
index 11635c9465..b8efd1e63e 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
@@ -424,13 +424,17 @@ void
nvc0_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
+ struct nvc0_screen *screen = nvc0->screen;
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nvc0_program *cp = nvc0->compprog;
int ret;
+ pipe_mutex_lock(screen->base.push_mutex);
+
ret = !nvc0_state_validate_cp(nvc0, ~0);
if (ret) {
NOUVEAU_ERR("Failed to launch grid !\n");
+ pipe_mutex_unlock(screen->base.push_mutex);
return;
}
@@ -498,4 +502,6 @@ nvc0_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_SUF);
nvc0->dirty_cp |= NVC0_NEW_CP_SURFACES;
nvc0->images_dirty[5] |= nvc0->images_valid[5];
+
+ pipe_mutex_unlock(screen->base.push_mutex);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
index c711cb07de..6bb94dcdaf 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.c
@@ -38,7 +38,9 @@ nvc0_flush(struct pipe_context *pipe,
if (fence)
nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence);
+ pipe_mutex_lock(screen->push_mutex);
PUSH_KICK(nvc0->base.pushbuf); /* fencing handled in kick_notify */
+ pipe_mutex_unlock(screen->push_mutex);
nouveau_context_update_frame_stats(&nvc0->base);
}
@@ -48,8 +50,10 @@ nvc0_texture_barrier(struct pipe_context *pipe)
{
struct nouveau_pushbuf *push = nvc0_context(pipe)->base.pushbuf;
+ pipe_mutex_lock(nvc0_context(pipe)->screen->base.push_mutex);
IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
IMMED_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 0);
+ pipe_mutex_unlock(nvc0_context(pipe)->screen->base.push_mutex);
}
static void
@@ -59,6 +63,8 @@ nvc0_memory_barrier(struct pipe_context *pipe, unsigned flags)
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
int i, s;
+ pipe_mutex_lock(nvc0_context(pipe)->screen->base.push_mutex);
+
if (flags & PIPE_BARRIER_MAPPED_BUFFER) {
for (i = 0; i < nvc0->num_vtxbufs; ++i) {
if (!nvc0->vtxbuf[i].buffer)
@@ -108,6 +114,8 @@ nvc0_memory_barrier(struct pipe_context *pipe, unsigned flags)
nvc0->cb_dirty = true;
if (flags & (PIPE_BARRIER_VERTEX_BUFFER | PIPE_BARRIER_INDEX_BUFFER))
nvc0->base.vbo_dirty = true;
+
+ pipe_mutex_unlock(nvc0_context(pipe)->screen->base.push_mutex);
}
static void
@@ -124,6 +132,7 @@ nvc0_emit_string_marker(struct pipe_context *pipe, const char *str, int len)
data_words = string_words;
else
data_words = string_words + !!(len & 3);
+ pipe_mutex_lock(nvc0_context(pipe)->screen->base.push_mutex);
BEGIN_NIC0(push, SUBC_3D(NV04_GRAPH_NOP), data_words);
if (string_words)
PUSH_DATAp(push, str, string_words);
@@ -132,6 +141,7 @@ nvc0_emit_string_marker(struct pipe_context *pipe, const char *str, int len)
memcpy(&data, &str[string_words * 4], len & 3);
PUSH_DATA (push, data);
}
+ pipe_mutex_unlock(nvc0_context(pipe)->screen->base.push_mutex);
}
static void
@@ -365,6 +375,8 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
return NULL;
pipe = &nvc0->base.pipe;
+ pipe_mutex_lock(screen->base.push_mutex);
+
if (!nvc0_blitctx_create(nvc0))
goto out_err;
@@ -468,9 +480,12 @@ nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
util_dynarray_init(&nvc0->global_residents);
+ pipe_mutex_unlock(screen->base.push_mutex);
+
return pipe;
out_err:
+ pipe_mutex_unlock(screen->base.push_mutex);
if (nvc0) {
if (nvc0->bufctx_3d)
nouveau_bufctx_del(&nvc0->bufctx_3d);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
index 37aecae904..973b3c7abc 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_context.h
@@ -299,6 +299,11 @@ uint32_t nvc0_program_symbol_offset(const struct nvc0_program *,
uint32_t label);
void nvc0_program_init_tcp_empty(struct nvc0_context *);
+/* nvc0_query.c */
+void nvc0_render_condition(struct pipe_context *pipe,
+ struct pipe_query *pq,
+ boolean condition, uint mode);
+
/* nvc0_shader_state.c */
void nvc0_vertprog_validate(struct nvc0_context *);
void nvc0_tctlprog_validate(struct nvc0_context *);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c
index 91fb72f90b..55d1dc18e4 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c
@@ -92,7 +92,7 @@ nvc0_get_query_result_resource(struct pipe_context *pipe,
index, resource, offset);
}
-static void
+void
nvc0_render_condition(struct pipe_context *pipe,
struct pipe_query *pq,
boolean condition, uint mode)
@@ -161,6 +161,16 @@ nvc0_render_condition(struct pipe_context *pipe,
PUSH_DATA (push, hq->bo->offset + hq->offset);
}
+static void
+nvc0_render_condition_locked(struct pipe_context *pipe,
+ struct pipe_query *pq,
+ boolean condition, uint mode)
+{
+ pipe_mutex_lock(nouveau_context(pipe)->screen->push_mutex);
+ nvc0_render_condition(pipe, pq, condition, mode);
+ pipe_mutex_unlock(nouveau_context(pipe)->screen->push_mutex);
+}
+
int
nvc0_screen_get_driver_query_info(struct pipe_screen *pscreen,
unsigned id,
@@ -272,6 +282,6 @@ nvc0_init_query_functions(struct nvc0_context *nvc0)
pipe->get_query_result = nvc0_get_query_result;
pipe->get_query_result_resource = nvc0_get_query_result_resource;
pipe->set_active_query_state = nvc0_set_active_query_state;
- pipe->render_condition = nvc0_render_condition;
+ pipe->render_condition = nvc0_render_condition_locked;
nvc0->cond_condmode = NVC0_3D_COND_MODE_ALWAYS;
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
index 4c34593ef9..4b51a67dac 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
@@ -48,9 +48,12 @@ nvc0_hw_query_allocate(struct nvc0_context *nvc0, struct nvc0_query *q,
if (hq->mm) {
if (hq->state == NVC0_HW_QUERY_STATE_READY)
nouveau_mm_free(hq->mm);
- else
+ else {
+ pipe_mutex_lock(screen->base.push_mutex);
nouveau_fence_work(screen->base.fence.current,
nouveau_mm_free_work, hq->mm);
+ pipe_mutex_unlock(screen->base.push_mutex);
+ }
}
}
if (size) {
@@ -154,6 +157,7 @@ nvc0_hw_begin_query(struct nvc0_context *nvc0, struct nvc0_query *q)
}
hq->sequence++;
+ pipe_mutex_lock(nvc0->screen->base.push_mutex);
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
@@ -198,6 +202,7 @@ nvc0_hw_begin_query(struct nvc0_context *nvc0, struct nvc0_query *q)
default:
break;
}
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
hq->state = NVC0_HW_QUERY_STATE_ACTIVE;
return ret;
}
@@ -221,6 +226,7 @@ nvc0_hw_end_query(struct nvc0_context *nvc0, struct nvc0_query *q)
}
hq->state = NVC0_HW_QUERY_STATE_ENDED;
+ pipe_mutex_lock(nvc0->screen->base.push_mutex);
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
case PIPE_QUERY_OCCLUSION_PREDICATE:
@@ -276,6 +282,7 @@ nvc0_hw_end_query(struct nvc0_context *nvc0, struct nvc0_query *q)
default:
break;
}
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
if (hq->is64bit)
nouveau_fence_ref(nvc0->screen->base.fence.current, &hq->fence);
}
@@ -298,16 +305,21 @@ nvc0_hw_get_query_result(struct nvc0_context *nvc0, struct nvc0_query *q,
nvc0_hw_query_update(nvc0->screen->base.client, q);
if (hq->state != NVC0_HW_QUERY_STATE_READY) {
+ pipe_mutex_lock(nvc0->screen->base.push_mutex);
if (!wait) {
if (hq->state != NVC0_HW_QUERY_STATE_FLUSHED) {
hq->state = NVC0_HW_QUERY_STATE_FLUSHED;
/* flush for silly apps that spin on GL_QUERY_RESULT_AVAILABLE */
PUSH_KICK(nvc0->base.pushbuf);
}
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return false;
}
- if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nvc0->screen->base.client))
+ if (nouveau_bo_wait(hq->bo, NOUVEAU_BO_RD, nvc0->screen->base.client)) {
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return false;
+ }
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
NOUVEAU_DRV_STAT(&nvc0->screen->base, query_sync_count, 1);
}
hq->state = NVC0_HW_QUERY_STATE_READY;
@@ -374,6 +386,8 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
assert(!hq->funcs || !hq->funcs->get_query_result);
+ pipe_mutex_lock(nvc0->screen->base.push_mutex);
+
if (index == -1) {
/* TODO: Use a macro to write the availability of the query */
if (hq->state != NVC0_HW_QUERY_STATE_READY)
@@ -382,6 +396,7 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
nvc0->base.push_cb(&nvc0->base, buf, offset,
result_type >= PIPE_QUERY_TYPE_I64 ? 2 : 1,
ready);
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return;
}
@@ -469,6 +484,8 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0,
4 | NVC0_IB_ENTRY_1_NO_PREFETCH);
}
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+
if (buf->mm) {
nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence);
nouveau_fence_ref(nvc0->screen->base.fence.current, &buf->fence_wr);
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
index d4721201bb..982042e30c 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
@@ -1662,6 +1662,7 @@ nve4_hw_sm_begin_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq)
return false;
}
+ pipe_mutex_lock(screen->base.push_mutex);
assert(cfg->num_counters <= 4);
PUSH_SPACE(push, 4 * 8 * + 6);
@@ -1710,6 +1711,7 @@ nve4_hw_sm_begin_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq)
BEGIN_NVC0(push, NVE4_CP(MP_PM_SET(c)), 1);
PUSH_DATA (push, 0);
}
+ pipe_mutex_unlock(screen->base.push_mutex);
return true;
}
@@ -1733,6 +1735,7 @@ nvc0_hw_sm_begin_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq)
return false;
}
+ pipe_mutex_lock(screen->base.push_mutex);
assert(cfg->num_counters <= 8);
PUSH_SPACE(push, 8 * 8 + 2);
@@ -1779,6 +1782,7 @@ nvc0_hw_sm_begin_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq)
BEGIN_NVC0(push, NVC0_CP(MP_PM_SET(c)), 1);
PUSH_DATA (push, 0);
}
+ pipe_mutex_unlock(screen->base.push_mutex);
return true;
}
@@ -1866,6 +1870,7 @@ nvc0_hw_sm_end_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq)
if (unlikely(!screen->pm.prog))
screen->pm.prog = nvc0_hw_sm_get_program(screen);
+ pipe_mutex_lock(screen->base.push_mutex);
/* disable all counting */
PUSH_SPACE(push, 8);
for (c = 0; c < 8; ++c)
@@ -1893,6 +1898,7 @@ nvc0_hw_sm_end_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq)
/* upload input data for the compute shader which reads MP counters */
nvc0_hw_sm_upload_input(nvc0, hq);
+ pipe_mutex_unlock(screen->base.push_mutex);
pipe->bind_compute_state(pipe, screen->pm.prog);
for (i = 0; i < 3; i++) {
@@ -1906,6 +1912,7 @@ nvc0_hw_sm_end_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq)
nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_QUERY);
+ pipe_mutex_lock(screen->base.push_mutex);
/* re-activate other counters */
PUSH_SPACE(push, 16);
mask = 0;
@@ -1930,6 +1937,7 @@ nvc0_hw_sm_end_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq)
PUSH_DATA (push, (cfg->ctr[i].func << 4) | cfg->ctr[i].mode);
}
}
+ pipe_mutex_unlock(screen->base.push_mutex);
}
static inline bool
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
index 2cac3c79e2..97d9f2658b 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
@@ -507,7 +507,9 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
* _current_ one, and remove both.
*/
nouveau_fence_ref(screen->base.fence.current, &current);
+ pipe_mutex_lock(screen->base.push_mutex);
nouveau_fence_wait(current, NULL);
+ pipe_mutex_unlock(screen->base.push_mutex);
nouveau_fence_ref(NULL, &current);
nouveau_fence_ref(NULL, &screen->base.fence.current);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
index 0d14058714..ee8c26dd28 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
@@ -206,11 +206,14 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
bool m2mf;
unsigned dst_layer = dstz, src_layer = src_box->z;
+ pipe_mutex_lock(nvc0->screen->base.push_mutex);
+
if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
nouveau_copy_buffer(&nvc0->base,
nv04_resource(dst), dstx,
nv04_resource(src), src_box->x, src_box->width);
NOUVEAU_DRV_STAT(&nvc0->screen->base, buf_copy_bytes, src_box->width);
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return;
}
NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_copy_count, 1);
@@ -251,6 +254,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
else
srect.base += src_mt->layer_stride;
}
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return;
}
@@ -273,6 +277,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe,
break;
}
nouveau_bufctx_reset(nvc0->bufctx, 0);
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
}
static void
@@ -291,8 +296,12 @@ nvc0_clear_render_target(struct pipe_context *pipe,
assert(dst->texture->target != PIPE_BUFFER);
- if (!PUSH_SPACE(push, 32 + sf->depth))
+ pipe_mutex_lock(nvc0->screen->base.push_mutex);
+
+ if (!PUSH_SPACE(push, 32 + sf->depth)) {
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return;
+ }
PUSH_REFN (push, res->bo, res->domain | NOUVEAU_BO_WR);
@@ -357,6 +366,8 @@ nvc0_clear_render_target(struct pipe_context *pipe,
IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);
nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER;
+
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
}
static void
@@ -542,8 +553,11 @@ nvc0_clear_buffer(struct pipe_context *pipe,
assert(size % data_size == 0);
+ pipe_mutex_lock(nvc0->screen->base.push_mutex);
+
if (data_size == 12) {
nvc0_clear_buffer_push(pipe, res, offset, size, data, data_size);
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return;
}
@@ -553,8 +567,10 @@ nvc0_clear_buffer(struct pipe_context *pipe,
nvc0_clear_buffer_push(pipe, res, offset, fixup_size, data, data_size);
offset += fixup_size;
size -= fixup_size;
- if (!size)
+ if (!size) {
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return;
+ }
}
elements = size / data_size;
@@ -564,8 +580,10 @@ nvc0_clear_buffer(struct pipe_context *pipe,
width &= ~0xff;
assert(width > 0);
- if (!PUSH_SPACE(push, 40))
+ if (!PUSH_SPACE(push, 40)) {
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return;
+ }
PUSH_REFN (push, buf->bo, buf->domain | NOUVEAU_BO_WR);
@@ -613,6 +631,8 @@ nvc0_clear_buffer(struct pipe_context *pipe,
}
nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER;
+
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
}
static void
@@ -635,8 +655,11 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
assert(dst->texture->target != PIPE_BUFFER);
- if (!PUSH_SPACE(push, 32 + sf->depth))
+ pipe_mutex_lock(nvc0->screen->base.push_mutex);
+ if (!PUSH_SPACE(push, 32 + sf->depth)) {
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return;
+ }
PUSH_REFN (push, mt->base.bo, mt->base.domain | NOUVEAU_BO_WR);
@@ -685,6 +708,8 @@ nvc0_clear_depth_stencil(struct pipe_context *pipe,
IMMED_NVC0(push, NVC0_3D(COND_MODE), nvc0->cond_condmode);
nvc0->dirty_3d |= NVC0_NEW_3D_FRAMEBUFFER;
+
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
}
void
@@ -698,9 +723,13 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
unsigned i, j, k;
uint32_t mode = 0;
+ pipe_mutex_lock(nvc0->screen->base.push_mutex);
+
/* don't need NEW_BLEND, COLOR_MASK doesn't affect CLEAR_BUFFERS */
- if (!nvc0_state_validate_3d(nvc0, NVC0_NEW_3D_FRAMEBUFFER))
+ if (!nvc0_state_validate_3d(nvc0, NVC0_NEW_3D_FRAMEBUFFER)) {
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
return;
+ }
if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
BEGIN_NVC0(push, NVC0_3D(CLEAR_COLOR(0)), 4);
@@ -759,6 +788,8 @@ nvc0_clear(struct pipe_context *pipe, unsigned buffers,
(j << NVC0_3D_CLEAR_BUFFERS_LAYER__SHIFT));
}
}
+
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
}
@@ -1163,8 +1194,8 @@ nvc0_blitctx_post_blit(struct nvc0_blitctx *blit)
nvc0->samplers_dirty[4] |= 3;
if (nvc0->cond_query && !blit->render_condition_enable)
- nvc0->base.pipe.render_condition(&nvc0->base.pipe, nvc0->cond_query,
- nvc0->cond_cond, nvc0->cond_mode);
+ nvc0_render_condition(&nvc0->base.pipe, nvc0->cond_query,
+ nvc0->cond_cond, nvc0->cond_mode);
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_VTX_TMP);
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_FB);
@@ -1626,6 +1657,8 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
if (info->num_window_rectangles > 0 || info->window_rectangle_include)
eng3d = true;
+ pipe_mutex_lock(nvc0->screen->base.push_mutex);
+
if (nvc0->screen->num_occlusion_queries_active)
IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 0);
@@ -1637,6 +1670,8 @@ nvc0_blit(struct pipe_context *pipe, const struct pipe_blit_info *info)
if (nvc0->screen->num_occlusion_queries_active)
IMMED_NVC0(push, NVC0_3D(SAMPLECNT_ENABLE), 1);
+ pipe_mutex_unlock(nvc0->screen->base.push_mutex);
+
NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_blit_count, 1);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
index 14fb53cb8f..6cb39a9c30 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
@@ -342,16 +342,18 @@ nvc0_mt_sync(struct nvc0_context *nvc0, struct nv50_miptree *mt, unsigned usage)
return !mt->base.fence_wr || nouveau_fence_wait(mt->base.fence_wr, &nvc0->base.debug);
}
-void *
-nvc0_miptree_transfer_map(struct pipe_context *pctx,
- struct pipe_resource *res,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- struct pipe_transfer **ptransfer)
+static void *
+nvc0_miptree_transfer_map_unlocked(
+ struct pipe_context *pctx,
+ struct pipe_resource *res,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ struct pipe_transfer **ptransfer)
{
struct nvc0_context *nvc0 = nvc0_context(pctx);
- struct nouveau_device *dev = nvc0->screen->base.device;
+ struct nvc0_screen *screen = nvc0->screen;
+ struct nouveau_device *dev = screen->base.device;
struct nv50_miptree *mt = nv50_miptree(res);
struct nvc0_transfer *tx;
uint32_t size;
@@ -465,9 +467,29 @@ nvc0_miptree_transfer_map(struct pipe_context *pctx,
return tx->rect[1].bo->map;
}
-void
-nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
- struct pipe_transfer *transfer)
+void *
+nvc0_miptree_transfer_map(
+ struct pipe_context *pctx,
+ struct pipe_resource *res,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ struct pipe_transfer **ptransfer)
+{
+ struct nvc0_context *nvc0 = nvc0_context(pctx);
+ struct nvc0_screen *screen = nvc0->screen;
+
+ pipe_mutex_lock(screen->base.push_mutex);
+ void *ret = nvc0_miptree_transfer_map_unlocked(
+ pctx, res, level, usage, box, ptransfer);
+ pipe_mutex_unlock(screen->base.push_mutex);
+
+ return ret;
+}
+
+static void
+nvc0_miptree_transfer_unmap_unlocked(struct pipe_context *pctx,
+ struct pipe_transfer *transfer)
{
struct nvc0_context *nvc0 = nvc0_context(pctx);
struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
@@ -507,6 +529,18 @@ nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
FREE(tx);
}
+void
+nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
+ struct pipe_transfer *transfer)
+{
+ struct nvc0_context *nvc0 = nvc0_context(pctx);
+ struct nvc0_screen *screen = nvc0->screen;
+
+ pipe_mutex_lock(screen->base.push_mutex);
+ nvc0_miptree_transfer_unmap_unlocked(pctx, transfer);
+ pipe_mutex_unlock(screen->base.push_mutex);
+}
+
/* This happens rather often with DTD9/st. */
static void
nvc0_cb_push(struct nouveau_context *nv,
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
index 69ca091c4c..39bafa6447 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
@@ -940,6 +940,8 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
struct nvc0_screen *screen = nvc0->screen;
int s;
+ pipe_mutex_lock(screen->base.push_mutex);
+
/* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
nvc0->vb_elt_first = info->min_index + info->index_bias;
nvc0->vb_elt_limit = info->max_index - info->min_index;
@@ -1033,6 +1035,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nvc0_push_vbo(nvc0, info);
push->kick_notify = nvc0_default_kick_notify;
nouveau_pushbuf_bufctx(push, NULL);
+ pipe_mutex_unlock(screen->base.push_mutex);
return;
}
@@ -1085,4 +1088,5 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
nvc0_release_user_vbufs(nvc0);
nouveau_pushbuf_bufctx(push, NULL);
+ pipe_mutex_unlock(screen->base.push_mutex);
}
diff --git a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
index d661c000b3..43de892bf9 100644
--- a/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
+++ b/src/gallium/drivers/nouveau/nvc0/nve4_compute.c
@@ -604,12 +604,15 @@ void
nve4_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info)
{
struct nvc0_context *nvc0 = nvc0_context(pipe);
+ struct nvc0_screen *screen = nvc0->screen;
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
struct nve4_cp_launch_desc *desc;
uint64_t desc_gpuaddr;
struct nouveau_bo *desc_bo;
int ret;
+ pipe_mutex_lock(screen->base.push_mutex);
+
desc = nve4_compute_alloc_launch_desc(&nvc0->base, &desc_bo, &desc_gpuaddr);
if (!desc) {
ret = -1;
@@ -690,6 +693,7 @@ out:
NOUVEAU_ERR("Failed to launch grid !\n");
nouveau_scratch_done(&nvc0->base);
nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_DESC);
+ pipe_mutex_unlock(screen->base.push_mutex);
}
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
index c7a08cc72c..9d679ebfe3 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
@@ -22,6 +22,7 @@
*/
#include "si_shader_internal.h"
+#include "radeon_llvm_init.h"
#include "radeon/radeon_elf_util.h"
#include "gallivm/lp_bld_const.h"
@@ -119,18 +120,10 @@ void si_llvm_shader_type(LLVMValueRef F, unsigned type)
static void init_amdgpu_target()
{
gallivm_init_llvm_targets();
-#if HAVE_LLVM < 0x0307
- LLVMInitializeR600TargetInfo();
- LLVMInitializeR600Target();
- LLVMInitializeR600TargetMC();
- LLVMInitializeR600AsmPrinter();
-#else
LLVMInitializeAMDGPUTargetInfo();
LLVMInitializeAMDGPUTarget();
LLVMInitializeAMDGPUTargetMC();
LLVMInitializeAMDGPUAsmPrinter();
-
-#endif
}
static once_flag init_amdgpu_target_once_flag = ONCE_FLAG_INIT;
diff --git a/src/gallium/drivers/svga/svga_format.c b/src/gallium/drivers/svga/svga_format.c
index e307674750..a1c95141b5 100644
--- a/src/gallium/drivers/svga/svga_format.c
+++ b/src/gallium/drivers/svga/svga_format.c
@@ -393,8 +393,14 @@ svga_translate_format(const struct svga_screen *ss,
}
switch(format) {
+#ifdef PIPE_OS_ANDROID
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ return SVGA3D_A8R8G8B8;
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+#else
case PIPE_FORMAT_B8G8R8A8_UNORM:
return SVGA3D_A8R8G8B8;
+#endif
case PIPE_FORMAT_B8G8R8X8_UNORM:
return SVGA3D_X8R8G8B8;
diff --git a/src/gallium/include/state_tracker/drm_driver.h b/src/gallium/include/state_tracker/drm_driver.h
index c80fb09dbc..b8dfd2310d 100644
--- a/src/gallium/include/state_tracker/drm_driver.h
+++ b/src/gallium/include/state_tracker/drm_driver.h
@@ -11,6 +11,7 @@ struct pipe_resource;
#define DRM_API_HANDLE_TYPE_SHARED 0
#define DRM_API_HANDLE_TYPE_KMS 1
#define DRM_API_HANDLE_TYPE_FD 2
+#define DRM_API_HANDLE_TYPE_BUFFER 3
/**
@@ -20,11 +21,18 @@ struct winsys_handle
{
/**
* Input for texture_from_handle, valid values are
- * DRM_API_HANDLE_TYPE_SHARED or DRM_API_HANDLE_TYPE_FD.
+ * DRM_API_HANDLE_TYPE_SHARED or DRM_API_HANDLE_TYPE_FD or DRM_API_HANDLE_TYPE_BUFFER.
* Input to texture_get_handle,
* to select handle for kms, flink, or prime.
*/
unsigned type;
+
+ /**
+ * Input to texture_from_handle.
+ * Output for texture_get_handle.
+ */
+ void* externalBuffer;
+
/**
* Input for texture_get_handle, allows to export the offset
* of a specific layer of an array texture.
diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
index 9ec069b306..9b51936b5b 100644
--- a/src/gallium/state_trackers/dri/dri2.c
+++ b/src/gallium/state_trackers/dri/dri2.c
@@ -765,7 +765,7 @@ dri2_update_tex_buffer(struct dri_drawable *drawable,
/* no-op */
}
-static __DRIimage *
+__DRIimage *
dri2_lookup_egl_image(struct dri_screen *screen, void *handle)
{
const __DRIimageLookupExtension *loader = screen->sPriv->dri2.image;
@@ -780,7 +780,7 @@ dri2_lookup_egl_image(struct dri_screen *screen, void *handle)
return img;
}
-static __DRIimage *
+__DRIimage *
dri2_create_image_from_winsys(__DRIscreen *_screen,
int width, int height, int format,
int num_handles, struct winsys_handle *whandle,
@@ -1173,7 +1173,7 @@ dri2_from_planar(__DRIimage *image, int plane, void *loaderPrivate)
return img;
}
-static __DRIimage *
+__DRIimage *
dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
int depth, int level, unsigned *error,
void *loaderPrivate)
@@ -1374,7 +1374,7 @@ dri2_unmap_image(__DRIcontext *context, __DRIimage *image, void *data)
pipe_transfer_unmap(pipe, (struct pipe_transfer *)data);
}
-static void
+void
dri2_destroy_image(__DRIimage *img)
{
pipe_resource_reference(&img->texture, NULL);
@@ -1551,7 +1551,7 @@ dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags)
/* AFAIK, no driver currently supports parallel context execution. */
}
-static __DRI2fenceExtension dri2FenceExtension = {
+__DRI2fenceExtension dri2FenceExtension = {
.base = { __DRI2_FENCE, 1 },
.create_fence = dri2_create_fence,
@@ -1881,9 +1881,7 @@ dri2_init_screen(__DRIscreen * sPriv)
if (screen->fd < 0 || (fd = fcntl(screen->fd, F_DUPFD_CLOEXEC, 3)) < 0)
goto free_screen;
- if (pipe_loader_drm_probe_fd(&screen->dev, fd))
- pscreen = pipe_loader_create_screen(screen->dev);
-
+ pscreen = load_pipe_screen(&screen->dev, screen->fd);
if (!pscreen)
goto release_pipe;
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index edcd0e6843..474c3313bc 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -176,8 +176,6 @@ dri_destroy_buffer(__DRIdrawable * dPriv)
pipe_resource_reference(&drawable->msaa_textures[i], NULL);
swap_fences_unref(drawable);
-
- FREE(drawable);
}
/**
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index aa0ad09ce5..a950f5241d 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -143,7 +143,7 @@ dri_fill_in_modes(struct dri_screen *screen)
stencil_bits_array[0] = 0;
depth_buffer_factor = 1;
}
-
+
msaa_samples_max = (screen->st_api->feature_mask & ST_API_FEATURE_MS_VISUALS_MASK)
? MSAA_VISUAL_MAX_SAMPLES : 1;
diff --git a/src/gallium/state_trackers/dri/drisw.c b/src/gallium/state_trackers/dri/drisw.c
index b85a73c57d..3761dad24e 100644
--- a/src/gallium/state_trackers/dri/drisw.c
+++ b/src/gallium/state_trackers/dri/drisw.c
@@ -361,14 +361,66 @@ drisw_update_tex_buffer(struct dri_drawable *drawable,
pipe_transfer_unmap(pipe, transfer);
}
+extern __DRIimage *
+dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
+ int depth, int level, unsigned *error,
+ void *loaderPrivate);
+
+extern __DRIimage *dri2_lookup_egl_image(struct dri_screen *screen, void *handle);
+
+extern __DRIimage *dri2_create_image_from_winsys(__DRIscreen *_screen,
+ int width, int height, int format,
+ int num_handles, struct winsys_handle *whandle,
+ void *loaderPrivate);
+
+extern void dri2_destroy_image(__DRIimage *img);
+
+extern __DRI2fenceExtension dri2FenceExtension;
+
+static GLboolean
+drisw_query_image(__DRIimage *image, int attrib, int *value)
+{
+ switch (attrib) {
+ case __DRI_IMAGE_ATTRIB_FORMAT:
+ *value = image->dri_format;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_WIDTH:
+ *value = image->texture->width0;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_HEIGHT:
+ *value = image->texture->height0;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_COMPONENTS:
+ if (image->dri_components == 0)
+ return GL_FALSE;
+ *value = image->dri_components;
+ return GL_TRUE;
+ case __DRI_IMAGE_ATTRIB_NUM_PLANES:
+ *value = 1;
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
/*
* Backend function for init_screen.
*/
+static const __DRIimageExtension driswImageExtension = {
+ .base = { __DRI_IMAGE, 11 },
+
+ .createImageFromTexture = dri2_create_from_texture,
+ .destroyImage = dri2_destroy_image,
+ .queryImage = drisw_query_image,
+};
+
static const __DRIextension *drisw_screen_extensions[] = {
&driTexBufferExtension.base,
&dri2RendererQueryExtension.base,
&dri2ConfigQueryExtension.base,
+ &driswImageExtension.base,
+ &dri2FenceExtension.base,
NULL
};
@@ -407,6 +459,9 @@ drisw_init_screen(__DRIscreen * sPriv)
if (!configs)
goto fail;
+ screen->lookup_egl_image = dri2_lookup_egl_image;
+ driSWRastExtension.createImageFromWinsys = dri2_create_image_from_winsys;
+
return configs;
fail:
dri_destroy_screen_helper(screen);
diff --git a/src/gallium/targets/dri/Android.mk b/src/gallium/targets/dri/Android.mk
index a30bcf077e..18aefe34af 100644
--- a/src/gallium/targets/dri/Android.mk
+++ b/src/gallium/targets/dri/Android.mk
@@ -27,6 +27,12 @@ include $(CLEAR_VARS)
LOCAL_MODULE := gallium_dri
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+ $(MESA_TOP)/src \
+ $(MESA_TOP)/include \
+ $(MESA_TOP)/src/gallium/auxiliary \
+ $(MESA_TOP)/src/gallium/include
+
ifeq ($(MESA_LOLLIPOP_BUILD),true)
LOCAL_MODULE_RELATIVE_PATH := $(MESA_DRI_MODULE_REL_PATH)
else
@@ -40,8 +46,10 @@ LOCAL_CFLAGS :=
LOCAL_SHARED_LIBRARIES := \
libdl \
+ liblog \
libglapi \
libexpat \
+ libhardware \
ifneq ($(filter freedreno,$(MESA_GPU_DRIVERS)),)
LOCAL_CFLAGS += -DGALLIUM_FREEDRENO
@@ -81,8 +89,9 @@ gallium_DRIVERS += libmesa_winsys_radeon libmesa_pipe_radeon libmesa_amdgpu_addr
LOCAL_SHARED_LIBRARIES += libdrm_radeon
endif
ifneq ($(filter swrast,$(MESA_GPU_DRIVERS)),)
-gallium_DRIVERS += libmesa_pipe_softpipe libmesa_winsys_sw_dri
-LOCAL_CFLAGS += -DGALLIUM_SOFTPIPE
+gallium_DRIVERS += libmesa_pipe_llvmpipe libmesa_pipe_softpipe libmesa_winsys_sw_dri
+LOCAL_CFLAGS += -DGALLIUM_LLVMPIPE -DGALLIUM_SOFTPIPE
+LOCAL_SHARED_LIBRARIES += libLLVM
endif
ifneq ($(filter vc4,$(MESA_GPU_DRIVERS)),)
LOCAL_CFLAGS += -DGALLIUM_VC4
@@ -114,17 +123,13 @@ LOCAL_WHOLE_STATIC_LIBRARIES := \
libmesa_util \
libmesa_loader \
-LOCAL_STATIC_LIBRARIES :=
ifeq ($(MESA_ENABLE_LLVM),true)
-LOCAL_STATIC_LIBRARIES += \
- libLLVMR600CodeGen \
- libLLVMR600Desc \
- libLLVMR600Info \
- libLLVMR600AsmPrinter \
- libelf
+LOCAL_STATIC_LIBRARIES := libelf libz
LOCAL_LDLIBS += $(if $(filter true,$(MESA_LOLLIPOP_BUILD)),-lgcc)
endif
+LOCAL_ADDITION_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
include $(GALLIUM_COMMON_MK)
include $(BUILD_SHARED_LIBRARY)
diff --git a/src/gallium/targets/dri/dri.sym b/src/gallium/targets/dri/dri.sym
index 1fdf18beee..1d86c88029 100644
--- a/src/gallium/targets/dri/dri.sym
+++ b/src/gallium/targets/dri/dri.sym
@@ -2,6 +2,7 @@
global:
__driDriverExtensions;
__driDriverGetExtensions*;
+ load_pipe_screen;
nouveau_drm_screen_create;
radeon_drm_winsys_create;
amdgpu_winsys_create;
diff --git a/src/gallium/winsys/sw/dri/Android.mk b/src/gallium/winsys/sw/dri/Android.mk
index 72fb920ff1..d25e677dd6 100644
--- a/src/gallium/winsys/sw/dri/Android.mk
+++ b/src/gallium/winsys/sw/dri/Android.mk
@@ -29,6 +29,8 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(C_SOURCES)
+LOCAL_CFLAGS += -DHAVE_ANDROID_PLATFORM
+
LOCAL_MODULE := libmesa_winsys_sw_dri
include $(GALLIUM_COMMON_MK)
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
index 94d5092405..ea1fe58496 100644
--- a/src/gallium/winsys/sw/dri/dri_sw_winsys.c
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
@@ -34,8 +34,14 @@
#include "util/u_memory.h"
#include "state_tracker/sw_winsys.h"
+#include "state_tracker/drm_driver.h"
#include "dri_sw_winsys.h"
+#ifdef HAVE_ANDROID_PLATFORM
+#include <system/graphics.h>
+#include <system/window.h>
+#include <hardware/gralloc.h>
+#endif
struct dri_sw_displaytarget
{
@@ -45,11 +51,31 @@ struct dri_sw_displaytarget
unsigned stride;
unsigned map_flags;
+#ifdef HAVE_ANDROID_PLATFORM
+ struct ANativeWindowBuffer *androidBuffer;
+#endif
void *data;
void *mapped;
const void *front_private;
};
+#ifdef HAVE_ANDROID_PLATFORM
+const struct gralloc_module_t* get_gralloc()
+{
+ static const struct gralloc_module_t* gr_module = NULL;
+ const hw_module_t *mod;
+ int err;
+
+ if (!gr_module) {
+ err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod);
+ if (!err) {
+ gr_module = (gralloc_module_t *) mod;
+ }
+ }
+ return gr_module;
+}
+#endif
+
struct dri_sw_winsys
{
struct sw_winsys base;
@@ -125,6 +151,12 @@ dri_sw_displaytarget_destroy(struct sw_winsys *ws,
{
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+#ifdef HAVE_ANDROID_PLATFORM
+ if (dri_sw_dt->androidBuffer) {
+ dri_sw_dt->androidBuffer->common.decRef(&dri_sw_dt->androidBuffer->common);
+ }
+#endif
+
align_free(dri_sw_dt->data);
FREE(dri_sw_dt);
@@ -136,6 +168,17 @@ dri_sw_displaytarget_map(struct sw_winsys *ws,
unsigned flags)
{
struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+#ifdef HAVE_ANDROID_PLATFORM
+ if (dri_sw_dt->androidBuffer) {
+ if (!get_gralloc()->lock(get_gralloc(), dri_sw_dt->androidBuffer->handle,
+ GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ 0, 0, dri_sw_dt->androidBuffer->width, dri_sw_dt->androidBuffer->height,
+ (void**)&dri_sw_dt->mapped)) {
+ dri_sw_dt->map_flags = flags;
+ return dri_sw_dt->mapped;
+ }
+ }
+#endif
dri_sw_dt->mapped = dri_sw_dt->data;
if (dri_sw_dt->front_private && (flags & PIPE_TRANSFER_READ)) {
@@ -156,6 +199,11 @@ dri_sw_displaytarget_unmap(struct sw_winsys *ws,
dri_sw_ws->lf->put_image2((void *)dri_sw_dt->front_private, dri_sw_dt->data, 0, 0, dri_sw_dt->width, dri_sw_dt->height, dri_sw_dt->stride);
}
dri_sw_dt->map_flags = 0;
+#ifdef HAVE_ANDROID_PLATFORM
+ if (dri_sw_dt->androidBuffer) {
+ get_gralloc()->unlock(get_gralloc(), dri_sw_dt->androidBuffer->handle);
+ }
+#endif
dri_sw_dt->mapped = NULL;
}
@@ -165,6 +213,22 @@ dri_sw_displaytarget_from_handle(struct sw_winsys *winsys,
struct winsys_handle *whandle,
unsigned *stride)
{
+#ifdef HAVE_ANDROID_PLATFORM
+ struct dri_sw_displaytarget *dri_sw_dt;
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_BUFFER) {
+ dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget);
+ dri_sw_dt->width = templ->width0;
+ dri_sw_dt->height = templ->height0;
+ dri_sw_dt->androidBuffer = whandle->externalBuffer;
+ dri_sw_dt->stride = whandle->stride;
+
+ dri_sw_dt->androidBuffer->common.incRef(&dri_sw_dt->androidBuffer->common);
+ *stride = dri_sw_dt->stride;
+
+ return dri_sw_dt;
+ }
+#endif
assert(0);
return NULL;
}
diff --git a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
index 86e0470e68..f73d2a96dd 100644
--- a/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
+++ b/src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
@@ -585,6 +585,7 @@ static void virgl_drm_cmd_buf_destroy(struct virgl_cmd_buf *_cbuf)
static boolean virgl_drm_lookup_res(struct virgl_drm_cmd_buf *cbuf,
struct virgl_hw_res *res)
{
+ if (!res) return false;
unsigned hash = res->res_handle & (sizeof(cbuf->is_handle_added)-1);
int i;
@@ -607,6 +608,7 @@ static void virgl_drm_add_res(struct virgl_drm_winsys *qdws,
struct virgl_drm_cmd_buf *cbuf,
struct virgl_hw_res *res)
{
+ if (!res) return;
unsigned hash = res->res_handle & (sizeof(cbuf->is_handle_added)-1);
if (cbuf->cres > cbuf->nres) {
diff --git a/src/intel/Android.genxml.mk b/src/intel/Android.genxml.mk
index 79de784380..349e64fcdd 100644
--- a/src/intel/Android.genxml.mk
+++ b/src/intel/Android.genxml.mk
@@ -41,9 +41,10 @@ $(intermediates)/dummy.c:
$(hide) touch $@
# This is the list of auto-generated files headers
-LOCAL_GENERATED_SOURCES += $(addprefix $(intermediates)/, $(GENXML_GENERATED_FILES))
+LOCAL_GENERATED_SOURCES += $(addprefix $(intermediates)/, $(GENXML_GENERATED_FILES)) \
+ $(addprefix $(intermediates)/, $(AUBINATOR_GENERATED_FILES))
-define header-gen
+define pack-header-gen
@mkdir -p $(dir $@)
@echo "Gen Header: $(PRIVATE_MODULE) <= $(notdir $(@))"
$(hide) $(PRIVATE_SCRIPT) $(PRIVATE_XML) > $@
@@ -52,42 +53,66 @@ endef
$(intermediates)/genxml/gen4_pack.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/genxml/gen_pack_header.py
$(intermediates)/genxml/gen4_pack.h: PRIVATE_XML := $(LOCAL_PATH)/genxml/gen4.xml
$(intermediates)/genxml/gen4_pack.h: $(LOCAL_PATH)/genxml/gen4.xml $(LOCAL_PATH)/genxml/gen_pack_header.py
- $(call header-gen)
+ $(call pack-header-gen)
$(intermediates)/genxml/gen45_pack.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/genxml/gen_pack_header.py
$(intermediates)/genxml/gen45_pack.h: PRIVATE_XML := $(LOCAL_PATH)/genxml/gen45.xml
$(intermediates)/genxml/gen45_pack.h: $(LOCAL_PATH)/genxml/gen45.xml $(LOCAL_PATH)/genxml/gen_pack_header.py
- $(call header-gen)
+ $(call pack-header-gen)
$(intermediates)/genxml/gen5_pack.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/genxml/gen_pack_header.py
$(intermediates)/genxml/gen5_pack.h: PRIVATE_XML := $(LOCAL_PATH)/genxml/gen5.xml
$(intermediates)/genxml/gen5_pack.h: $(LOCAL_PATH)/genxml/gen5.xml $(LOCAL_PATH)/genxml/gen_pack_header.py
- $(call header-gen)
+ $(call pack-header-gen)
$(intermediates)/genxml/gen6_pack.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/genxml/gen_pack_header.py
$(intermediates)/genxml/gen6_pack.h: PRIVATE_XML := $(LOCAL_PATH)/genxml/gen6.xml
$(intermediates)/genxml/gen6_pack.h: $(LOCAL_PATH)/genxml/gen6.xml $(LOCAL_PATH)/genxml/gen_pack_header.py
- $(call header-gen)
+ $(call pack-header-gen)
$(intermediates)/genxml/gen7_pack.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/genxml/gen_pack_header.py
$(intermediates)/genxml/gen7_pack.h: PRIVATE_XML := $(LOCAL_PATH)/genxml/gen7.xml
$(intermediates)/genxml/gen7_pack.h: $(LOCAL_PATH)/genxml/gen7.xml $(LOCAL_PATH)/genxml/gen_pack_header.py
- $(call header-gen)
+ $(call pack-header-gen)
$(intermediates)/genxml/gen75_pack.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/genxml/gen_pack_header.py
$(intermediates)/genxml/gen75_pack.h: PRIVATE_XML := $(LOCAL_PATH)/genxml/gen75.xml
$(intermediates)/genxml/gen75_pack.h: $(LOCAL_PATH)/genxml/gen75.xml $(LOCAL_PATH)/genxml/gen_pack_header.py
- $(call header-gen)
+ $(call pack-header-gen)
$(intermediates)/genxml/gen8_pack.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/genxml/gen_pack_header.py
$(intermediates)/genxml/gen8_pack.h: PRIVATE_XML := $(LOCAL_PATH)/genxml/gen8.xml
$(intermediates)/genxml/gen8_pack.h: $(LOCAL_PATH)/genxml/gen8.xml $(LOCAL_PATH)/genxml/gen_pack_header.py
- $(call header-gen)
+ $(call pack-header-gen)
$(intermediates)/genxml/gen9_pack.h: PRIVATE_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/genxml/gen_pack_header.py
$(intermediates)/genxml/gen9_pack.h: PRIVATE_XML := $(LOCAL_PATH)/genxml/gen9.xml
$(intermediates)/genxml/gen9_pack.h: $(LOCAL_PATH)/genxml/gen9.xml $(LOCAL_PATH)/genxml/gen_pack_header.py
- $(call header-gen)
+ $(call pack-header-gen)
+
+define xml-header-gen
+ @mkdir -p $(dir $@)
+ @echo "Gen Header: $(PRIVATE_MODULE) <= $(notdir $(@))"
+ $(hide) echo -n "static const uint8_t " > $@; \
+ sed -e 's,_xml.h,,' <<< "`basename $@`_xml[] = {" >> $@; \
+ cat $< | xxd -i >> $@; \
+ echo "};" >> $@
+endef
+
+$(intermediates)/genxml/gen6_xml.h: $(LOCAL_PATH)/genxml/gen6.xml
+ $(call xml-header-gen)
+
+$(intermediates)/genxml/gen7_xml.h: $(LOCAL_PATH)/genxml/gen7.xml
+ $(call xml-header-gen)
+
+$(intermediates)/genxml/gen75_xml.h: $(LOCAL_PATH)/genxml/gen75.xml
+ $(call xml-header-gen)
+
+$(intermediates)/genxml/gen8_xml.h: $(LOCAL_PATH)/genxml/gen8.xml
+ $(call xml-header-gen)
+
+$(intermediates)/genxml/gen9_xml.h: $(LOCAL_PATH)/genxml/gen9.xml
+ $(call xml-header-gen)
LOCAL_EXPORT_C_INCLUDE_DIRS := \
$(MESA_TOP)/src/intel \
diff --git a/src/mapi/Android.mk b/src/mapi/Android.mk
index 44452181ec..b654c25186 100644
--- a/src/mapi/Android.mk
+++ b/src/mapi/Android.mk
@@ -57,6 +57,9 @@ intermediates := $(call local-generated-sources-dir)
abi_header := $(intermediates)/$(abi_header)
LOCAL_GENERATED_SOURCES := $(abi_header)
+# workaround build warning
+LOCAL_LDFLAGS_x86 += -Wl,--no-warn-shared-textrel
+
$(abi_header): PRIVATE_PRINTER := shared-glapi
mapi_abi_headers += $(abi_header)
diff --git a/src/mesa/Android.gen.mk b/src/mesa/Android.gen.mk
index a985f0a64b..aaa2de94a9 100644
--- a/src/mesa/Android.gen.mk
+++ b/src/mesa/Android.gen.mk
@@ -45,10 +45,11 @@ LOCAL_SRC_FILES := $(filter-out $(sources), $(LOCAL_SRC_FILES))
LOCAL_C_INCLUDES += $(intermediates)/main
ifeq ($(strip $(MESA_ENABLE_ASM)),true)
-ifeq ($(TARGET_ARCH),x86)
-sources += x86/matypes.h
-LOCAL_C_INCLUDES += $(intermediates)/x86
-endif
+LOCAL_GENERATED_SOURCES_x86 += $(addprefix $(intermediates)/, x86/matypes.h)
+LOCAL_GENERATED_SOURCES_x86_64 += $(addprefix $(intermediates)/, x86_64/matypes.h)
+
+LOCAL_C_INCLUDES_x86 += $(intermediates)/x86
+LOCAL_C_INCLUDES_x86_64 += $(intermediates)/x86_64
endif
sources += main/git_sha1.h
@@ -69,7 +70,7 @@ define es-gen
$(hide) $(PRIVATE_SCRIPT) $(1) $(PRIVATE_XML) > $@
endef
-$(intermediates)/main/git_sha1.h:
+$(intermediates)/main/git_sha1.h: $(wildcard $(MESA_TOP)/.git/ORIG_HEAD)
@mkdir -p $(dir $@)
@echo "GIT-SHA1: $(PRIVATE_MODULE) <= git"
$(hide) touch $@
@@ -79,12 +80,22 @@ $(intermediates)/main/git_sha1.h:
> $@; \
fi
-matypes_deps := \
- $(BUILD_OUT_EXECUTABLES)/mesa_gen_matypes$(BUILD_EXECUTABLE_SUFFIX) \
+matypes_deps32 := \
+ $(BUILD_OUT_EXECUTABLES)/mesa_gen_matypes32$(BUILD_EXECUTABLE_SUFFIX) \
+ $(LOCAL_PATH)/main/mtypes.h \
+ $(LOCAL_PATH)/tnl/t_context.h
+
+matypes_deps64 := \
+ $(BUILD_OUT_EXECUTABLES)/mesa_gen_matypes64$(BUILD_EXECUTABLE_SUFFIX) \
$(LOCAL_PATH)/main/mtypes.h \
$(LOCAL_PATH)/tnl/t_context.h
-$(intermediates)/x86/matypes.h: $(matypes_deps)
+$(intermediates)/x86/matypes.h: $(matypes_deps32)
+ @mkdir -p $(dir $@)
+ @echo "MATYPES: $(PRIVATE_MODULE) <= $(notdir $@)"
+ $(hide) $< > $@
+
+$(intermediates)/x86_64/matypes.h: $(matypes_deps64)
@mkdir -p $(dir $@)
@echo "MATYPES: $(PRIVATE_MODULE) <= $(notdir $@)"
$(hide) $< > $@
diff --git a/src/mesa/Android.libmesa_dricore.mk b/src/mesa/Android.libmesa_dricore.mk
index 86196ceb36..8de90b8b83 100644
--- a/src/mesa/Android.libmesa_dricore.mk
+++ b/src/mesa/Android.libmesa_dricore.mk
@@ -31,6 +31,7 @@ LOCAL_PATH := $(call my-dir)
# Import the following variables:
# MESA_FILES
# X86_FILES
+# X86_64_FILES
include $(LOCAL_PATH)/Makefile.sources
include $(CLEAR_VARS)
@@ -42,19 +43,10 @@ LOCAL_SRC_FILES := \
$(MESA_FILES)
ifeq ($(strip $(MESA_ENABLE_ASM)),true)
-ifeq ($(TARGET_ARCH),x86)
- LOCAL_SRC_FILES += $(X86_FILES)
-endif # x86
+ LOCAL_SRC_FILES_x86 += $(X86_FILES)
+ LOCAL_SRC_FILES_x86_64 += $(X86_64_FILES)
endif # MESA_ENABLE_ASM
-ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
-LOCAL_WHOLE_STATIC_LIBRARIES := \
- libmesa_sse41
-LOCAL_CFLAGS := \
- -msse4.1 \
- -DUSE_SSE41
-endif
-
LOCAL_C_INCLUDES := \
$(MESA_TOP)/src/mapi \
$(MESA_TOP)/src/mesa/main \
@@ -69,6 +61,12 @@ LOCAL_GENERATED_SOURCES += \
LOCAL_WHOLE_STATIC_LIBRARIES += \
libmesa_program
+LOCAL_WHOLE_STATIC_LIBRARIES_x86 += \
+ libmesa_sse41 \
+
+LOCAL_WHOLE_STATIC_LIBRARIES_x86_64 += \
+ libmesa_sse41 \
+
include $(LOCAL_PATH)/Android.gen.mk
include $(MESA_COMMON_MK)
include $(BUILD_STATIC_LIBRARY)
diff --git a/src/mesa/Android.libmesa_sse41.mk b/src/mesa/Android.libmesa_sse41.mk
index 8562da6019..3668785fe5 100644
--- a/src/mesa/Android.libmesa_sse41.mk
+++ b/src/mesa/Android.libmesa_sse41.mk
@@ -20,7 +20,7 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
-ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
+ifneq ($(filter x86 x86_64,$(TARGET_ARCH)),)
LOCAL_PATH := $(call my-dir)
@@ -33,6 +33,9 @@ LOCAL_MODULE := libmesa_sse41
LOCAL_SRC_FILES += \
$(X86_SSE41_FILES)
+LOCAL_CFLAGS += \
+ -msse4.1 \
+
LOCAL_C_INCLUDES := \
$(MESA_TOP)/src/mapi \
$(MESA_TOP)/src/gallium/include \
diff --git a/src/mesa/Android.libmesa_st_mesa.mk b/src/mesa/Android.libmesa_st_mesa.mk
index 3905ddcf24..22ba1b2647 100644
--- a/src/mesa/Android.libmesa_st_mesa.mk
+++ b/src/mesa/Android.libmesa_st_mesa.mk
@@ -40,21 +40,15 @@ LOCAL_MODULE := libmesa_st_mesa
LOCAL_SRC_FILES := \
$(MESA_GALLIUM_FILES)
-LOCAL_GENERATED_SOURCES := $(MESA_GEN_GLSL_H)
+LOCAL_GENERATED_SOURCES := \
+ $(MESA_GEN_GLSL_H) \
+ $(MESA_GEN_NIR_H)
ifeq ($(strip $(MESA_ENABLE_ASM)),true)
-ifeq ($(TARGET_ARCH),x86)
- LOCAL_SRC_FILES += $(X86_FILES)
-endif # x86
+ LOCAL_SRC_FILES_x86 += $(X86_FILES)
+ LOCAL_SRC_FILES_x86_64 += $(X86_64_FILES)
endif # MESA_ENABLE_ASM
-ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
-LOCAL_WHOLE_STATIC_LIBRARIES := \
- libmesa_sse41
-LOCAL_CFLAGS := \
- -DUSE_SSE41
-endif
-
LOCAL_C_INCLUDES := \
$(MESA_TOP)/src/mapi \
$(MESA_TOP)/src/mesa/main \
@@ -65,6 +59,12 @@ LOCAL_C_INCLUDES := \
LOCAL_WHOLE_STATIC_LIBRARIES += \
libmesa_program
+LOCAL_WHOLE_STATIC_LIBRARIES_x86 += \
+ libmesa_sse41 \
+
+LOCAL_WHOLE_STATIC_LIBRARIES_x86_64 += \
+ libmesa_sse41 \
+
LOCAL_STATIC_LIBRARIES += libmesa_nir libmesa_glsl
include $(LOCAL_PATH)/Android.gen.mk
diff --git a/src/mesa/Android.mesa_gen_matypes.mk b/src/mesa/Android.mesa_gen_matypes.mk
index 4fcf73a631..163f0e234f 100644
--- a/src/mesa/Android.mesa_gen_matypes.mk
+++ b/src/mesa/Android.mesa_gen_matypes.mk
@@ -25,13 +25,16 @@
# ---------------------------------------------------------------------
ifeq ($(strip $(MESA_ENABLE_ASM)),true)
-ifeq ($(TARGET_ARCH),x86)
+ifneq ($(filter x86 x86_64,$(TARGET_ARCH)),)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mesa_gen_matypes
+LOCAL_MULTILIB := both
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
LOCAL_IS_HOST_MODULE := true
LOCAL_C_INCLUDES := \
@@ -43,5 +46,5 @@ LOCAL_SRC_FILES := \
include $(MESA_COMMON_MK)
include $(BUILD_HOST_EXECUTABLE)
-endif # x86
+endif # x86 x86_64
endif # MESA_ENABLE_ASM
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 79cb0506dd..eafd1528d8 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -781,8 +781,8 @@ const __DRIdri2Extension driDRI2Extension = {
.createNewScreen2 = driCreateNewScreen2,
};
-const __DRIswrastExtension driSWRastExtension = {
- .base = { __DRI_SWRAST, 4 },
+__DRIswrastExtension driSWRastExtension = {
+ .base = { __DRI_SWRAST, 5 },
.createNewScreen = driSWRastCreateNewScreen,
.createNewDrawable = driCreateNewDrawable,
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index 6987f555e6..79148fadb2 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -63,7 +63,7 @@
* Extensions.
*/
extern const __DRIcoreExtension driCoreExtension;
-extern const __DRIswrastExtension driSWRastExtension;
+extern __DRIswrastExtension driSWRastExtension;
extern const __DRIdri2Extension driDRI2Extension;
extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c
index 83cd7336ec..58deb22bba 100644
--- a/src/mesa/drivers/dri/i915/i830_texstate.c
+++ b/src/mesa/drivers/dri/i915/i830_texstate.c
@@ -336,6 +336,7 @@ i830UpdateTextureState(struct intel_context *intel)
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP:
+ case TEXTURE_EXTERNAL_BIT:
ok = i830_update_tex_unit(intel, i, TEXCOORDS_ARE_NORMAL);
break;
case GL_TEXTURE_RECTANGLE:
diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index 6c4882378f..e424f31d74 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -108,6 +108,7 @@ intel_init_texture_formats(struct gl_context *ctx)
ctx->TextureFormatSupported[MESA_FORMAT_B4G4R4A4_UNORM] = true;
ctx->TextureFormatSupported[MESA_FORMAT_B5G5R5A1_UNORM] = true;
ctx->TextureFormatSupported[MESA_FORMAT_B5G6R5_UNORM] = true;
+ ctx->TextureFormatSupported[MESA_FORMAT_R8G8B8X8_UNORM] = true;
ctx->TextureFormatSupported[MESA_FORMAT_L_UNORM8] = true;
if (intel->gen == 3)
ctx->TextureFormatSupported[MESA_FORMAT_A_UNORM8] = true;
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c
index 1944b3db0a..40b0feb78d 100644
--- a/src/mesa/drivers/dri/i915/i915_fragprog.c
+++ b/src/mesa/drivers/dri/i915/i915_fragprog.c
@@ -262,6 +262,7 @@ translate_tex_src_target(struct i915_fragment_program *p, GLubyte bit)
case TEXTURE_1D_INDEX:
return D0_SAMPLE_TYPE_2D;
case TEXTURE_2D_INDEX:
+ case TEXTURE_EXTERNAL_INDEX:
return D0_SAMPLE_TYPE_2D;
case TEXTURE_RECT_INDEX:
return D0_SAMPLE_TYPE_2D;
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 39abe1b293..77d77bd553 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -774,6 +774,7 @@ i915Enable(struct gl_context * ctx, GLenum cap, GLboolean state)
switch (cap) {
case GL_TEXTURE_2D:
+ case GL_TEXTURE_EXTERNAL_OES:
break;
case GL_LIGHTING:
diff --git a/src/mesa/drivers/dri/i915/i915_tex_layout.c b/src/mesa/drivers/dri/i915/i915_tex_layout.c
index e76ccb0b56..29448e222b 100644
--- a/src/mesa/drivers/dri/i915/i915_tex_layout.c
+++ b/src/mesa/drivers/dri/i915/i915_tex_layout.c
@@ -236,6 +236,7 @@ i915_miptree_layout(struct intel_mipmap_tree * mt)
break;
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
+ case GL_TEXTURE_EXTERNAL_OES:
case GL_TEXTURE_RECTANGLE_ARB:
i915_miptree_layout_2d(mt);
break;
@@ -468,6 +469,7 @@ i945_miptree_layout(struct intel_mipmap_tree * mt)
break;
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
+ case GL_TEXTURE_EXTERNAL_OES:
case GL_TEXTURE_RECTANGLE_ARB:
i945_miptree_layout_2d(mt);
break;
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index f653f441ad..bbd1ac17a3 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -61,6 +61,8 @@ translate_texture_format(mesa_format mesa_format, GLenum DepthMode)
return MAPSURF_32BIT | MT_32BIT_ARGB8888;
case MESA_FORMAT_B8G8R8X8_UNORM:
return MAPSURF_32BIT | MT_32BIT_XRGB8888;
+ case MESA_FORMAT_R8G8B8X8_UNORM:
+ return MAPSURF_32BIT | MT_32BIT_XBGR8888;
case MESA_FORMAT_R8G8B8A8_UNORM:
return MAPSURF_32BIT | MT_32BIT_ABGR8888;
case MESA_FORMAT_YCBCR_REV:
@@ -423,6 +425,7 @@ i915UpdateTextureState(struct intel_context *intel)
case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP:
case GL_TEXTURE_3D:
+ case GL_TEXTURE_EXTERNAL_OES:
ok = i915_update_tex_unit(intel, i, SS3_NORMALIZED_COORDS);
break;
case GL_TEXTURE_RECTANGLE:
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index c41cd37bcc..72218e5cf9 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -550,6 +550,7 @@ static uint32_t i915_render_target_format_for_mesa_format[MESA_FORMAT_COUNT] =
{
[MESA_FORMAT_B8G8R8A8_UNORM] = DV_PF_8888,
[MESA_FORMAT_B8G8R8X8_UNORM] = DV_PF_8888,
+ [MESA_FORMAT_R8G8B8X8_UNORM] = DV_PF_8888,
[MESA_FORMAT_B5G6R5_UNORM] = DV_PF_565 | DITHER_FULL_ALWAYS,
[MESA_FORMAT_B5G5R5A1_UNORM] = DV_PF_1555 | DITHER_FULL_ALWAYS,
[MESA_FORMAT_B4G4R4A4_UNORM] = DV_PF_4444 | DITHER_FULL_ALWAYS,
diff --git a/src/mesa/drivers/dri/i915/intel_extensions.c b/src/mesa/drivers/dri/i915/intel_extensions.c
index ab7820f123..eca6234ebc 100644
--- a/src/mesa/drivers/dri/i915/intel_extensions.c
+++ b/src/mesa/drivers/dri/i915/intel_extensions.c
@@ -76,6 +76,7 @@ intelInitExtensions(struct gl_context *ctx)
ctx->Extensions.TDFX_texture_compression_FXT1 = true;
ctx->Extensions.OES_EGL_image = true;
ctx->Extensions.OES_draw_texture = true;
+ ctx->Extensions.OES_EGL_image_external = true;
ctx->Const.GLSLVersion = 120;
_mesa_override_glsl_version(&ctx->Const);
diff --git a/src/mesa/drivers/dri/i965/Android.mk b/src/mesa/drivers/dri/i965/Android.mk
index b4f1adf6ca..cfaa3f8845 100644
--- a/src/mesa/drivers/dri/i965/Android.mk
+++ b/src/mesa/drivers/dri/i965/Android.mk
@@ -168,11 +168,6 @@ endif
LOCAL_CFLAGS := \
$(MESA_DRI_CFLAGS)
-ifeq ($(ARCH_X86_HAVE_SSE4_1),true)
-LOCAL_CFLAGS += \
- -DUSE_SSE41
-endif
-
LOCAL_C_INCLUDES := \
$(MESA_DRI_C_INCLUDES)
diff --git a/src/mesa/drivers/dri/i965/intel_tex_image.c b/src/mesa/drivers/dri/i965/intel_tex_image.c
index 4454e53916..ec0fe9ad6c 100644
--- a/src/mesa/drivers/dri/i965/intel_tex_image.c
+++ b/src/mesa/drivers/dri/i965/intel_tex_image.c
@@ -392,6 +392,7 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
if (image == NULL)
return;
+#ifndef ANDROID
/* We support external textures only for EGLImages created with
* EGL_EXT_image_dma_buf_import. We may lift that restriction in the future.
*/
@@ -401,6 +402,7 @@ intel_image_target_texture_2d(struct gl_context *ctx, GLenum target,
"for images created with EGL_EXT_image_dma_buf_import");
return;
}
+#endif
/* Disallow depth/stencil textures: we don't have a way to pass the
* separate stencil miptree of a GL_DEPTH_STENCIL texture through.
diff --git a/src/mesa/main/errors.c b/src/mesa/main/errors.c
index 9932b4a5a8..53a84361c2 100644
--- a/src/mesa/main/errors.c
+++ b/src/mesa/main/errors.c
@@ -42,6 +42,10 @@
#include "util/hash_table.h"
#include "util/simple_list.h"
+#if defined(ANDROID)
+# define LOG_TAG "mesa"
+# include <log/log.h>
+#endif
static FILE *LogFile = NULL;
@@ -95,6 +99,10 @@ output_if_debug(const char *prefixString, const char *outputString,
_mesa_snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : "");
OutputDebugStringA(buf);
}
+#elif defined(ANDROID)
+ {
+ ALOGD("%s: %s", prefixString, outputString);
+ }
#endif
}
}
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index b6286fc6d5..e03c937d2b 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -25,6 +25,7 @@ EXT(ANGLE_texture_compression_dxt5 , ANGLE_texture_compression_dxt
EXT(APPLE_object_purgeable , APPLE_object_purgeable , GLL, GLC, x , x , 2006)
EXT(APPLE_packed_pixels , dummy_true , GLL, x , x , x , 2002)
+EXT(APPLE_texture_2D_limited_npot , ARB_texture_non_power_of_two , x , x , ES1, x , 2011)
EXT(APPLE_texture_max_level , dummy_true , x , x , ES1, ES2, 2009)
EXT(APPLE_vertex_array_object , dummy_true , GLL, x , x , x , 2002)
@@ -145,7 +146,7 @@ EXT(ARB_texture_gather , ARB_texture_gather
EXT(ARB_texture_mirror_clamp_to_edge , ARB_texture_mirror_clamp_to_edge , GLL, GLC, x , x , 2013)
EXT(ARB_texture_mirrored_repeat , dummy_true , GLL, x , x , x , 2001)
EXT(ARB_texture_multisample , ARB_texture_multisample , GLL, GLC, x , x , 2009)
-EXT(ARB_texture_non_power_of_two , ARB_texture_non_power_of_two , GLL, GLC, x , x , 2003)
+EXT(ARB_texture_non_power_of_two , ARB_texture_non_power_of_two , GLL, GLC, ES1, x , 2003)
EXT(ARB_texture_query_levels , ARB_texture_query_levels , GLL, GLC, x , x , 2012)
EXT(ARB_texture_query_lod , ARB_texture_query_lod , GLL, GLC, x , x , 2009)
EXT(ARB_texture_rectangle , NV_texture_rectangle , GLL, GLC, x , x , 2004)