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