OSDN Git Service

Merge remote-tracking branch 'mesa/17.0' into marshmallow-x86 marshmallow-x86 android-x86-6.0-r3
authorChih-Wei Huang <cwhuang@linux.org.tw>
Thu, 20 Apr 2017 07:53:26 +0000 (15:53 +0800)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Thu, 20 Apr 2017 07:53:26 +0000 (15:53 +0800)
71 files changed:
Android.common.mk
Android.mk
CleanSpec.mk
include/GL/internal/dri_interface.h
src/compiler/glsl/ast_array_index.cpp
src/egl/Android.mk
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/dri2/platform_android.c
src/gallium/Android.mk
src/gallium/auxiliary/pipe-loader/pipe_loader.h
src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c
src/gallium/drivers/llvmpipe/Android.mk [new file with mode: 0644]
src/gallium/drivers/nouveau/nouveau_buffer.c
src/gallium/drivers/nouveau/nouveau_fence.c
src/gallium/drivers/nouveau/nouveau_fence.h
src/gallium/drivers/nouveau/nouveau_screen.c
src/gallium/drivers/nouveau/nouveau_screen.h
src/gallium/drivers/nouveau/nv30/nv30_clear.c
src/gallium/drivers/nouveau/nv30/nv30_context.c
src/gallium/drivers/nouveau/nv30/nv30_draw.c
src/gallium/drivers/nouveau/nv30/nv30_fragprog.c
src/gallium/drivers/nouveau/nv30/nv30_miptree.c
src/gallium/drivers/nouveau/nv30/nv30_query.c
src/gallium/drivers/nouveau/nv30/nv30_vbo.c
src/gallium/drivers/nouveau/nv50/nv50_compute.c
src/gallium/drivers/nouveau/nv50/nv50_context.c
src/gallium/drivers/nouveau/nv50/nv50_context.h
src/gallium/drivers/nouveau/nv50/nv50_miptree.c
src/gallium/drivers/nouveau/nv50/nv50_query.c
src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
src/gallium/drivers/nouveau/nv50/nv50_query_hw_sm.c
src/gallium/drivers/nouveau/nv50/nv50_surface.c
src/gallium/drivers/nouveau/nv50/nv50_transfer.c
src/gallium/drivers/nouveau/nv50/nv50_vbo.c
src/gallium/drivers/nouveau/nvc0/nvc0_compute.c
src/gallium/drivers/nouveau/nvc0/nvc0_context.c
src/gallium/drivers/nouveau/nvc0/nvc0_context.h
src/gallium/drivers/nouveau/nvc0/nvc0_query.c
src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
src/gallium/drivers/nouveau/nvc0/nvc0_query_hw_sm.c
src/gallium/drivers/nouveau/nvc0/nvc0_screen.c
src/gallium/drivers/nouveau/nvc0/nvc0_surface.c
src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
src/gallium/drivers/nouveau/nvc0/nve4_compute.c
src/gallium/include/state_tracker/drm_driver.h
src/gallium/state_trackers/dri/dri2.c
src/gallium/state_trackers/dri/drisw.c
src/gallium/targets/dri/Android.mk
src/gallium/targets/dri/dri.sym
src/gallium/winsys/sw/dri/dri_sw_winsys.c
src/gallium/winsys/virgl/drm/virgl_drm_winsys.c
src/mapi/Android.mk
src/mesa/Android.gen.mk
src/mesa/Android.libmesa_dricore.mk
src/mesa/Android.libmesa_sse41.mk
src/mesa/Android.libmesa_st_mesa.mk
src/mesa/Android.mesa_gen_matypes.mk
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/common/dri_util.h
src/mesa/drivers/dri/i915/i830_texstate.c
src/mesa/drivers/dri/i915/i915_context.c
src/mesa/drivers/dri/i915/i915_fragprog.c
src/mesa/drivers/dri/i915/i915_state.c
src/mesa/drivers/dri/i915/i915_tex_layout.c
src/mesa/drivers/dri/i915/i915_texstate.c
src/mesa/drivers/dri/i915/i915_vtbl.c
src/mesa/drivers/dri/i915/intel_extensions.c
src/mesa/drivers/dri/i965/Android.mk
src/mesa/drivers/dri/i965/intel_tex_image.c
src/mesa/main/extensions_table.h

index 46e4e64..ef83a97 100644 (file)
@@ -44,6 +44,7 @@ LOCAL_CFLAGS += \
 
 LOCAL_CFLAGS += \
        -DENABLE_SHADER_CACHE \
+       -D__STDC_CONSTANT_MACROS \
        -D__STDC_LIMIT_MACROS \
        -DHAVE___BUILTIN_EXPECT \
        -DHAVE___BUILTIN_FFS \
@@ -61,6 +62,7 @@ LOCAL_CFLAGS += \
        -DHAVE___BUILTIN_UNREACHABLE \
        -DHAVE_PTHREAD=1 \
        -DHAVE_DLOPEN \
+       -DTEXTURE_FLOAT_ENABLED \
        -fvisibility=hidden \
        -Wno-sign-compare
 
@@ -68,13 +70,28 @@ 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 += \
@@ -105,7 +122,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
 
index fb29105..8a62d98 100644 (file)
@@ -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)),)
index d08b0de..d0fcc72 100644 (file)
@@ -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)
index 8922356..c8ef019 100644 (file)
@@ -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;
@@ -861,8 +862,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;
 
@@ -909,6 +911,15 @@ struct __DRIswrastExtensionRec {
                                     const __DRIconfig ***driver_configs,
                                     void *loaderPrivate);
 
+   /**
+    * create a dri image from native window system handle
+    *
+    * \since version 5
+    */
+   __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
@@ -1308,7 +1319,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;
index dfa44b7..3e650c0 100644 (file)
@@ -306,7 +306,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",
index bfd56a7..d63e71d 100644 (file)
@@ -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
index 35591c2..3015b0e 100644 (file)
@@ -402,6 +402,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 }
 };
 
index 511b696..3a71e23 100644 (file)
@@ -40,7 +40,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))
 
@@ -154,7 +156,8 @@ 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 EGLBoolean
@@ -338,9 +341,16 @@ 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;
@@ -980,6 +990,234 @@ 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;
+   }
+   return !dri2_surf->buffer;
+}
+
+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;
+   _EGLDisplay *egl_dpy = dri2_surf->base.Resource.Display;
+   char *dstPtr, *srcPtr;
+   size_t BPerPixel, dstStride, copyWidth, xOffset;
+
+   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;
+   if (stride == 0)
+      stride = copyWidth;
+
+   /* 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;
+
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(egl_dpy);
+   if (dri2_dpy->gralloc->lock(dri2_dpy->gralloc, 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 (dri2_dpy->gralloc->unlock(dri2_dpy->gralloc, 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)
+{
+   swrastPutImage2(draw, op, x, y, w, h, 0, 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;
+
+   struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);
+   if (dri2_dpy->gralloc->lock(dri2_dpy->gralloc, 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 (dri2_dpy->gralloc->unlock(dri2_dpy->gralloc, 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.external_buffer = 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(struct dri2_egl_display *dri2_dpy)
 {
@@ -1064,6 +1302,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,
@@ -1078,27 +1325,43 @@ 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 struct dri2_egl_display *alloc_dri2_egl_display(bool is_swrast)
+{
+   struct dri2_egl_display *dri2_dpy = NULL;
+   const hw_module_t *mod;
+
+   if (!hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mod)) {
+      gralloc_module_t *gr_mod = (gralloc_module_t *) mod;
+      if (is_swrast || gr_mod->perform) {
+         dri2_dpy = calloc(1, sizeof(*dri2_dpy));
+         if (dri2_dpy)
+            dri2_dpy->gralloc = gr_mod;
+         else
+            _eglError(EGL_BAD_ALLOC, "eglInitialize");
+      }
+   } else {
+      _eglLog(_EGL_FATAL, "DRI2: failed to get gralloc module");
+   }
+
+   return dri2_dpy;
+}
+
+static EGLBoolean
+dri2_initialize_android_drm(_EGLDriver *drv, _EGLDisplay *dpy)
 {
    struct dri2_egl_display *dri2_dpy;
    const char *err;
    int ret;
 
-   _eglSetLogProc(droid_log);
-
-   loader_set_logger(_eglLog);
-
-   dri2_dpy = calloc(1, sizeof(*dri2_dpy));
+   dri2_dpy = alloc_dri2_egl_display(false);
    if (!dri2_dpy)
-      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
-
-   ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
-                       (const hw_module_t **)&dri2_dpy->gralloc);
-   if (ret) {
-      err = "DRI2: failed to get gralloc module";
-      goto cleanup_display;
-   }
+      return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
 
    dpy->DriverData = (void *) dri2_dpy;
 
@@ -1163,3 +1426,95 @@ 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;
+
+   dri2_dpy = alloc_dri2_egl_display(true);
+   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_FALSE;
+
+   _eglSetLogProc(droid_log);
+
+   loader_set_logger(_eglLog);
+
+   if (!getenv("LIBGL_ALWAYS_SOFTWARE"))
+      initialized = dri2_initialize_android_drm(drv, dpy);
+
+   if (!initialized)
+      initialized = dri2_initialize_android_swrast(drv, dpy);
+
+   return initialized;
+}
index 2b469b6..690b289 100644 (file)
@@ -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
index 690d088..19d269f 100644 (file)
@@ -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
index 6c89fe5..7155134 100644 (file)
@@ -304,3 +304,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/drivers/llvmpipe/Android.mk b/src/gallium/drivers/llvmpipe/Android.mk
new file mode 100644 (file)
index 0000000..0ead4da
--- /dev/null
@@ -0,0 +1,36 @@
+# 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)
index 2c60441..e14ba7f 100644 (file)
@@ -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;
@@ -424,14 +429,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;
@@ -477,7 +487,9 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
                             PIPE_TRANSFER_PERSISTENT))) {
          /* 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
@@ -486,10 +498,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. */
@@ -513,9 +528,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,
@@ -535,11 +554,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);
index 6c299cb..bbc8ad4 100644 (file)
@@ -67,12 +67,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);
 
@@ -86,6 +88,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) {
@@ -119,6 +124,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;
@@ -140,6 +146,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)
@@ -194,18 +201,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)
@@ -223,6 +239,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;
 }
 
index e14572b..35ed94f 100644 (file)
@@ -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"
 
@@ -46,10 +47,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);
    }
 
index f59e101..1a2fe7d 100644 (file)
@@ -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
index 28c4760..28c8620 100644 (file)
@@ -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);
index 4e6df1e..8e05c6b 100644 (file)
@@ -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, 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, 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;
 }
 
index 3ed0889..fbc4136 100644 (file)
@@ -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;
 }
index 10c9f56..c5761a3 100644 (file)
@@ -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);
 }
index 6de61bc..fd21f99 100644 (file)
@@ -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
index 165b8f2..b748e49 100644 (file)
@@ -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);
    }
index aa9a12f..a047e15 100644 (file)
@@ -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
index bc9b9a1..8e3fdee 100644 (file)
@@ -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
index d781f6f..3c174e4 100644 (file)
@@ -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;
 }
index ece7da9..6b59bdb 100644 (file)
@@ -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, unsigned flags)
 {
    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)
index cca44f5..4c8a4e5 100644 (file)
@@ -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 *);
index f2e304f..7f281f9 100644 (file)
@@ -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);
index e57e3ac..4317f22 100644 (file)
@@ -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;
 }
 
index 727b509..d2ad72e 100644 (file)
@@ -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;
 
index bcfba9f..31445eb 100644 (file)
@@ -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;
 
index f5fa9d6..3b2e5b0 100644 (file)
@@ -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, 64 + sf->depth, 1, 0))
+   if (nouveau_pushbuf_space(push, 64 + 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, 64 + sf->depth, 1, 0))
+   if (nouveau_pushbuf_space(push, 64 + 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, 64, 1, 0))
+   if (nouveau_pushbuf_space(push, 64, 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
index 8209f1f..c751ade 100644 (file)
@@ -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);
    }
index 4c46ed0..3eabcd7 100644 (file)
@@ -768,6 +768,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;
@@ -828,6 +830,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;
    }
 
@@ -887,4 +890,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);
 }
index 11635c9..b8efd1e 100644 (file)
@@ -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);
 }
index 8f2b974..dc700cb 100644 (file)
@@ -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, unsigned flags)
 {
    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);
index 79a5333..7d27e6d 100644 (file)
@@ -303,6 +303,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 *);
index 24aa5ed..f17ee26 100644 (file)
@@ -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)
@@ -169,6 +169,16 @@ nvc0_render_condition(struct pipe_context *pipe,
    }
 }
 
+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,
@@ -278,6 +288,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;
 }
index ff20fe6..4c7c714 100644 (file)
@@ -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);
index df5723d..0b610d5 100644 (file)
@@ -2325,6 +2325,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);
 
@@ -2385,6 +2386,7 @@ nve4_hw_sm_begin_query(struct nvc0_context *nvc0, struct nvc0_hw_query *hq)
       PUSH_DATA (push, 0xff);
    }
 
+   pipe_mutex_unlock(screen->base.push_mutex);
    return true;
 }
 
@@ -2408,6 +2410,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);
 
@@ -2454,6 +2457,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;
 }
 
@@ -2546,6 +2550,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)
@@ -2576,6 +2581,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++) {
@@ -2589,6 +2595,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;
@@ -2613,6 +2620,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
index 8477d66..8b6a414 100644 (file)
@@ -515,7 +515,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);
    }
index d567d82..36aa378 100644 (file)
@@ -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);
 }
 
 
@@ -1171,8 +1202,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);
@@ -1634,6 +1665,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);
 
@@ -1645,6 +1678,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);
 }
 
index 14fb53c..6cb39a9 100644 (file)
@@ -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,
index 9a3eb06..f6413d8 100644 (file)
@@ -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;
@@ -1031,6 +1033,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;
    }
 
@@ -1083,4 +1086,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);
 }
index 798761d..548343e 100644 (file)
@@ -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);
 }
 
 
index c80fb09..e4d8f17 100644 (file)
@@ -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,7 +21,7 @@ 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.
     */
@@ -30,6 +31,13 @@ struct winsys_handle
     * of a specific layer of an array texture.
     */
    unsigned layer;
+
+   /**
+    * Input to texture_from_handle.
+    * Output for texture_get_handle.
+    */
+   void* external_buffer;
+
    /**
     * Input to texture_from_handle.
     * Output for texture_get_handle.
index ad2e056..485a03d 100644 (file)
@@ -111,7 +111,7 @@ static int convert_fourcc(int format, int *dri_components_p)
  * only needed for exporting dmabuf's, so I think I won't loose much
  * sleep over it.
  */
-static int convert_to_fourcc(int format)
+int convert_to_fourcc(int format)
 {
    switch(format) {
    case __DRI_IMAGE_FORMAT_RGB565:
@@ -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);
@@ -1600,7 +1600,7 @@ dri2_server_wait_sync(__DRIcontext *_ctx, void *_fence, unsigned flags)
       ctx->fence_server_sync(ctx, fence->pipe_fence);
 }
 
-static __DRI2fenceExtension dri2FenceExtension = {
+__DRI2fenceExtension dri2FenceExtension = {
    .base = { __DRI2_FENCE, 2 },
 
    .create_fence = dri2_create_fence,
@@ -1933,9 +1933,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;
 
index b85a73c..1360765 100644 (file)
@@ -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 void dri2_destroy_image(__DRIimage *img);
+extern int convert_to_fourcc(int format);
+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 __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;
+   case __DRI_IMAGE_ATTRIB_FOURCC:
+      *value = convert_to_fourcc(image->dri_format);
+      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);
index 950a464..7343fb9 100644 (file)
@@ -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
@@ -42,6 +48,7 @@ LOCAL_SHARED_LIBRARIES := \
        libdl \
        libglapi \
        libexpat \
+       libhardware \
 
 ifneq ($(filter freedreno,$(MESA_GPU_DRIVERS)),)
 LOCAL_CFLAGS += -DGALLIUM_FREEDRENO
@@ -81,8 +88,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
@@ -117,14 +125,11 @@ LOCAL_WHOLE_STATIC_LIBRARIES := \
 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)
index 1fdf18b..1d86c88 100644 (file)
@@ -2,6 +2,7 @@
        global:
                __driDriverExtensions;
                __driDriverGetExtensions*;
+               load_pipe_screen;
                nouveau_drm_screen_create;
                radeon_drm_winsys_create;
                amdgpu_winsys_create;
index 94d5092..66240a2 100644 (file)
 #include "util/u_memory.h"
 
 #include "state_tracker/sw_winsys.h"
+#include "state_tracker/drm_driver.h"
 #include "dri_sw_winsys.h"
 
+#ifdef ANDROID
+#include <system/graphics.h>
+#include <system/window.h>
+#include <hardware/gralloc.h>
+#endif
+
 
 struct dri_sw_displaytarget
 {
@@ -48,8 +55,28 @@ struct dri_sw_displaytarget
    void *data;
    void *mapped;
    const void *front_private;
+#ifdef ANDROID
+   struct ANativeWindowBuffer *androidBuffer;
+#endif
 };
 
+#ifdef ANDROID
+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 +152,12 @@ dri_sw_displaytarget_destroy(struct sw_winsys *ws,
 {
    struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
 
+#ifdef ANDROID
+   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 +169,17 @@ dri_sw_displaytarget_map(struct sw_winsys *ws,
                          unsigned flags)
 {
    struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+#ifdef ANDROID
+   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 +200,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 ANDROID
+   if (dri_sw_dt->androidBuffer) {
+      get_gralloc()->unlock(get_gralloc(), dri_sw_dt->androidBuffer->handle);
+   }
+#endif
    dri_sw_dt->mapped = NULL;
 }
 
@@ -165,6 +214,22 @@ dri_sw_displaytarget_from_handle(struct sw_winsys *winsys,
                                  struct winsys_handle *whandle,
                                  unsigned *stride)
 {
+#ifdef ANDROID
+   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->external_buffer;
+      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;
 }
index 86e0470..f73d2a9 100644 (file)
@@ -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) {
index 4445218..b654c25 100644 (file)
@@ -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)
index a985f0a..cf62bac 100644 (file)
@@ -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,22 +70,32 @@ define es-gen
        $(hide) $(PRIVATE_SCRIPT) $(1) $(PRIVATE_XML) > $@
 endef
 
-$(intermediates)/main/git_sha1.h:
+$(intermediates)/main/git_sha1.h: $(wildcard $(MESA_TOP)/.git/logs/HEAD)
        @mkdir -p $(dir $@)
        @echo "GIT-SHA1: $(PRIVATE_MODULE) <= git"
        $(hide) touch $@
        $(hide) if which git > /dev/null; then \
-                       git --git-dir $(PRIVATE_PATH)/../../.git log -n 1 --oneline | \
+                       git --git-dir $(MESA_TOP)/.git log -n 1 --oneline | \
                        sed 's/^\([^ ]*\) .*/#define MESA_GIT_SHA1 "git-\1"/' \
                        > $@; \
                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) $< > $@
index 86196ce..8de90b8 100644 (file)
@@ -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)
index 8562da6..3668785 100644 (file)
@@ -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 \
index 92df4ad..7872800 100644 (file)
@@ -45,18 +45,10 @@ LOCAL_GENERATED_SOURCES := \
        $(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 \
@@ -67,8 +59,21 @@ 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
 
+ifeq ($(MESA_LOLLIPOP_BUILD),true)
+LOCAL_C_INCLUDES += external/libcxx/include
+LOCAL_CXX_STL := libc++
+else
+include external/stlport/libstlport.mk
+endif # MESA_LOLLIPOP_BUILD
+
 include $(LOCAL_PATH)/Android.gen.mk
 include $(MESA_COMMON_MK)
 include $(BUILD_STATIC_LIBRARY)
index 4fcf73a..163f0e2 100644 (file)
 # ---------------------------------------------------------------------
 
 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
index fc12b3b..f80a34a 100644 (file)
@@ -793,8 +793,8 @@ const __DRIdri2Extension driDRI2Extension = {
     .createNewScreen2           = driCreateNewScreen2,
 };
 
-const __DRIswrastExtension driSWRastExtension = {
-    .base = { __DRI_SWRAST, 4 },
+__DRIswrastExtension driSWRastExtension = {
+    .base = { __DRI_SWRAST, __DRI_SWRAST_VERSION },
 
     .createNewScreen            = driSWRastCreateNewScreen,
     .createNewDrawable          = driCreateNewDrawable,
index 6987f55..79148fa 100644 (file)
@@ -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;
index 83cd733..58deb22 100644 (file)
@@ -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:
index 6c48823..e424f31 100644 (file)
@@ -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;
index fce649d..e566dfb 100644 (file)
@@ -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;
index 715db1f..eefc484 100644 (file)
@@ -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:
index e76ccb0..29448e2 100644 (file)
@@ -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;
index f653f44..bbd1ac1 100644 (file)
@@ -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:
index c41cd37..72218e5 100644 (file)
@@ -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,
index ab7820f..eca6234 100644 (file)
@@ -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);
index 7dea3c2..91574a7 100644 (file)
@@ -194,11 +194,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)
 
index 141996f..4277f74 100644 (file)
@@ -413,6 +413,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.
     */
@@ -422,6 +423,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.
index 08a403e..718ea4f 100644 (file)
@@ -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)
 
@@ -146,7 +147,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)