Compare commits
54 Commits
mesa-23.1.
...
mesa-10.0-
Author | SHA1 | Date | |
---|---|---|---|
|
15118b45a0 | ||
|
3fd32619d7 | ||
|
7a87dc278e | ||
|
f843604b6a | ||
|
e9f8b78278 | ||
|
dfff838429 | ||
|
11982ca08d | ||
|
713966c82f | ||
|
3a98fc6abe | ||
|
531637feee | ||
|
02807c06b8 | ||
|
9ed0452740 | ||
|
ef8fcfc9cf | ||
|
1b45f255b5 | ||
|
1a163c0b34 | ||
|
53e681f2fe | ||
|
10c25e58ca | ||
|
0558e10160 | ||
|
1e51d3a668 | ||
|
e5839c2397 | ||
|
7d2187176a | ||
|
329a75511f | ||
|
76434775e0 | ||
|
2365244302 | ||
|
3e6f200250 | ||
|
99c62ff2ea | ||
|
a5a6ef9702 | ||
|
6640147463 | ||
|
229ee20460 | ||
|
dbddd86cc2 | ||
|
c702f5eead | ||
|
c4cc166abc | ||
|
2a3dcece72 | ||
|
accc276df2 | ||
|
afbdcdcaaf | ||
|
6f2877c40d | ||
|
02d9e1be87 | ||
|
095d583e52 | ||
|
8af132fca9 | ||
|
ade312cd8a | ||
|
f9a74a0b4c | ||
|
0e3f5999b9 | ||
|
ebc460bc5f | ||
|
0010bdd54a | ||
|
b8a631295a | ||
|
c94ed272eb | ||
|
47139b0233 | ||
|
94251281b4 | ||
|
03a29306b5 | ||
|
d37ea6dfec | ||
|
84ee00c1b2 | ||
|
3ffcc96abc | ||
|
bc94bf08c4 | ||
|
ce904c4caf |
3
bin/.cherry-ignore
Normal file
3
bin/.cherry-ignore
Normal file
@@ -0,0 +1,3 @@
|
||||
# Since we've disabled DRI3 completely in 10.0, this commit is no longer
|
||||
# necessary.
|
||||
f0f202e6b764be803470e27cba9102f14361ae22 glx: conditionaly build dri3 and present loader (v3)
|
18
configure.ac
18
configure.ac
@@ -34,9 +34,6 @@ LIBDRM_NVVIEUX_REQUIRED=2.4.33
|
||||
LIBDRM_NOUVEAU_REQUIRED="2.4.33 libdrm >= 2.4.41"
|
||||
LIBDRM_FREEDRENO_REQUIRED=2.4.39
|
||||
DRI2PROTO_REQUIRED=2.6
|
||||
DRI3PROTO_REQUIRED=1.0
|
||||
PRESENTPROTO_REQUIRED=1.0
|
||||
LIBUDEV_REQUIRED=151
|
||||
GLPROTO_REQUIRED=1.4.14
|
||||
|
||||
dnl Check for progs
|
||||
@@ -811,13 +808,10 @@ xyesno)
|
||||
fi
|
||||
PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= $DRI2PROTO_REQUIRED])
|
||||
GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV libdrm >= $LIBDRM_REQUIRED"
|
||||
PKG_CHECK_MODULES([DRI3PROTO], [dri3proto >= $DRI3PROTO_REQUIRED])
|
||||
PKG_CHECK_MODULES([PRESENTPROTO], [presentproto >= $PRESENTPROTO_REQUIRED])
|
||||
PKG_CHECK_MODULES([LIBUDEV], [libudev >= $LIBUDEV_REQUIRED])
|
||||
fi
|
||||
|
||||
# find the DRI deps for libGL
|
||||
dri_modules="x11 xext xdamage xfixes x11-xcb xcb-glx >= 1.8.1 xcb-dri2 >= 1.8 xcb-dri3 xcb-present xcb-sync xshmfence"
|
||||
dri_modules="x11 xext xdamage xfixes x11-xcb xcb-glx >= 1.8.1 xcb-dri2 >= 1.8"
|
||||
|
||||
# add xf86vidmode if available
|
||||
PKG_CHECK_MODULES([XF86VIDMODE], [xxf86vm], HAVE_XF86VIDMODE=yes, HAVE_XF86VIDMODE=no)
|
||||
@@ -827,8 +821,8 @@ xyesno)
|
||||
|
||||
PKG_CHECK_MODULES([DRIGL], [$dri_modules])
|
||||
GL_PC_REQ_PRIV="$GL_PC_REQ_PRIV $dri_modules"
|
||||
X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS $LIBUDEV_CFLAGS"
|
||||
GL_LIB_DEPS="$DRIGL_LIBS $LIBUDEV_LIBS"
|
||||
X11_INCLUDES="$X11_INCLUDES $DRIGL_CFLAGS"
|
||||
GL_LIB_DEPS="$DRIGL_LIBS"
|
||||
|
||||
# need DRM libs, $PTHREAD_LIBS, etc.
|
||||
GL_LIB_DEPS="$GL_LIB_DEPS $LIBDRM_LIBS -lm $PTHREAD_LIBS $DLOPEN_LIBS"
|
||||
@@ -1500,12 +1494,6 @@ AC_ARG_WITH([llvm-shared-libs],
|
||||
[link with LLVM shared libraries @<:@default=disabled@:>@])],
|
||||
[],
|
||||
[with_llvm_shared_libs=no])
|
||||
AS_IF([test x$enable_opencl = xyes],
|
||||
[
|
||||
if test "x$with_llvm_shared_libs" != xyes; then
|
||||
AC_MSG_ERROR([OpenCL requires LLVM shared libraries])
|
||||
fi
|
||||
])
|
||||
|
||||
AC_ARG_WITH([llvm-prefix],
|
||||
[AS_HELP_STRING([--with-llvm-prefix],
|
||||
|
@@ -782,12 +782,6 @@ typedef __DRIdrawable *
|
||||
const __DRIconfig *config,
|
||||
void *loaderPrivate);
|
||||
|
||||
typedef __DRIcontext *
|
||||
(*__DRIcreateNewContextFunc)(__DRIscreen *screen,
|
||||
const __DRIconfig *config,
|
||||
__DRIcontext *shared,
|
||||
void *loaderPrivate);
|
||||
|
||||
typedef __DRIcontext *
|
||||
(*__DRIcreateContextAttribsFunc)(__DRIscreen *screen,
|
||||
int api,
|
||||
@@ -949,7 +943,10 @@ struct __DRIdri2ExtensionRec {
|
||||
void *loaderPrivate);
|
||||
|
||||
__DRIcreateNewDrawableFunc createNewDrawable;
|
||||
__DRIcreateNewContextFunc createNewContext;
|
||||
__DRIcontext *(*createNewContext)(__DRIscreen *screen,
|
||||
const __DRIconfig *config,
|
||||
__DRIcontext *shared,
|
||||
void *loaderPrivate);
|
||||
|
||||
/* Since version 2 */
|
||||
__DRIgetAPIMaskFunc getAPIMask;
|
||||
@@ -1405,7 +1402,6 @@ struct __DRIimageDriverExtensionRec {
|
||||
/* Common DRI functions, shared with DRI2 */
|
||||
__DRIcreateNewScreen2Func createNewScreen2;
|
||||
__DRIcreateNewDrawableFunc createNewDrawable;
|
||||
__DRIcreateNewContextFunc createNewContext;
|
||||
__DRIcreateContextAttribsFunc createContextAttribs;
|
||||
__DRIgetAPIMaskFunc getAPIMask;
|
||||
};
|
||||
|
@@ -117,7 +117,7 @@ struct dri2_egl_display
|
||||
|
||||
__DRIdri2LoaderExtension dri2_loader_extension;
|
||||
__DRIswrastLoaderExtension swrast_loader_extension;
|
||||
const __DRIextension *extensions[4];
|
||||
const __DRIextension *extensions[5];
|
||||
const __DRIextension **driver_extensions;
|
||||
|
||||
#ifdef HAVE_X11_PLATFORM
|
||||
@@ -189,7 +189,6 @@ struct dri2_egl_surface
|
||||
#ifdef HAVE_WAYLAND_PLATFORM
|
||||
struct wl_buffer *wl_buffer;
|
||||
__DRIimage *dri_image;
|
||||
int pitch, name;
|
||||
#endif
|
||||
#ifdef HAVE_DRM_PLATFORM
|
||||
struct gbm_bo *bo;
|
||||
|
@@ -175,13 +175,12 @@ dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
|
||||
}
|
||||
|
||||
static int
|
||||
get_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
|
||||
get_back_bo(struct dri2_egl_surface *dri2_surf)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy =
|
||||
dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||
struct gbm_dri_bo *bo;
|
||||
struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
|
||||
int i, name, pitch;
|
||||
int i;
|
||||
|
||||
if (dri2_surf->back == NULL) {
|
||||
for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
|
||||
@@ -201,6 +200,17 @@ get_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
|
||||
if (dri2_surf->back->bo == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy =
|
||||
dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||
struct gbm_dri_bo *bo;
|
||||
int name, pitch;
|
||||
|
||||
bo = (struct gbm_dri_bo *) dri2_surf->back->bo;
|
||||
|
||||
dri2_dpy->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_NAME, &name);
|
||||
@@ -211,8 +221,6 @@ get_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
|
||||
buffer->pitch = pitch;
|
||||
buffer->cpp = 4;
|
||||
buffer->flags = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -254,10 +262,11 @@ dri2_get_buffers_with_format(__DRIdrawable *driDrawable,
|
||||
|
||||
switch (attachments[i]) {
|
||||
case __DRI_BUFFER_BACK_LEFT:
|
||||
if (get_back_bo(dri2_surf, &dri2_surf->buffers[j]) < 0) {
|
||||
if (get_back_bo(dri2_surf) < 0) {
|
||||
_eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
|
||||
return NULL;
|
||||
}
|
||||
back_bo_to_dri_buffer(dri2_surf, &dri2_surf->buffers[j]);
|
||||
break;
|
||||
default:
|
||||
if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],
|
||||
@@ -312,6 +321,27 @@ dri2_get_buffers(__DRIdrawable * driDrawable,
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int
|
||||
dri_image_get_buffers(__DRIdrawable *driDrawable,
|
||||
unsigned int format,
|
||||
uint32_t *stamp,
|
||||
void *loaderPrivate,
|
||||
uint32_t buffer_mask,
|
||||
struct __DRIimageList *buffers)
|
||||
{
|
||||
struct dri2_egl_surface *dri2_surf = loaderPrivate;
|
||||
struct gbm_dri_bo *bo;
|
||||
|
||||
if (get_back_bo(dri2_surf) < 0)
|
||||
return 0;
|
||||
|
||||
bo = (struct gbm_dri_bo *) dri2_surf->back->bo;
|
||||
buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
|
||||
buffers->back = bo->image;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
dri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
|
||||
{
|
||||
@@ -348,9 +378,8 @@ dri2_query_buffer_age(_EGLDriver *drv,
|
||||
_EGLDisplay *disp, _EGLSurface *surface)
|
||||
{
|
||||
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
|
||||
__DRIbuffer buffer;
|
||||
|
||||
if (get_back_bo(dri2_surf, &buffer) < 0) {
|
||||
if (get_back_bo(dri2_surf) < 0) {
|
||||
_eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
|
||||
return 0;
|
||||
}
|
||||
@@ -469,6 +498,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
|
||||
dri2_dpy->gbm_dri->get_buffers = dri2_get_buffers;
|
||||
dri2_dpy->gbm_dri->flush_front_buffer = dri2_flush_front_buffer;
|
||||
dri2_dpy->gbm_dri->get_buffers_with_format = dri2_get_buffers_with_format;
|
||||
dri2_dpy->gbm_dri->image_get_buffers = dri_image_get_buffers;
|
||||
|
||||
dri2_dpy->gbm_dri->base.base.surface_lock_front_buffer = lock_front_buffer;
|
||||
dri2_dpy->gbm_dri->base.base.surface_release_buffer = release_buffer;
|
||||
|
@@ -257,12 +257,11 @@ dri2_release_buffers(struct dri2_egl_surface *dri2_surf)
|
||||
}
|
||||
|
||||
static int
|
||||
get_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
|
||||
get_back_bo(struct dri2_egl_surface *dri2_surf)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy =
|
||||
dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||
__DRIimage *image;
|
||||
int i, name, pitch;
|
||||
int i;
|
||||
|
||||
/* There might be a buffer release already queued that wasn't processed */
|
||||
wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_dpy->wl_queue);
|
||||
@@ -295,23 +294,30 @@ get_back_bo(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
|
||||
if (dri2_surf->back->dri_image == NULL)
|
||||
return -1;
|
||||
|
||||
dri2_surf->back->locked = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy =
|
||||
dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||
__DRIimage *image;
|
||||
int name, pitch;
|
||||
|
||||
image = dri2_surf->back->dri_image;
|
||||
|
||||
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
|
||||
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
|
||||
|
||||
dri2_surf->back->name = name;
|
||||
dri2_surf->back->pitch = pitch;
|
||||
|
||||
buffer->attachment = __DRI_BUFFER_BACK_LEFT;
|
||||
buffer->name = name;
|
||||
buffer->pitch = pitch;
|
||||
buffer->cpp = 4;
|
||||
buffer->flags = 0;
|
||||
|
||||
dri2_surf->back->locked = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -337,16 +343,12 @@ get_aux_bo(struct dri2_egl_surface *dri2_surf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __DRIbuffer *
|
||||
dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
|
||||
int *width, int *height,
|
||||
unsigned int *attachments, int count,
|
||||
int *out_count, void *loaderPrivate)
|
||||
static int
|
||||
update_buffers(struct dri2_egl_surface *dri2_surf)
|
||||
{
|
||||
struct dri2_egl_surface *dri2_surf = loaderPrivate;
|
||||
struct dri2_egl_display *dri2_dpy =
|
||||
dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
if (dri2_surf->base.Type == EGL_WINDOW_BIT &&
|
||||
(dri2_surf->base.Width != dri2_surf->wl_win->width ||
|
||||
@@ -360,22 +362,9 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
|
||||
dri2_surf->dy = dri2_surf->wl_win->dy;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
|
||||
switch (attachments[i]) {
|
||||
case __DRI_BUFFER_BACK_LEFT:
|
||||
if (get_back_bo(dri2_surf, &dri2_surf->buffers[j]) < 0) {
|
||||
_eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],
|
||||
&dri2_surf->buffers[j]) < 0) {
|
||||
_eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (get_back_bo(dri2_surf) < 0) {
|
||||
_eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If we have an extra unlocked buffer at this point, we had to do triple
|
||||
@@ -391,6 +380,36 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __DRIbuffer *
|
||||
dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
|
||||
int *width, int *height,
|
||||
unsigned int *attachments, int count,
|
||||
int *out_count, void *loaderPrivate)
|
||||
{
|
||||
struct dri2_egl_surface *dri2_surf = loaderPrivate;
|
||||
int i, j;
|
||||
|
||||
if (update_buffers(dri2_surf) < 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
|
||||
switch (attachments[i]) {
|
||||
case __DRI_BUFFER_BACK_LEFT:
|
||||
back_bo_to_dri_buffer(dri2_surf, &dri2_surf->buffers[j]);
|
||||
break;
|
||||
default:
|
||||
if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],
|
||||
&dri2_surf->buffers[j]) < 0) {
|
||||
_eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*out_count = j;
|
||||
if (j == 0)
|
||||
return NULL;
|
||||
@@ -434,6 +453,25 @@ dri2_get_buffers(__DRIdrawable * driDrawable,
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int
|
||||
image_get_buffers(__DRIdrawable *driDrawable,
|
||||
unsigned int format,
|
||||
uint32_t *stamp,
|
||||
void *loaderPrivate,
|
||||
uint32_t buffer_mask,
|
||||
struct __DRIimageList *buffers)
|
||||
{
|
||||
struct dri2_egl_surface *dri2_surf = loaderPrivate;
|
||||
|
||||
if (update_buffers(dri2_surf) < 0)
|
||||
return 0;
|
||||
|
||||
buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
|
||||
buffers->back = dri2_surf->back->dri_image;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
dri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
|
||||
{
|
||||
@@ -441,6 +479,12 @@ dri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
|
||||
(void) loaderPrivate;
|
||||
}
|
||||
|
||||
static const __DRIimageLoaderExtension image_loader_extension = {
|
||||
{ __DRI_IMAGE_LOADER, 1 },
|
||||
image_get_buffers,
|
||||
dri2_flush_front_buffer
|
||||
};
|
||||
|
||||
static void
|
||||
wayland_frame_callback(void *data, struct wl_callback *callback, uint32_t time)
|
||||
{
|
||||
@@ -459,7 +503,7 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy =
|
||||
dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||
int fd;
|
||||
int fd, stride, name;
|
||||
|
||||
if (dri2_surf->current->wl_buffer != NULL)
|
||||
return;
|
||||
@@ -467,6 +511,8 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf)
|
||||
if (dri2_dpy->capabilities & WL_DRM_CAPABILITY_PRIME) {
|
||||
dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
|
||||
__DRI_IMAGE_ATTRIB_FD, &fd);
|
||||
dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
|
||||
__DRI_IMAGE_ATTRIB_STRIDE, &stride);
|
||||
|
||||
dri2_surf->current->wl_buffer =
|
||||
wl_drm_create_prime_buffer(dri2_dpy->wl_drm,
|
||||
@@ -474,17 +520,22 @@ create_wl_buffer(struct dri2_egl_surface *dri2_surf)
|
||||
dri2_surf->base.Width,
|
||||
dri2_surf->base.Height,
|
||||
dri2_surf->format,
|
||||
0, dri2_surf->current->pitch,
|
||||
0, stride,
|
||||
0, 0,
|
||||
0, 0);
|
||||
close(fd);
|
||||
} else {
|
||||
dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
|
||||
__DRI_IMAGE_ATTRIB_NAME, &name);
|
||||
dri2_dpy->image->queryImage(dri2_surf->current->dri_image,
|
||||
__DRI_IMAGE_ATTRIB_STRIDE, &stride);
|
||||
|
||||
dri2_surf->current->wl_buffer =
|
||||
wl_drm_create_buffer(dri2_dpy->wl_drm,
|
||||
dri2_surf->current->name,
|
||||
name,
|
||||
dri2_surf->base.Width,
|
||||
dri2_surf->base.Height,
|
||||
dri2_surf->current->pitch,
|
||||
stride,
|
||||
dri2_surf->format);
|
||||
}
|
||||
|
||||
@@ -506,7 +557,6 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv,
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
|
||||
__DRIbuffer buffer;
|
||||
int i, ret = 0;
|
||||
|
||||
while (dri2_surf->frame_callback && ret != -1)
|
||||
@@ -526,7 +576,7 @@ dri2_swap_buffers_with_damage(_EGLDriver *drv,
|
||||
|
||||
/* Make sure we have a back buffer in case we're swapping without ever
|
||||
* rendering. */
|
||||
if (get_back_bo(dri2_surf, &buffer) < 0) {
|
||||
if (get_back_bo(dri2_surf) < 0) {
|
||||
_eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");
|
||||
return EGL_FALSE;
|
||||
}
|
||||
@@ -573,9 +623,8 @@ dri2_query_buffer_age(_EGLDriver *drv,
|
||||
_EGLDisplay *disp, _EGLSurface *surface)
|
||||
{
|
||||
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
|
||||
__DRIbuffer buffer;
|
||||
|
||||
if (get_back_bo(dri2_surf, &buffer) < 0) {
|
||||
if (get_back_bo(dri2_surf) < 0) {
|
||||
_eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
|
||||
return 0;
|
||||
}
|
||||
@@ -799,11 +848,12 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
|
||||
dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
|
||||
dri2_dpy->dri2_loader_extension.getBuffersWithFormat =
|
||||
dri2_get_buffers_with_format;
|
||||
|
||||
|
||||
dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base;
|
||||
dri2_dpy->extensions[1] = &image_lookup_extension.base;
|
||||
dri2_dpy->extensions[2] = &use_invalidate.base;
|
||||
dri2_dpy->extensions[3] = NULL;
|
||||
dri2_dpy->extensions[1] = &image_loader_extension.base;
|
||||
dri2_dpy->extensions[2] = &image_lookup_extension.base;
|
||||
dri2_dpy->extensions[3] = &use_invalidate.base;
|
||||
dri2_dpy->extensions[4] = NULL;
|
||||
|
||||
if (!dri2_create_screen(disp))
|
||||
goto cleanup_driver;
|
||||
|
@@ -41,7 +41,7 @@
|
||||
#include "util/u_debug.h" /* for assert */
|
||||
|
||||
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_HURD)
|
||||
|
||||
#include <pthread.h> /* POSIX threads headers */
|
||||
#include <stdio.h> /* for perror() */
|
||||
@@ -316,7 +316,7 @@ typedef int64_t pipe_condvar;
|
||||
* pipe_barrier
|
||||
*/
|
||||
|
||||
#if (defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)) && !defined(PIPE_OS_ANDROID)
|
||||
#if (defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HURD)) && !defined(PIPE_OS_ANDROID)
|
||||
|
||||
typedef pthread_barrier_t pipe_barrier;
|
||||
|
||||
@@ -444,7 +444,7 @@ pipe_semaphore_wait(pipe_semaphore *sema)
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_HURD)
|
||||
pthread_key_t key;
|
||||
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
|
||||
DWORD key;
|
||||
@@ -459,7 +459,7 @@ typedef struct {
|
||||
static INLINE void
|
||||
pipe_tsd_init(pipe_tsd *tsd)
|
||||
{
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_HURD)
|
||||
if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
|
||||
perror("pthread_key_create(): failed to allocate key for thread specific data");
|
||||
exit(-1);
|
||||
@@ -476,7 +476,7 @@ pipe_tsd_get(pipe_tsd *tsd)
|
||||
if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) {
|
||||
pipe_tsd_init(tsd);
|
||||
}
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_HURD)
|
||||
return pthread_getspecific(tsd->key);
|
||||
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
|
||||
assert(0);
|
||||
@@ -493,7 +493,7 @@ pipe_tsd_set(pipe_tsd *tsd, void *value)
|
||||
if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) {
|
||||
pipe_tsd_init(tsd);
|
||||
}
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN)
|
||||
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_HURD)
|
||||
if (pthread_setspecific(tsd->key, value) != 0) {
|
||||
perror("pthread_set_specific() failed");
|
||||
exit(-1);
|
||||
|
@@ -88,6 +88,9 @@ find_drm_pci_id(struct pipe_loader_drm_device *ddev)
|
||||
&ddev->base.u.pci.chip_id) != 2)
|
||||
goto fail;
|
||||
|
||||
udev_device_unref(device);
|
||||
udev_unref(udev);
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
|
@@ -519,7 +519,7 @@ nouveau_create_decoder(struct pipe_context *context,
|
||||
goto vl;
|
||||
if (screen->device->chipset >= 0x98 && screen->device->chipset != 0xa0)
|
||||
goto vl;
|
||||
if (screen->device->chipset < 0x31 || screen->device->chipset == 0x35)
|
||||
if (screen->device->chipset < 0x40)
|
||||
goto vl;
|
||||
|
||||
dec = CALLOC_STRUCT(nouveau_decoder);
|
||||
@@ -611,7 +611,6 @@ nouveau_create_decoder(struct pipe_context *context,
|
||||
BEGIN_NV04(push, NV31_MPEG(FORMAT), 2);
|
||||
PUSH_DATA (push, 0);
|
||||
switch (templ->entrypoint) {
|
||||
case PIPE_VIDEO_ENTRYPOINT_BITSTREAM: PUSH_DATA (push, 0x100); break;
|
||||
case PIPE_VIDEO_ENTRYPOINT_IDCT: PUSH_DATA (push, 1); break;
|
||||
case PIPE_VIDEO_ENTRYPOINT_MC: PUSH_DATA (push, 0); break;
|
||||
default: assert(0);
|
||||
@@ -782,7 +781,7 @@ nouveau_video_buffer_create(struct pipe_context *pipe,
|
||||
*/
|
||||
if (templat->buffer_format != PIPE_FORMAT_NV12 || getenv("XVMC_VL") ||
|
||||
(screen->device->chipset >= 0x98 && screen->device->chipset != 0xa0) ||
|
||||
screen->device->chipset < 0x31 || screen->device->chipset == 0x35)
|
||||
screen->device->chipset < 0x40)
|
||||
return vl_video_buffer_create(pipe, templat);
|
||||
|
||||
assert(templat->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
|
||||
@@ -839,7 +838,8 @@ nouveau_screen_get_video_param(struct pipe_screen *pscreen,
|
||||
{
|
||||
switch (param) {
|
||||
case PIPE_VIDEO_CAP_SUPPORTED:
|
||||
return vl_profile_supported(pscreen, profile, entrypoint);
|
||||
return entrypoint >= PIPE_VIDEO_ENTRYPOINT_IDCT &&
|
||||
u_reduce_video_profile(profile) == PIPE_VIDEO_FORMAT_MPEG12;
|
||||
case PIPE_VIDEO_CAP_NPOT_TEXTURES:
|
||||
return 1;
|
||||
case PIPE_VIDEO_CAP_MAX_WIDTH:
|
||||
|
@@ -712,6 +712,7 @@ unsigned r600_llvm_compile(
|
||||
const char * gpu_family = r600_llvm_gpu_string(family);
|
||||
unsigned i;
|
||||
|
||||
memset(&binary, 0, sizeof(struct radeon_llvm_binary));
|
||||
r = radeon_llvm_compile(mod, &binary, gpu_family, dump);
|
||||
|
||||
assert(binary.code_size % 4 == 0);
|
||||
@@ -744,6 +745,9 @@ unsigned r600_llvm_compile(
|
||||
}
|
||||
}
|
||||
|
||||
FREE(binary.code);
|
||||
FREE(binary.config);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@@ -173,6 +173,10 @@ unsigned radeon_llvm_compile(LLVMModuleRef M, struct radeon_llvm_binary *binary,
|
||||
}
|
||||
}
|
||||
|
||||
if (elf){
|
||||
elf_end(elf);
|
||||
}
|
||||
FREE(elf_buffer);
|
||||
LLVMDisposeMemoryBuffer(out_buffer);
|
||||
LLVMDisposeTargetMachine(tm);
|
||||
return 0;
|
||||
|
@@ -42,6 +42,7 @@ LLVMModuleRef radeon_llvm_parse_bitcode(const unsigned char * bitcode,
|
||||
buf = LLVMCreateMemoryBufferWithMemoryRangeCopy((const char*)bitcode,
|
||||
bitcode_len, "radeon");
|
||||
LLVMParseBitcodeInContext(ctx, buf, &module, NULL);
|
||||
LLVMDisposeMemoryBuffer(buf);
|
||||
return module;
|
||||
}
|
||||
|
||||
|
@@ -1379,7 +1379,7 @@ void radeon_llvm_finalize_module(struct radeon_llvm_context * ctx)
|
||||
LLVMAddAggressiveDCEPass(gallivm->passmgr);
|
||||
LLVMAddCFGSimplificationPass(gallivm->passmgr);
|
||||
|
||||
/* Run the passs */
|
||||
/* Run the pass */
|
||||
LLVMRunFunctionPassManager(gallivm->passmgr, ctx->main_fn);
|
||||
|
||||
LLVMDisposeBuilder(gallivm->builder);
|
||||
|
@@ -49,6 +49,7 @@ static void *radeonsi_create_compute_state(
|
||||
LLVMModuleRef mod = radeon_llvm_get_kernel_module(i, code,
|
||||
header->num_bytes);
|
||||
si_compile_llvm(rctx, &program->kernels[i], mod);
|
||||
LLVMDisposeModule(mod);
|
||||
}
|
||||
|
||||
return program;
|
||||
@@ -161,9 +162,18 @@ static void radeonsi_launch_grid(
|
||||
si_pm4_add_bo(pm4, buffer, RADEON_USAGE_READWRITE);
|
||||
}
|
||||
|
||||
/* XXX: This should be:
|
||||
* (number of compute units) * 4 * (waves per simd) - 1 */
|
||||
si_pm4_set_reg(pm4, R_00B82C_COMPUTE_MAX_WAVE_ID, 0x190 /* Default value */);
|
||||
/* This register has been moved to R_00CD20_COMPUTE_MAX_WAVE_ID
|
||||
* and is now per pipe, so it should be handled in the
|
||||
* kernel if we want to use something other than the default value,
|
||||
* which is now 0x22f.
|
||||
*/
|
||||
if (rctx->b.chip_class <= SI) {
|
||||
/* XXX: This should be:
|
||||
* (number of compute units) * 4 * (waves per simd) - 1 */
|
||||
|
||||
si_pm4_set_reg(pm4, R_00B82C_COMPUTE_MAX_WAVE_ID,
|
||||
0x190 /* Default value */);
|
||||
}
|
||||
|
||||
shader_va = r600_resource_va(ctx->screen, (void *)shader->bo);
|
||||
si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ);
|
||||
@@ -236,7 +246,21 @@ static void radeonsi_launch_grid(
|
||||
}
|
||||
|
||||
|
||||
static void si_delete_compute_state(struct pipe_context *ctx, void* state){}
|
||||
static void si_delete_compute_state(struct pipe_context *ctx, void* state){
|
||||
struct si_pipe_compute *program = (struct si_pipe_compute *)state;
|
||||
|
||||
if (!state) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (program->kernels) {
|
||||
FREE(program->kernels);
|
||||
}
|
||||
|
||||
//And then free the program itself.
|
||||
FREE(program);
|
||||
}
|
||||
|
||||
static void si_set_compute_resources(struct pipe_context * ctx_,
|
||||
unsigned start, unsigned count,
|
||||
struct pipe_surface ** surfaces) { }
|
||||
|
@@ -24,6 +24,7 @@
|
||||
**********************************************************/
|
||||
|
||||
#include "util/u_inlines.h"
|
||||
#include "util/u_prim.h"
|
||||
#include "indices/u_indices.h"
|
||||
|
||||
#include "svga_cmd.h"
|
||||
@@ -37,17 +38,25 @@
|
||||
|
||||
static enum pipe_error
|
||||
translate_indices(struct svga_hwtnl *hwtnl, struct pipe_resource *src,
|
||||
unsigned offset, unsigned nr, unsigned index_size,
|
||||
unsigned offset, unsigned prim, unsigned nr,
|
||||
unsigned index_size,
|
||||
u_translate_func translate, struct pipe_resource **out_buf)
|
||||
{
|
||||
struct pipe_context *pipe = &hwtnl->svga->pipe;
|
||||
struct pipe_transfer *src_transfer = NULL;
|
||||
struct pipe_transfer *dst_transfer = NULL;
|
||||
unsigned size = index_size * nr;
|
||||
unsigned size;
|
||||
const void *src_map = NULL;
|
||||
struct pipe_resource *dst = NULL;
|
||||
void *dst_map = NULL;
|
||||
|
||||
/* Need to trim vertex count to make sure we don't write too much data
|
||||
* to the dst buffer in the translate() call.
|
||||
*/
|
||||
u_trim_pipe_prim(prim, &nr);
|
||||
|
||||
size = index_size * nr;
|
||||
|
||||
dst = pipe_buffer_create(pipe->screen,
|
||||
PIPE_BIND_INDEX_BUFFER, PIPE_USAGE_STATIC, size);
|
||||
if (dst == NULL)
|
||||
@@ -180,7 +189,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
|
||||
ret = translate_indices(hwtnl,
|
||||
index_buffer,
|
||||
start * index_size,
|
||||
gen_nr, gen_size, gen_func, &gen_buf);
|
||||
gen_prim, gen_nr, gen_size, gen_func, &gen_buf);
|
||||
if (ret != PIPE_OK)
|
||||
goto done;
|
||||
|
||||
|
@@ -148,6 +148,8 @@ static void svga_surface_copy(struct pipe_context *pipe,
|
||||
|
||||
#endif
|
||||
|
||||
/* Mark the destination image as being defined */
|
||||
svga_define_texture_level(dtex, dst_face, dst_level);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -61,18 +61,24 @@ clCreateContextFromType(const cl_context_properties *d_props,
|
||||
void *user_data, cl_int *r_errcode) try {
|
||||
cl_platform_id d_platform;
|
||||
cl_uint num_platforms;
|
||||
cl_device_id d_dev;
|
||||
cl_int ret;
|
||||
std::vector<cl_device_id> devs;
|
||||
cl_uint num_devices;
|
||||
|
||||
ret = clGetPlatformIDs(1, &d_platform, &num_platforms);
|
||||
if (ret || !num_platforms)
|
||||
throw error(CL_INVALID_PLATFORM);
|
||||
|
||||
ret = clGetDeviceIDs(d_platform, type, 1, &d_dev, 0);
|
||||
ret = clGetDeviceIDs(d_platform, type, 0, NULL, &num_devices);
|
||||
if (ret)
|
||||
throw error(CL_DEVICE_NOT_FOUND);
|
||||
devs.resize(num_devices);
|
||||
ret = clGetDeviceIDs(d_platform, type, num_devices, devs.data(), 0);
|
||||
if (ret)
|
||||
throw error(CL_DEVICE_NOT_FOUND);
|
||||
|
||||
return clCreateContext(d_props, 1, &d_dev, pfn_notify, user_data, r_errcode);
|
||||
return clCreateContext(d_props, num_devices, devs.data(), pfn_notify,
|
||||
user_data, r_errcode);
|
||||
|
||||
} catch (error &e) {
|
||||
ret_error(r_errcode, e);
|
||||
|
@@ -269,7 +269,8 @@ namespace clover {
|
||||
|
||||
typename super::const_iterator
|
||||
end() const {
|
||||
return { f, tuple::map(ends(), os) };
|
||||
return { f, tuple::map(advances_by(size()),
|
||||
tuple::map(begins(), os)) };
|
||||
}
|
||||
|
||||
typename super::size_type
|
||||
|
@@ -89,6 +89,7 @@ dri_create_context(gl_api api,
|
||||
unsigned major_version,
|
||||
unsigned minor_version,
|
||||
uint32_t flags,
|
||||
bool notify_reset,
|
||||
unsigned *error,
|
||||
void *sharedContextPrivate);
|
||||
|
||||
|
@@ -30,6 +30,8 @@
|
||||
#
|
||||
include $(top_srcdir)/src/gallium/Automake.inc
|
||||
|
||||
LDFLAGS += -Wl,$(top_srcdir)/src/gallium/targets/egl-static/egl.link
|
||||
|
||||
AM_CFLAGS = $(PTHREAD_CFLAGS)
|
||||
AM_CPPFLAGS = \
|
||||
$(GALLIUM_CFLAGS) \
|
||||
|
3
src/gallium/targets/egl-static/egl.link
Normal file
3
src/gallium/targets/egl-static/egl.link
Normal file
@@ -0,0 +1,3 @@
|
||||
VERSION {
|
||||
{ global: _eglMain; local: *; };
|
||||
};
|
@@ -22,6 +22,8 @@
|
||||
|
||||
include $(top_srcdir)/src/gallium/Automake.inc
|
||||
|
||||
LDFLAGS += -Wl,$(top_srcdir)/src/gallium/targets/pipe-loader/pipe.link
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
$(GALLIUM_CFLAGS) \
|
||||
-I$(top_srcdir)/include \
|
||||
|
3
src/gallium/targets/pipe-loader/pipe.link
Normal file
3
src/gallium/targets/pipe-loader/pipe.link
Normal file
@@ -0,0 +1,3 @@
|
||||
VERSION {
|
||||
{global: driver_descriptor; local: *; };
|
||||
};
|
@@ -104,6 +104,24 @@ dri_get_buffers_with_format(__DRIdrawable * driDrawable,
|
||||
count, out_count, surf->dri_private);
|
||||
}
|
||||
|
||||
static int
|
||||
image_get_buffers(__DRIdrawable *driDrawable,
|
||||
unsigned int format,
|
||||
uint32_t *stamp,
|
||||
void *loaderPrivate,
|
||||
uint32_t buffer_mask,
|
||||
struct __DRIimageList *buffers)
|
||||
{
|
||||
struct gbm_dri_surface *surf = loaderPrivate;
|
||||
struct gbm_dri_device *dri = gbm_dri_device(surf->base.gbm);
|
||||
|
||||
if (dri->image_get_buffers == NULL)
|
||||
return 0;
|
||||
|
||||
return dri->image_get_buffers(driDrawable, format, stamp,
|
||||
surf->dri_private, buffer_mask, buffers);
|
||||
}
|
||||
|
||||
static const __DRIuseInvalidateExtension use_invalidate = {
|
||||
{ __DRI_USE_INVALIDATE, 1 }
|
||||
};
|
||||
@@ -120,6 +138,13 @@ const __DRIdri2LoaderExtension dri2_loader_extension = {
|
||||
dri_get_buffers_with_format,
|
||||
};
|
||||
|
||||
const __DRIimageLoaderExtension image_loader_extension = {
|
||||
{ __DRI_IMAGE_LOADER, 1 },
|
||||
image_get_buffers,
|
||||
dri_flush_front_buffer,
|
||||
};
|
||||
|
||||
|
||||
struct dri_extension_match {
|
||||
const char *name;
|
||||
int version;
|
||||
@@ -258,7 +283,8 @@ dri_screen_create(struct gbm_dri_device *dri)
|
||||
dri->extensions[0] = &image_lookup_extension.base;
|
||||
dri->extensions[1] = &use_invalidate.base;
|
||||
dri->extensions[2] = &dri2_loader_extension.base;
|
||||
dri->extensions[3] = NULL;
|
||||
dri->extensions[3] = &image_loader_extension.base;
|
||||
dri->extensions[4] = NULL;
|
||||
|
||||
if (dri->dri2 == NULL)
|
||||
return -1;
|
||||
|
@@ -52,7 +52,7 @@ struct gbm_dri_device {
|
||||
__DRIdri2LoaderExtension *loader;
|
||||
|
||||
const __DRIconfig **driver_configs;
|
||||
const __DRIextension *extensions[4];
|
||||
const __DRIextension *extensions[5];
|
||||
const __DRIextension **driver_extensions;
|
||||
|
||||
__DRIimage *(*lookup_image)(__DRIscreen *screen, void *image, void *data);
|
||||
@@ -67,6 +67,12 @@ struct gbm_dri_device {
|
||||
int *width, int *height,
|
||||
unsigned int *attachments, int count,
|
||||
int *out_count, void *data);
|
||||
int (*image_get_buffers)(__DRIdrawable *driDrawable,
|
||||
unsigned int format,
|
||||
uint32_t *stamp,
|
||||
void *loaderPrivate,
|
||||
uint32_t buffer_mask,
|
||||
struct __DRIimageList *buffers);
|
||||
|
||||
struct wl_drm *wl_drm;
|
||||
};
|
||||
|
@@ -30,13 +30,211 @@
|
||||
#include "glsl_symbol_table.h"
|
||||
#include "linker.h"
|
||||
#include "main/macros.h"
|
||||
#include "program/hash_table.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Information about a single interface block definition that we need to keep
|
||||
* track of in order to check linkage rules.
|
||||
*
|
||||
* Note: this class is expected to be short lived, so it doesn't make copies
|
||||
* of the strings it references; it simply borrows the pointers from the
|
||||
* ir_variable class.
|
||||
*/
|
||||
struct interface_block_definition
|
||||
{
|
||||
/**
|
||||
* Extract an interface block definition from an ir_variable that
|
||||
* represents either the interface instance (for named interfaces), or a
|
||||
* member of the interface (for unnamed interfaces).
|
||||
*/
|
||||
explicit interface_block_definition(const ir_variable *var)
|
||||
: type(var->get_interface_type()),
|
||||
instance_name(NULL),
|
||||
array_size(-1)
|
||||
{
|
||||
if (var->is_interface_instance()) {
|
||||
instance_name = var->name;
|
||||
if (var->type->is_array())
|
||||
array_size = var->type->length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface block type
|
||||
*/
|
||||
const glsl_type *type;
|
||||
|
||||
/**
|
||||
* For a named interface block, the instance name. Otherwise NULL.
|
||||
*/
|
||||
const char *instance_name;
|
||||
|
||||
/**
|
||||
* For an interface block array, the array size (or 0 if unsized).
|
||||
* Otherwise -1.
|
||||
*/
|
||||
int array_size;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if two interfaces match, according to intrastage interface matching
|
||||
* rules. If they do, and the first interface uses an unsized array, it will
|
||||
* be updated to reflect the array size declared in the second interface.
|
||||
*/
|
||||
bool
|
||||
intrastage_match(interface_block_definition *a,
|
||||
const interface_block_definition *b,
|
||||
ir_variable_mode mode)
|
||||
{
|
||||
/* Types must match. */
|
||||
if (a->type != b->type)
|
||||
return false;
|
||||
|
||||
/* Presence/absence of interface names must match. */
|
||||
if ((a->instance_name == NULL) != (b->instance_name == NULL))
|
||||
return false;
|
||||
|
||||
/* For uniforms, instance names need not match. For shader ins/outs,
|
||||
* it's not clear from the spec whether they need to match, but
|
||||
* Mesa's implementation relies on them matching.
|
||||
*/
|
||||
if (a->instance_name != NULL && mode != ir_var_uniform &&
|
||||
strcmp(a->instance_name, b->instance_name) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Array vs. nonarray must be consistent, and sizes must be
|
||||
* consistent, with the exception that unsized arrays match sized
|
||||
* arrays.
|
||||
*/
|
||||
if ((a->array_size == -1) != (b->array_size == -1))
|
||||
return false;
|
||||
if (b->array_size != 0) {
|
||||
if (a->array_size == 0)
|
||||
a->array_size = b->array_size;
|
||||
else if (a->array_size != b->array_size)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if two interfaces match, according to interstage (in/out) interface
|
||||
* matching rules.
|
||||
*
|
||||
* If \c extra_array_level is true, then vertex-to-geometry shader matching
|
||||
* rules are enforced (i.e. a successful match requires the consumer interface
|
||||
* to be an array and the producer interface to be a non-array).
|
||||
*/
|
||||
bool
|
||||
interstage_match(const interface_block_definition *producer,
|
||||
const interface_block_definition *consumer,
|
||||
bool extra_array_level)
|
||||
{
|
||||
/* Unsized arrays should not occur during interstage linking. They
|
||||
* should have all been assigned a size by link_intrastage_shaders.
|
||||
*/
|
||||
assert(consumer->array_size != 0);
|
||||
assert(producer->array_size != 0);
|
||||
|
||||
/* Types must match. */
|
||||
if (consumer->type != producer->type)
|
||||
return false;
|
||||
if (extra_array_level) {
|
||||
/* Consumer must be an array, and producer must not. */
|
||||
if (consumer->array_size == -1)
|
||||
return false;
|
||||
if (producer->array_size != -1)
|
||||
return false;
|
||||
} else {
|
||||
/* Array vs. nonarray must be consistent, and sizes must be consistent.
|
||||
* Since unsized arrays have been ruled out, we can check this by just
|
||||
* making sure the sizes are equal.
|
||||
*/
|
||||
if (consumer->array_size != producer->array_size)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This class keeps track of a mapping from an interface block name to the
|
||||
* necessary information about that interface block to determine whether to
|
||||
* generate a link error.
|
||||
*
|
||||
* Note: this class is expected to be short lived, so it doesn't make copies
|
||||
* of the strings it references; it simply borrows the pointers from the
|
||||
* ir_variable class.
|
||||
*/
|
||||
class interface_block_definitions
|
||||
{
|
||||
public:
|
||||
interface_block_definitions()
|
||||
: mem_ctx(ralloc_context(NULL)),
|
||||
ht(hash_table_ctor(0, hash_table_string_hash,
|
||||
hash_table_string_compare))
|
||||
{
|
||||
}
|
||||
|
||||
~interface_block_definitions()
|
||||
{
|
||||
hash_table_dtor(ht);
|
||||
ralloc_free(mem_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the interface definition having the given block name. Return
|
||||
* NULL if none is found.
|
||||
*/
|
||||
interface_block_definition *lookup(const char *block_name)
|
||||
{
|
||||
return (interface_block_definition *) hash_table_find(ht, block_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new interface definition.
|
||||
*/
|
||||
void store(const interface_block_definition &def)
|
||||
{
|
||||
interface_block_definition *hash_entry =
|
||||
rzalloc(mem_ctx, interface_block_definition);
|
||||
*hash_entry = def;
|
||||
hash_table_insert(ht, hash_entry, def.type->name);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Ralloc context for data structures allocated by this class.
|
||||
*/
|
||||
void *mem_ctx;
|
||||
|
||||
/**
|
||||
* Hash table mapping interface block name to an \c
|
||||
* interface_block_definition struct. interface_block_definition structs
|
||||
* are allocated using \c mem_ctx.
|
||||
*/
|
||||
hash_table *ht;
|
||||
};
|
||||
|
||||
|
||||
}; /* anonymous namespace */
|
||||
|
||||
|
||||
void
|
||||
validate_intrastage_interface_blocks(struct gl_shader_program *prog,
|
||||
const gl_shader **shader_list,
|
||||
unsigned num_shaders)
|
||||
{
|
||||
glsl_symbol_table interfaces;
|
||||
interface_block_definitions in_interfaces;
|
||||
interface_block_definitions out_interfaces;
|
||||
interface_block_definitions uniform_interfaces;
|
||||
|
||||
for (unsigned int i = 0; i < num_shaders; i++) {
|
||||
if (shader_list[i] == NULL)
|
||||
@@ -52,17 +250,36 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog,
|
||||
if (iface_type == NULL)
|
||||
continue;
|
||||
|
||||
const glsl_type *old_iface_type =
|
||||
interfaces.get_interface(iface_type->name,
|
||||
(enum ir_variable_mode) var->mode);
|
||||
|
||||
if (old_iface_type == NULL) {
|
||||
/* This is the first time we've seen the interface, so save
|
||||
* it into our symbol table.
|
||||
interface_block_definitions *definitions;
|
||||
switch (var->mode) {
|
||||
case ir_var_shader_in:
|
||||
definitions = &in_interfaces;
|
||||
break;
|
||||
case ir_var_shader_out:
|
||||
definitions = &out_interfaces;
|
||||
break;
|
||||
case ir_var_uniform:
|
||||
definitions = &uniform_interfaces;
|
||||
break;
|
||||
default:
|
||||
/* Only in, out, and uniform interfaces are legal, so we should
|
||||
* never get here.
|
||||
*/
|
||||
interfaces.add_interface(iface_type->name, iface_type,
|
||||
(enum ir_variable_mode) var->mode);
|
||||
} else if (old_iface_type != iface_type) {
|
||||
assert(!"illegal interface type");
|
||||
continue;
|
||||
}
|
||||
|
||||
const interface_block_definition def(var);
|
||||
interface_block_definition *prev_def =
|
||||
definitions->lookup(iface_type->name);
|
||||
|
||||
if (prev_def == NULL) {
|
||||
/* This is the first time we've seen the interface, so save
|
||||
* it into the appropriate data structure.
|
||||
*/
|
||||
definitions->store(def);
|
||||
} else if (!intrastage_match(prev_def, &def,
|
||||
(ir_variable_mode) var->mode)) {
|
||||
linker_error(prog, "definitions of interface block `%s' do not"
|
||||
" match\n", iface_type->name);
|
||||
return;
|
||||
@@ -76,7 +293,9 @@ validate_interstage_interface_blocks(struct gl_shader_program *prog,
|
||||
const gl_shader *producer,
|
||||
const gl_shader *consumer)
|
||||
{
|
||||
glsl_symbol_table interfaces;
|
||||
interface_block_definitions inout_interfaces;
|
||||
interface_block_definitions uniform_interfaces;
|
||||
const bool extra_array_level = consumer->Type == GL_GEOMETRY_SHADER;
|
||||
|
||||
/* Add non-output interfaces from the consumer to the symbol table. */
|
||||
foreach_list(node, consumer->ir) {
|
||||
@@ -84,9 +303,9 @@ validate_interstage_interface_blocks(struct gl_shader_program *prog,
|
||||
if (!var || !var->get_interface_type() || var->mode == ir_var_shader_out)
|
||||
continue;
|
||||
|
||||
interfaces.add_interface(var->get_interface_type()->name,
|
||||
var->get_interface_type(),
|
||||
(enum ir_variable_mode) var->mode);
|
||||
interface_block_definitions *definitions = var->mode == ir_var_uniform ?
|
||||
&uniform_interfaces : &inout_interfaces;
|
||||
definitions->store(interface_block_definition(var));
|
||||
}
|
||||
|
||||
/* Verify that the producer's interfaces match. */
|
||||
@@ -95,17 +314,29 @@ validate_interstage_interface_blocks(struct gl_shader_program *prog,
|
||||
if (!var || !var->get_interface_type() || var->mode == ir_var_shader_in)
|
||||
continue;
|
||||
|
||||
enum ir_variable_mode consumer_mode =
|
||||
var->mode == ir_var_uniform ? ir_var_uniform : ir_var_shader_in;
|
||||
const glsl_type *expected_type =
|
||||
interfaces.get_interface(var->get_interface_type()->name,
|
||||
consumer_mode);
|
||||
interface_block_definitions *definitions = var->mode == ir_var_uniform ?
|
||||
&uniform_interfaces : &inout_interfaces;
|
||||
interface_block_definition *consumer_def =
|
||||
definitions->lookup(var->get_interface_type()->name);
|
||||
|
||||
/* The consumer doesn't use this output block. Ignore it. */
|
||||
if (expected_type == NULL)
|
||||
if (consumer_def == NULL)
|
||||
continue;
|
||||
|
||||
if (var->get_interface_type() != expected_type) {
|
||||
const interface_block_definition producer_def(var);
|
||||
bool match;
|
||||
if (var->mode == ir_var_uniform) {
|
||||
/* Uniform matching rules are the same for interstage and intrastage
|
||||
* linking.
|
||||
*/
|
||||
match = intrastage_match(consumer_def, &producer_def,
|
||||
(ir_variable_mode) var->mode);
|
||||
} else {
|
||||
match = interstage_match(&producer_def, consumer_def,
|
||||
extra_array_level);
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
linker_error(prog, "definitions of interface block `%s' do not "
|
||||
"match\n", var->get_interface_type()->name);
|
||||
return;
|
||||
|
@@ -352,6 +352,7 @@ equals(ir_texture *a, ir_texture *b)
|
||||
if (!equals(a->lod_info.grad.dPdx, b->lod_info.grad.dPdx) ||
|
||||
!equals(a->lod_info.grad.dPdy, b->lod_info.grad.dPdy))
|
||||
return false;
|
||||
break;
|
||||
case ir_txf_ms:
|
||||
if (!equals(a->lod_info.sample_index, b->lod_info.sample_index))
|
||||
return false;
|
||||
@@ -359,6 +360,7 @@ equals(ir_texture *a, ir_texture *b)
|
||||
case ir_tg4:
|
||||
if (!equals(a->lod_info.component, b->lod_info.component))
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
assert(!"Unrecognized texture op");
|
||||
}
|
||||
|
@@ -94,8 +94,6 @@ libglx_la_SOURCES = \
|
||||
dri2_glx.c \
|
||||
dri2.c \
|
||||
dri2_query_renderer.c \
|
||||
dri3_glx.c \
|
||||
dri3_common.c \
|
||||
applegl_glx.c
|
||||
|
||||
GL_LIBS = \
|
||||
|
@@ -63,6 +63,7 @@ sources = [
|
||||
'indirect_vertex_program.c',
|
||||
'pixel.c',
|
||||
'pixelstore.c',
|
||||
'query_renderer.c',
|
||||
'render2.c',
|
||||
'renderpix.c',
|
||||
'single2.c',
|
||||
@@ -78,6 +79,9 @@ sources = [
|
||||
'glxhash.c',
|
||||
'dri2_glx.c',
|
||||
'dri2.c',
|
||||
'dri2_query_renderer.c',
|
||||
#'dri3_glx.c',
|
||||
#'dri3_common.c',
|
||||
'applegl_glx.c',
|
||||
]
|
||||
|
||||
|
@@ -159,51 +159,6 @@ dri3_unbind_context(struct glx_context *context, struct glx_context *new)
|
||||
(*psc->core->unbindContext) (pcp->driContext);
|
||||
}
|
||||
|
||||
static struct glx_context *
|
||||
dri3_create_context(struct glx_screen *base,
|
||||
struct glx_config *config_base,
|
||||
struct glx_context *shareList, int renderType)
|
||||
{
|
||||
struct dri3_context *pcp, *pcp_shared;
|
||||
struct dri3_screen *psc = (struct dri3_screen *) base;
|
||||
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
|
||||
__DRIcontext *shared = NULL;
|
||||
|
||||
if (shareList) {
|
||||
/* If the shareList context is not a DRI3 context, we cannot possibly
|
||||
* create a DRI3 context that shares it.
|
||||
*/
|
||||
if (shareList->vtable->destroy != dri3_destroy_context) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcp_shared = (struct dri3_context *) shareList;
|
||||
shared = pcp_shared->driContext;
|
||||
}
|
||||
|
||||
pcp = calloc(1, sizeof *pcp);
|
||||
if (pcp == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!glx_context_init(&pcp->base, &psc->base, &config->base)) {
|
||||
free(pcp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcp->driContext =
|
||||
(*psc->image_driver->createNewContext) (psc->driScreen,
|
||||
config->driConfig, shared, pcp);
|
||||
|
||||
if (pcp->driContext == NULL) {
|
||||
free(pcp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcp->base.vtable = &dri3_context_vtable;
|
||||
|
||||
return &pcp->base;
|
||||
}
|
||||
|
||||
static struct glx_context *
|
||||
dri3_create_context_attribs(struct glx_screen *base,
|
||||
struct glx_config *config_base,
|
||||
@@ -299,6 +254,17 @@ error_exit:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct glx_context *
|
||||
dri3_create_context(struct glx_screen *base,
|
||||
struct glx_config *config_base,
|
||||
struct glx_context *shareList, int renderType)
|
||||
{
|
||||
unsigned int error;
|
||||
|
||||
return dri3_create_context_attribs(base, config_base, shareList,
|
||||
0, NULL, &error);
|
||||
}
|
||||
|
||||
static void
|
||||
dri3_destroy_drawable(__GLXDRIdrawable *base)
|
||||
{
|
||||
|
@@ -477,7 +477,7 @@ struct glx_screen_vtable {
|
||||
unsigned *error);
|
||||
int (*query_renderer_integer)(struct glx_screen *psc,
|
||||
int attribute,
|
||||
int *value);
|
||||
unsigned int *value);
|
||||
int (*query_renderer_string)(struct glx_screen *psc,
|
||||
int attribute,
|
||||
const char **value);
|
||||
|
@@ -865,8 +865,6 @@ __glXInitialize(Display * dpy)
|
||||
** (e.g., those called in AllocAndFetchScreenConfigs).
|
||||
*/
|
||||
if (glx_direct && glx_accel) {
|
||||
if (!getenv("LIBGL_DRI3_DISABLE"))
|
||||
dpyPriv->dri3Display = dri3_create_display(dpy);
|
||||
dpyPriv->dri2Display = dri2CreateDisplay(dpy);
|
||||
dpyPriv->driDisplay = driCreateDisplay(dpy);
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ __glXQueryRendererInteger(struct glx_screen *psc, int attribute,
|
||||
unsigned int *value)
|
||||
{
|
||||
unsigned int values_for_query = 0;
|
||||
int buffer[32];
|
||||
unsigned int buffer[32];
|
||||
int err;
|
||||
|
||||
/* This probably means the caller is trying to use an extension function
|
||||
|
@@ -56,7 +56,8 @@ static bool query_renderer_string_called = false;
|
||||
static bool query_renderer_integer_called = false;
|
||||
|
||||
static int
|
||||
fake_query_renderer_integer(struct glx_screen *psc, int attribute, int *value)
|
||||
fake_query_renderer_integer(struct glx_screen *psc, int attribute,
|
||||
unsigned int *value)
|
||||
{
|
||||
(void) psc;
|
||||
(void) attribute;
|
||||
|
@@ -3,6 +3,7 @@ AM_CFLAGS = $(PTHREAD_CFLAGS)
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/gtest/include \
|
||||
-I$(top_srcdir)/src/mapi \
|
||||
-I$(top_builddir)/src/mapi \
|
||||
-I$(top_srcdir)/include
|
||||
|
||||
TESTS = shared-glapi-test
|
||||
|
@@ -10,3 +10,6 @@ if env['dri']:
|
||||
|
||||
if env['platform'] == 'windows':
|
||||
SConscript('windows/gdi/SConscript')
|
||||
|
||||
if env['platform'] == 'haiku':
|
||||
SConscript('haiku/swrast/SConscript')
|
||||
|
@@ -1515,6 +1515,9 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx,
|
||||
sizeof(struct vertex), OFFSET(x));
|
||||
_mesa_VertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE,
|
||||
sizeof(struct vertex), OFFSET(s));
|
||||
|
||||
_mesa_EnableVertexAttribArray(0);
|
||||
_mesa_EnableVertexAttribArray(1);
|
||||
}
|
||||
|
||||
/* Generate a relevant fragment shader program for the texture target */
|
||||
@@ -1591,8 +1594,6 @@ setup_glsl_blit_framebuffer(struct gl_context *ctx,
|
||||
_mesa_DeleteObjectARB(vs);
|
||||
_mesa_BindAttribLocation(ShaderProg, 0, "position");
|
||||
_mesa_BindAttribLocation(ShaderProg, 1, "texcoords");
|
||||
_mesa_EnableVertexAttribArray(0);
|
||||
_mesa_EnableVertexAttribArray(1);
|
||||
link_program_with_debug(ctx, ShaderProg);
|
||||
ralloc_free(mem_ctx);
|
||||
if (texture_2d)
|
||||
|
@@ -868,7 +868,6 @@ const __DRIimageDriverExtension driImageDriverExtension = {
|
||||
|
||||
.createNewScreen2 = driCreateNewScreen2,
|
||||
.createNewDrawable = driCreateNewDrawable,
|
||||
.createNewContext = driCreateNewContext,
|
||||
.getAPIMask = driGetAPIMask,
|
||||
.createContextAttribs = driCreateContextAttribs,
|
||||
};
|
||||
|
@@ -494,7 +494,7 @@ driIndexConfigAttrib(const __DRIconfig *config, int index,
|
||||
* Zero if a recognized value of \c param is supplied, -1 otherwise.
|
||||
*/
|
||||
int
|
||||
driQueryRendererIntegerCommon(__DRIscreen *psp, int param, int *value)
|
||||
driQueryRendererIntegerCommon(__DRIscreen *psp, int param, unsigned int *value)
|
||||
{
|
||||
switch (param) {
|
||||
case __DRI2_RENDERER_VERSION: {
|
||||
|
@@ -66,6 +66,6 @@ driIndexConfigAttrib(const __DRIconfig *config, int index,
|
||||
unsigned int *attrib, unsigned int *value);
|
||||
|
||||
int
|
||||
driQueryRendererIntegerCommon(__DRIscreen *psp, int param, int *value);
|
||||
driQueryRendererIntegerCommon(__DRIscreen *psp, int param, unsigned int *value);
|
||||
|
||||
#endif /* DRI_DEBUG_H */
|
||||
|
@@ -246,7 +246,8 @@ intel_allocate_image(int dri_format, void *loaderPrivate)
|
||||
image->offset = 0;
|
||||
|
||||
image->format = driImageFormatToGLFormat(dri_format);
|
||||
if (image->format == 0) {
|
||||
if (dri_format != __DRI_IMAGE_FORMAT_NONE &&
|
||||
image->format == MESA_FORMAT_NONE) {
|
||||
free(image);
|
||||
return NULL;
|
||||
}
|
||||
@@ -702,7 +703,7 @@ static struct __DRIimageExtensionRec intelImageExtension = {
|
||||
};
|
||||
|
||||
static int
|
||||
i915_query_renderer_integer(__DRIscreen *psp, int param, int *value)
|
||||
i915_query_renderer_integer(__DRIscreen *psp, int param, unsigned int *value)
|
||||
{
|
||||
const struct intel_screen *const intelScreen =
|
||||
(struct intel_screen *) psp->driverPrivate;
|
||||
@@ -722,9 +723,13 @@ i915_query_renderer_integer(__DRIscreen *psp, int param, int *value)
|
||||
* assume that there's some fragmentation, and we start doing extra
|
||||
* flushing, etc. That's the big cliff apps will care about.
|
||||
*/
|
||||
const unsigned long agp_bytes = drmAgpSize(psp->fd);
|
||||
size_t aper_size;
|
||||
size_t mappable_size;
|
||||
|
||||
drm_intel_get_aperture_sizes(psp->fd, &mappable_size, &aper_size);
|
||||
|
||||
const unsigned gpu_mappable_megabytes =
|
||||
(agp_bytes / (1024 * 1024)) * 3 / 4;
|
||||
(aper_size / (1024 * 1024)) * 3 / 4;
|
||||
|
||||
const long system_memory_pages = sysconf(_SC_PHYS_PAGES);
|
||||
const long system_page_size = sysconf(_SC_PAGE_SIZE);
|
||||
|
@@ -3281,20 +3281,33 @@ fs_visitor::run()
|
||||
progress = compute_to_mrf() || progress;
|
||||
} while (progress);
|
||||
|
||||
schedule_instructions(false);
|
||||
|
||||
lower_uniform_pull_constant_loads();
|
||||
|
||||
assign_curb_setup();
|
||||
assign_urb_setup();
|
||||
|
||||
schedule_instructions(SCHEDULE_PRE_NON_LIFO);
|
||||
|
||||
if (0)
|
||||
assign_regs_trivial();
|
||||
else {
|
||||
while (!assign_regs()) {
|
||||
if (failed)
|
||||
break;
|
||||
}
|
||||
if (!assign_regs(false)) {
|
||||
/* Try a non-spilling register allocation again with a different
|
||||
* scheduling heuristic.
|
||||
*/
|
||||
schedule_instructions(SCHEDULE_PRE_LIFO);
|
||||
if (!assign_regs(false)) {
|
||||
if (dispatch_width == 16) {
|
||||
fail("Failure to register allocate. Reduce number of "
|
||||
"live scalar values to avoid this.");
|
||||
} else {
|
||||
while (!assign_regs(true)) {
|
||||
if (failed)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(force_uncompressed_stack == 0);
|
||||
@@ -3309,7 +3322,7 @@ fs_visitor::run()
|
||||
if (failed)
|
||||
return false;
|
||||
|
||||
schedule_instructions(true);
|
||||
schedule_instructions(SCHEDULE_POST);
|
||||
|
||||
if (dispatch_width == 8) {
|
||||
c->prog_data.reg_blocks = brw_register_blocks(grf_used);
|
||||
|
@@ -291,7 +291,7 @@ public:
|
||||
void assign_curb_setup();
|
||||
void calculate_urb_setup();
|
||||
void assign_urb_setup();
|
||||
bool assign_regs();
|
||||
bool assign_regs(bool allow_spilling);
|
||||
void assign_regs_trivial();
|
||||
void get_used_mrfs(bool *mrf_used);
|
||||
void setup_payload_interference(struct ra_graph *g, int payload_reg_count,
|
||||
@@ -322,7 +322,7 @@ public:
|
||||
bool remove_dead_constants();
|
||||
bool remove_duplicate_mrf_writes();
|
||||
bool virtual_grf_interferes(int a, int b);
|
||||
void schedule_instructions(bool post_reg_alloc);
|
||||
void schedule_instructions(instruction_scheduler_mode mode);
|
||||
void insert_gen4_send_dependency_workarounds();
|
||||
void insert_gen4_pre_send_dependency_workarounds(fs_inst *inst);
|
||||
void insert_gen4_post_send_dependency_workarounds(fs_inst *inst);
|
||||
|
@@ -129,7 +129,8 @@ fs_visitor::opt_cse_local(bblock_t *block, exec_list *aeb)
|
||||
inst = (fs_inst *) inst->next) {
|
||||
|
||||
/* Skip some cases. */
|
||||
if (is_expression(inst) && !inst->is_partial_write())
|
||||
if (is_expression(inst) && !inst->is_partial_write() &&
|
||||
(inst->dst.file != HW_REG || inst->dst.is_null()))
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
|
@@ -757,7 +757,7 @@ fs_generator::generate_scratch_write(fs_inst *inst, struct brw_reg src)
|
||||
retype(brw_message_reg(inst->base_mrf + 1), BRW_REGISTER_TYPE_UD),
|
||||
retype(src, BRW_REGISTER_TYPE_UD));
|
||||
brw_oword_block_write_scratch(p, brw_message_reg(inst->base_mrf),
|
||||
inst->mlen, inst->offset);
|
||||
dispatch_width / 8, inst->offset);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -417,7 +417,7 @@ fs_visitor::setup_mrf_hack_interference(struct ra_graph *g, int first_mrf_node)
|
||||
}
|
||||
|
||||
bool
|
||||
fs_visitor::assign_regs()
|
||||
fs_visitor::assign_regs(bool allow_spilling)
|
||||
{
|
||||
/* Most of this allocation was written for a reg_width of 1
|
||||
* (dispatch_width == 8). In extending to 16-wide, the code was
|
||||
@@ -496,14 +496,10 @@ fs_visitor::assign_regs()
|
||||
if (reg == -1) {
|
||||
fail("no register to spill:\n");
|
||||
dump_instructions();
|
||||
} else if (dispatch_width == 16) {
|
||||
fail("Failure to register allocate. Reduce number of live scalar "
|
||||
"values to avoid this.");
|
||||
} else {
|
||||
spill_reg(reg);
|
||||
} else if (allow_spilling) {
|
||||
spill_reg(reg);
|
||||
}
|
||||
|
||||
|
||||
ralloc_free(g);
|
||||
|
||||
return false;
|
||||
|
@@ -34,26 +34,31 @@
|
||||
#include "glsl/glsl_types.h"
|
||||
#include "glsl/ir.h"
|
||||
#include "glsl/ir_builder.h"
|
||||
#include "glsl/ir_rvalue_visitor.h"
|
||||
|
||||
using namespace ir_builder;
|
||||
|
||||
class brw_lower_offset_array_visitor : public ir_hierarchical_visitor {
|
||||
class brw_lower_offset_array_visitor : public ir_rvalue_visitor {
|
||||
public:
|
||||
brw_lower_offset_array_visitor()
|
||||
{
|
||||
progress = false;
|
||||
}
|
||||
|
||||
ir_visitor_status visit_leave(ir_texture *ir);
|
||||
void handle_rvalue(ir_rvalue **rv);
|
||||
|
||||
bool progress;
|
||||
};
|
||||
|
||||
ir_visitor_status
|
||||
brw_lower_offset_array_visitor::visit_leave(ir_texture *ir)
|
||||
void
|
||||
brw_lower_offset_array_visitor::handle_rvalue(ir_rvalue **rv)
|
||||
{
|
||||
if (*rv == NULL || (*rv)->ir_type != ir_type_texture)
|
||||
return;
|
||||
|
||||
ir_texture *ir = (ir_texture *) *rv;
|
||||
if (ir->op != ir_tg4 || !ir->offset || !ir->offset->type->is_array())
|
||||
return visit_continue;
|
||||
return;
|
||||
|
||||
void *mem_ctx = ralloc_parent(ir);
|
||||
|
||||
@@ -68,10 +73,9 @@ brw_lower_offset_array_visitor::visit_leave(ir_texture *ir)
|
||||
base_ir->insert_before(assign(var, swizzle_w(tex), 1 << i));
|
||||
}
|
||||
|
||||
base_ir->replace_with(new (mem_ctx) ir_dereference_variable(var));
|
||||
*rv = new (mem_ctx) ir_dereference_variable(var);
|
||||
|
||||
progress = true;
|
||||
return visit_continue;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
@@ -56,29 +56,12 @@ using namespace brw;
|
||||
|
||||
static bool debug = false;
|
||||
|
||||
class instruction_scheduler;
|
||||
|
||||
class schedule_node : public exec_node
|
||||
{
|
||||
public:
|
||||
schedule_node(backend_instruction *inst, const struct brw_context *brw)
|
||||
{
|
||||
this->inst = inst;
|
||||
this->child_array_size = 0;
|
||||
this->children = NULL;
|
||||
this->child_latency = NULL;
|
||||
this->child_count = 0;
|
||||
this->parent_count = 0;
|
||||
this->unblocked_time = 0;
|
||||
this->cand_generation = 0;
|
||||
|
||||
/* We can't measure Gen6 timings directly but expect them to be much
|
||||
* closer to Gen7 than Gen4.
|
||||
*/
|
||||
if (brw->gen >= 6)
|
||||
set_latency_gen7(brw->is_haswell);
|
||||
else
|
||||
set_latency_gen4();
|
||||
}
|
||||
|
||||
schedule_node(backend_instruction *inst, instruction_scheduler *sched);
|
||||
void set_latency_gen4();
|
||||
void set_latency_gen7(bool is_haswell);
|
||||
|
||||
@@ -408,15 +391,24 @@ schedule_node::set_latency_gen7(bool is_haswell)
|
||||
|
||||
class instruction_scheduler {
|
||||
public:
|
||||
instruction_scheduler(backend_visitor *v, int grf_count, bool post_reg_alloc)
|
||||
instruction_scheduler(backend_visitor *v, int grf_count,
|
||||
instruction_scheduler_mode mode)
|
||||
{
|
||||
this->bv = v;
|
||||
this->mem_ctx = ralloc_context(NULL);
|
||||
this->grf_count = grf_count;
|
||||
this->instructions.make_empty();
|
||||
this->instructions_to_schedule = 0;
|
||||
this->post_reg_alloc = post_reg_alloc;
|
||||
this->post_reg_alloc = (mode == SCHEDULE_POST);
|
||||
this->mode = mode;
|
||||
this->time = 0;
|
||||
if (!post_reg_alloc) {
|
||||
this->remaining_grf_uses = rzalloc_array(mem_ctx, int, grf_count);
|
||||
this->grf_active = rzalloc_array(mem_ctx, bool, grf_count);
|
||||
} else {
|
||||
this->remaining_grf_uses = NULL;
|
||||
this->grf_active = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
~instruction_scheduler()
|
||||
@@ -442,6 +434,10 @@ public:
|
||||
*/
|
||||
virtual int issue_time(backend_instruction *inst) = 0;
|
||||
|
||||
virtual void count_remaining_grf_uses(backend_instruction *inst) = 0;
|
||||
virtual void update_register_pressure(backend_instruction *inst) = 0;
|
||||
virtual int get_register_pressure_benefit(backend_instruction *inst) = 0;
|
||||
|
||||
void schedule_instructions(backend_instruction *next_block_header);
|
||||
|
||||
void *mem_ctx;
|
||||
@@ -452,27 +448,116 @@ public:
|
||||
int time;
|
||||
exec_list instructions;
|
||||
backend_visitor *bv;
|
||||
|
||||
instruction_scheduler_mode mode;
|
||||
|
||||
/**
|
||||
* Number of instructions left to schedule that reference each vgrf.
|
||||
*
|
||||
* Used so that we can prefer scheduling instructions that will end the
|
||||
* live intervals of multiple variables, to reduce register pressure.
|
||||
*/
|
||||
int *remaining_grf_uses;
|
||||
|
||||
/**
|
||||
* Tracks whether each VGRF has had an instruction scheduled that uses it.
|
||||
*
|
||||
* This is used to estimate whether scheduling a new instruction will
|
||||
* increase register pressure.
|
||||
*/
|
||||
bool *grf_active;
|
||||
};
|
||||
|
||||
class fs_instruction_scheduler : public instruction_scheduler
|
||||
{
|
||||
public:
|
||||
fs_instruction_scheduler(fs_visitor *v, int grf_count, bool post_reg_alloc);
|
||||
fs_instruction_scheduler(fs_visitor *v, int grf_count,
|
||||
instruction_scheduler_mode mode);
|
||||
void calculate_deps();
|
||||
bool is_compressed(fs_inst *inst);
|
||||
schedule_node *choose_instruction_to_schedule();
|
||||
int issue_time(backend_instruction *inst);
|
||||
fs_visitor *v;
|
||||
|
||||
void count_remaining_grf_uses(backend_instruction *inst);
|
||||
void update_register_pressure(backend_instruction *inst);
|
||||
int get_register_pressure_benefit(backend_instruction *inst);
|
||||
};
|
||||
|
||||
fs_instruction_scheduler::fs_instruction_scheduler(fs_visitor *v,
|
||||
int grf_count,
|
||||
bool post_reg_alloc)
|
||||
: instruction_scheduler(v, grf_count, post_reg_alloc),
|
||||
instruction_scheduler_mode mode)
|
||||
: instruction_scheduler(v, grf_count, mode),
|
||||
v(v)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
fs_instruction_scheduler::count_remaining_grf_uses(backend_instruction *be)
|
||||
{
|
||||
fs_inst *inst = (fs_inst *)be;
|
||||
|
||||
if (!remaining_grf_uses)
|
||||
return;
|
||||
|
||||
if (inst->dst.file == GRF)
|
||||
remaining_grf_uses[inst->dst.reg]++;
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (inst->src[i].file != GRF)
|
||||
continue;
|
||||
|
||||
remaining_grf_uses[inst->src[i].reg]++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fs_instruction_scheduler::update_register_pressure(backend_instruction *be)
|
||||
{
|
||||
fs_inst *inst = (fs_inst *)be;
|
||||
|
||||
if (!remaining_grf_uses)
|
||||
return;
|
||||
|
||||
if (inst->dst.file == GRF) {
|
||||
remaining_grf_uses[inst->dst.reg]--;
|
||||
grf_active[inst->dst.reg] = true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (inst->src[i].file == GRF) {
|
||||
remaining_grf_uses[inst->src[i].reg]--;
|
||||
grf_active[inst->src[i].reg] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
fs_instruction_scheduler::get_register_pressure_benefit(backend_instruction *be)
|
||||
{
|
||||
fs_inst *inst = (fs_inst *)be;
|
||||
int benefit = 0;
|
||||
|
||||
if (inst->dst.file == GRF) {
|
||||
if (remaining_grf_uses[inst->dst.reg] == 1)
|
||||
benefit += v->virtual_grf_sizes[inst->dst.reg];
|
||||
if (!grf_active[inst->dst.reg])
|
||||
benefit -= v->virtual_grf_sizes[inst->dst.reg];
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (inst->src[i].file != GRF)
|
||||
continue;
|
||||
|
||||
if (remaining_grf_uses[inst->src[i].reg] == 1)
|
||||
benefit += v->virtual_grf_sizes[inst->src[i].reg];
|
||||
if (!grf_active[inst->src[i].reg])
|
||||
benefit -= v->virtual_grf_sizes[inst->src[i].reg];
|
||||
}
|
||||
|
||||
return benefit;
|
||||
}
|
||||
|
||||
class vec4_instruction_scheduler : public instruction_scheduler
|
||||
{
|
||||
public:
|
||||
@@ -481,19 +566,64 @@ public:
|
||||
schedule_node *choose_instruction_to_schedule();
|
||||
int issue_time(backend_instruction *inst);
|
||||
vec4_visitor *v;
|
||||
|
||||
void count_remaining_grf_uses(backend_instruction *inst);
|
||||
void update_register_pressure(backend_instruction *inst);
|
||||
int get_register_pressure_benefit(backend_instruction *inst);
|
||||
};
|
||||
|
||||
vec4_instruction_scheduler::vec4_instruction_scheduler(vec4_visitor *v,
|
||||
int grf_count)
|
||||
: instruction_scheduler(v, grf_count, true),
|
||||
: instruction_scheduler(v, grf_count, SCHEDULE_POST),
|
||||
v(v)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
vec4_instruction_scheduler::count_remaining_grf_uses(backend_instruction *be)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
vec4_instruction_scheduler::update_register_pressure(backend_instruction *be)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
vec4_instruction_scheduler::get_register_pressure_benefit(backend_instruction *be)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
schedule_node::schedule_node(backend_instruction *inst,
|
||||
instruction_scheduler *sched)
|
||||
{
|
||||
struct brw_context *brw = sched->bv->brw;
|
||||
|
||||
this->inst = inst;
|
||||
this->child_array_size = 0;
|
||||
this->children = NULL;
|
||||
this->child_latency = NULL;
|
||||
this->child_count = 0;
|
||||
this->parent_count = 0;
|
||||
this->unblocked_time = 0;
|
||||
this->cand_generation = 0;
|
||||
|
||||
/* We can't measure Gen6 timings directly but expect them to be much
|
||||
* closer to Gen7 than Gen4.
|
||||
*/
|
||||
if (!sched->post_reg_alloc)
|
||||
this->latency = 1;
|
||||
else if (brw->gen >= 6)
|
||||
set_latency_gen7(brw->is_haswell);
|
||||
else
|
||||
set_latency_gen4();
|
||||
}
|
||||
|
||||
void
|
||||
instruction_scheduler::add_inst(backend_instruction *inst)
|
||||
{
|
||||
schedule_node *n = new(mem_ctx) schedule_node(inst, bv->brw);
|
||||
schedule_node *n = new(mem_ctx) schedule_node(inst, this);
|
||||
|
||||
assert(!inst->is_head_sentinel());
|
||||
assert(!inst->is_tail_sentinel());
|
||||
@@ -1037,40 +1167,59 @@ fs_instruction_scheduler::choose_instruction_to_schedule()
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Prefer instructions that recently became available for scheduling.
|
||||
* These are the things that are most likely to (eventually) make a
|
||||
* variable dead and reduce register pressure. Typical register
|
||||
* pressure estimates don't work for us because most of our pressure
|
||||
* comes from texturing, where no single instruction to schedule will
|
||||
* make a vec4 value dead.
|
||||
/* Most important: If we can definitely reduce register pressure, do
|
||||
* so immediately.
|
||||
*/
|
||||
if (n->cand_generation > chosen->cand_generation) {
|
||||
int register_pressure_benefit = get_register_pressure_benefit(n->inst);
|
||||
int chosen_register_pressure_benefit =
|
||||
get_register_pressure_benefit(chosen->inst);
|
||||
|
||||
if (register_pressure_benefit > 0 &&
|
||||
register_pressure_benefit > chosen_register_pressure_benefit) {
|
||||
chosen = n;
|
||||
continue;
|
||||
} else if (n->cand_generation < chosen->cand_generation) {
|
||||
} else if (chosen_register_pressure_benefit > 0 &&
|
||||
(register_pressure_benefit <
|
||||
chosen_register_pressure_benefit)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* On MRF-using chips, prefer non-SEND instructions. If we don't do
|
||||
* this, then because we prefer instructions that just became
|
||||
* candidates, we'll end up in a pattern of scheduling a SEND, then
|
||||
* the MRFs for the next SEND, then the next SEND, then the MRFs,
|
||||
* etc., without ever consuming the results of a send.
|
||||
*/
|
||||
if (v->brw->gen < 7) {
|
||||
fs_inst *chosen_inst = (fs_inst *)chosen->inst;
|
||||
|
||||
/* We use regs_written > 1 as our test for the kind of send
|
||||
* instruction to avoid -- only sends generate many regs, and a
|
||||
* single-result send is probably actually reducing register
|
||||
* pressure.
|
||||
if (mode == SCHEDULE_PRE_LIFO) {
|
||||
/* Prefer instructions that recently became available for
|
||||
* scheduling. These are the things that are most likely to
|
||||
* (eventually) make a variable dead and reduce register pressure.
|
||||
* Typical register pressure estimates don't work for us because
|
||||
* most of our pressure comes from texturing, where no single
|
||||
* instruction to schedule will make a vec4 value dead.
|
||||
*/
|
||||
if (inst->regs_written <= 1 && chosen_inst->regs_written > 1) {
|
||||
if (n->cand_generation > chosen->cand_generation) {
|
||||
chosen = n;
|
||||
continue;
|
||||
} else if (inst->regs_written > chosen_inst->regs_written) {
|
||||
} else if (n->cand_generation < chosen->cand_generation) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* On MRF-using chips, prefer non-SEND instructions. If we don't
|
||||
* do this, then because we prefer instructions that just became
|
||||
* candidates, we'll end up in a pattern of scheduling a SEND,
|
||||
* then the MRFs for the next SEND, then the next SEND, then the
|
||||
* MRFs, etc., without ever consuming the results of a send.
|
||||
*/
|
||||
if (v->brw->gen < 7) {
|
||||
fs_inst *chosen_inst = (fs_inst *)chosen->inst;
|
||||
|
||||
/* We use regs_written > 1 as our test for the kind of send
|
||||
* instruction to avoid -- only sends generate many regs, and a
|
||||
* single-result send is probably actually reducing register
|
||||
* pressure.
|
||||
*/
|
||||
if (inst->regs_written <= 1 && chosen_inst->regs_written > 1) {
|
||||
chosen = n;
|
||||
continue;
|
||||
} else if (inst->regs_written > chosen_inst->regs_written) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* For instructions pushed on the cands list at the same time, prefer
|
||||
@@ -1153,6 +1302,7 @@ instruction_scheduler::schedule_instructions(backend_instruction *next_block_hea
|
||||
chosen->remove();
|
||||
next_block_header->insert_before(chosen->inst);
|
||||
instructions_to_schedule--;
|
||||
update_register_pressure(chosen->inst);
|
||||
|
||||
/* Update the clock for how soon an instruction could start after the
|
||||
* chosen one.
|
||||
@@ -1228,6 +1378,15 @@ instruction_scheduler::run(exec_list *all_instructions)
|
||||
bv->dump_instructions();
|
||||
}
|
||||
|
||||
/* Populate the remaining GRF uses array to improve the pre-regalloc
|
||||
* scheduling.
|
||||
*/
|
||||
if (remaining_grf_uses) {
|
||||
foreach_list(node, all_instructions) {
|
||||
count_remaining_grf_uses((backend_instruction *)node);
|
||||
}
|
||||
}
|
||||
|
||||
while (!next_block_header->is_tail_sentinel()) {
|
||||
/* Add things to be scheduled until we get to a new BB. */
|
||||
while (!next_block_header->is_tail_sentinel()) {
|
||||
@@ -1255,18 +1414,18 @@ instruction_scheduler::run(exec_list *all_instructions)
|
||||
}
|
||||
|
||||
void
|
||||
fs_visitor::schedule_instructions(bool post_reg_alloc)
|
||||
fs_visitor::schedule_instructions(instruction_scheduler_mode mode)
|
||||
{
|
||||
int grf_count;
|
||||
if (post_reg_alloc)
|
||||
if (mode == SCHEDULE_POST)
|
||||
grf_count = grf_used;
|
||||
else
|
||||
grf_count = virtual_grf_count;
|
||||
|
||||
fs_instruction_scheduler sched(this, grf_count, post_reg_alloc);
|
||||
fs_instruction_scheduler sched(this, grf_count, mode);
|
||||
sched.run(&instructions);
|
||||
|
||||
if (unlikely(INTEL_DEBUG & DEBUG_WM) && post_reg_alloc) {
|
||||
if (unlikely(INTEL_DEBUG & DEBUG_WM) && mode == SCHEDULE_POST) {
|
||||
printf("fs%d estimated execution time: %d cycles\n",
|
||||
dispatch_width, sched.time);
|
||||
}
|
||||
|
@@ -59,6 +59,12 @@ public:
|
||||
bool predicate_inverse;
|
||||
};
|
||||
|
||||
enum instruction_scheduler_mode {
|
||||
SCHEDULE_PRE_NON_LIFO,
|
||||
SCHEDULE_PRE_LIFO,
|
||||
SCHEDULE_POST,
|
||||
};
|
||||
|
||||
class backend_visitor : public ir_visitor {
|
||||
public:
|
||||
|
||||
|
@@ -86,7 +86,7 @@ intel_horizontal_texture_alignment_unit(struct brw_context *brw,
|
||||
|
||||
static unsigned int
|
||||
intel_vertical_texture_alignment_unit(struct brw_context *brw,
|
||||
gl_format format)
|
||||
gl_format format, bool multisampled)
|
||||
{
|
||||
/**
|
||||
* From the "Alignment Unit Size" section of various specs, namely:
|
||||
@@ -110,8 +110,6 @@ intel_vertical_texture_alignment_unit(struct brw_context *brw,
|
||||
*
|
||||
* On SNB+, non-special cases can be overridden by setting the SURFACE_STATE
|
||||
* "Surface Vertical Alignment" field to VALIGN_2 or VALIGN_4.
|
||||
*
|
||||
* We currently don't support multisampling.
|
||||
*/
|
||||
if (_mesa_is_format_compressed(format))
|
||||
return 4;
|
||||
@@ -119,6 +117,9 @@ intel_vertical_texture_alignment_unit(struct brw_context *brw,
|
||||
if (format == MESA_FORMAT_S8)
|
||||
return brw->gen >= 7 ? 8 : 4;
|
||||
|
||||
if (multisampled)
|
||||
return 4;
|
||||
|
||||
GLenum base_format = _mesa_get_format_base_format(format);
|
||||
|
||||
if (brw->gen >= 6 &&
|
||||
@@ -276,8 +277,10 @@ brw_miptree_layout_texture_3d(struct brw_context *brw,
|
||||
void
|
||||
brw_miptree_layout(struct brw_context *brw, struct intel_mipmap_tree *mt)
|
||||
{
|
||||
bool multisampled = mt->num_samples > 1;
|
||||
mt->align_w = intel_horizontal_texture_alignment_unit(brw, mt->format);
|
||||
mt->align_h = intel_vertical_texture_alignment_unit(brw, mt->format);
|
||||
mt->align_h =
|
||||
intel_vertical_texture_alignment_unit(brw, mt->format, multisampled);
|
||||
|
||||
switch (mt->target) {
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
|
@@ -890,7 +890,7 @@ brw_upload_abo_surfaces(struct brw_context *brw,
|
||||
struct intel_buffer_object *intel_bo =
|
||||
intel_buffer_object(binding->BufferObject);
|
||||
drm_intel_bo *bo = intel_bufferobj_buffer(
|
||||
brw, intel_bo, binding->Offset, bo->size - binding->Offset);
|
||||
brw, intel_bo, binding->Offset, intel_bo->Base.Size - binding->Offset);
|
||||
|
||||
brw->vtbl.create_raw_surface(brw, bo, binding->Offset,
|
||||
bo->size - binding->Offset,
|
||||
|
@@ -300,7 +300,8 @@ intel_allocate_image(int dri_format, void *loaderPrivate)
|
||||
image->offset = 0;
|
||||
|
||||
image->format = driImageFormatToGLFormat(dri_format);
|
||||
if (image->format == 0) {
|
||||
if (dri_format != __DRI_IMAGE_FORMAT_NONE &&
|
||||
image->format == MESA_FORMAT_NONE) {
|
||||
free(image);
|
||||
return NULL;
|
||||
}
|
||||
@@ -804,7 +805,7 @@ static struct __DRIimageExtensionRec intelImageExtension = {
|
||||
};
|
||||
|
||||
static int
|
||||
brw_query_renderer_integer(__DRIscreen *psp, int param, int *value)
|
||||
brw_query_renderer_integer(__DRIscreen *psp, int param, unsigned int *value)
|
||||
{
|
||||
const struct intel_screen *const intelScreen =
|
||||
(struct intel_screen *) psp->driverPrivate;
|
||||
@@ -823,10 +824,14 @@ brw_query_renderer_integer(__DRIscreen *psp, int param, int *value)
|
||||
/* Once a batch uses more than 75% of the maximum mappable size, we
|
||||
* assume that there's some fragmentation, and we start doing extra
|
||||
* flushing, etc. That's the big cliff apps will care about.
|
||||
*
|
||||
* Can only map 2G onto the GPU through the GTT.
|
||||
*/
|
||||
const unsigned gpu_mappable_megabytes = 2 * 1024 * 3 / 4;
|
||||
size_t aper_size;
|
||||
size_t mappable_size;
|
||||
|
||||
drm_intel_get_aperture_sizes(psp->fd, &mappable_size, &aper_size);
|
||||
|
||||
const unsigned gpu_mappable_megabytes =
|
||||
(aper_size / (1024 * 1024)) * 3 / 4;
|
||||
|
||||
const long system_memory_pages = sysconf(_SC_PHYS_PAGES);
|
||||
const long system_page_size = sysconf(_SC_PAGE_SIZE);
|
||||
|
@@ -664,6 +664,7 @@ dri_create_context(gl_api api,
|
||||
unsigned major_version,
|
||||
unsigned minor_version,
|
||||
uint32_t flags,
|
||||
bool notify_reset,
|
||||
unsigned *error,
|
||||
void *sharedContextPrivate)
|
||||
{
|
||||
|
28
src/mesa/drivers/haiku/swrast/SConscript
Normal file
28
src/mesa/drivers/haiku/swrast/SConscript
Normal file
@@ -0,0 +1,28 @@
|
||||
Import('*')
|
||||
|
||||
env = env.Clone()
|
||||
|
||||
env.Append(CPPPATH = [
|
||||
'#/src/mapi',
|
||||
'#/src/mesa',
|
||||
'#/src/mesa/main',
|
||||
'/boot/system/develop/headers/private',
|
||||
Dir('../../../mapi'), # src/mapi build path for python-generated GL API files/headers
|
||||
])
|
||||
|
||||
env.Prepend(LIBS = [
|
||||
glsl,
|
||||
mesa,
|
||||
])
|
||||
|
||||
sources = [
|
||||
'SoftwareRast.cpp'
|
||||
]
|
||||
|
||||
# Disallow undefined symbols
|
||||
#env.Append(SHLINKFLAGS = ['-Wl,-z,defs'])
|
||||
|
||||
libswrast = env.SharedLibrary(
|
||||
target = 'swrast',
|
||||
source = sources
|
||||
)
|
697
src/mesa/drivers/haiku/swrast/SoftwareRast.cpp
Normal file
697
src/mesa/drivers/haiku/swrast/SoftwareRast.cpp
Normal file
@@ -0,0 +1,697 @@
|
||||
/*
|
||||
* Copyright 2006-2012, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Jérôme Duval, korli@users.berlios.de
|
||||
* Philippe Houdoin, philippe.houdoin@free.fr
|
||||
* Artur Wyszynski, harakash@gmail.com
|
||||
* Alexander von Gluck, kallisti5@unixzen.com
|
||||
*/
|
||||
|
||||
|
||||
#include <kernel/image.h>
|
||||
#include "SoftwareRast.h"
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <interface/DirectWindowPrivate.h>
|
||||
#include <GraphicsDefs.h>
|
||||
#include <Screen.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
#include "extensions.h"
|
||||
#include "drivers/common/driverfuncs.h"
|
||||
#include "drivers/common/meta.h"
|
||||
#include "main/api_exec.h"
|
||||
#include "main/colormac.h"
|
||||
#include "main/cpuinfo.h"
|
||||
#include "main/buffers.h"
|
||||
#include "main/formats.h"
|
||||
#include "main/framebuffer.h"
|
||||
#include "main/renderbuffer.h"
|
||||
#include "main/version.h"
|
||||
#include "main/vtxfmt.h"
|
||||
#include "swrast/swrast.h"
|
||||
#include "swrast/s_renderbuffer.h"
|
||||
#include "swrast_setup/swrast_setup.h"
|
||||
#include "tnl/tnl.h"
|
||||
#include "tnl/t_context.h"
|
||||
#include "tnl/t_pipeline.h"
|
||||
#include "vbo/vbo.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
# define TRACE(x...) printf("MesaSoftwareRast: " x)
|
||||
# define CALLED() printf("MesaSoftwareRast: %s\n", __PRETTY_FUNCTION__)
|
||||
#else
|
||||
# define TRACE(x...)
|
||||
# define CALLED()
|
||||
#endif
|
||||
|
||||
#define ERROR(x...) printf("MesaSoftwareRast: " x)
|
||||
}
|
||||
|
||||
|
||||
extern const char* color_space_name(color_space space);
|
||||
|
||||
|
||||
extern "C" _EXPORT BGLRenderer*
|
||||
instantiate_gl_renderer(BGLView* view, ulong options,
|
||||
BGLDispatcher* dispatcher)
|
||||
{
|
||||
return new MesaSoftwareRast(view, options, dispatcher);
|
||||
}
|
||||
|
||||
|
||||
MesaSoftwareRast::MesaSoftwareRast(BGLView* view, ulong options,
|
||||
BGLDispatcher* dispatcher)
|
||||
: BGLRenderer(view, options, dispatcher),
|
||||
fBitmap(NULL),
|
||||
fDirectModeEnabled(false),
|
||||
fInfo(NULL),
|
||||
fInfoLocker("info locker"),
|
||||
fVisual(NULL),
|
||||
fFrameBuffer(NULL),
|
||||
fFrontRenderBuffer(NULL),
|
||||
fBackRenderBuffer(NULL),
|
||||
fColorSpace(B_NO_COLOR_SPACE)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
fColorSpace = BScreen(GLView()->Window()).ColorSpace();
|
||||
|
||||
// We force single buffering for the time being
|
||||
options &= ~BGL_DOUBLE;
|
||||
|
||||
const GLboolean rgbFlag = ((options & BGL_INDEX) == 0);
|
||||
const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA);
|
||||
const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE);
|
||||
const GLboolean stereoFlag = false;
|
||||
const GLint depth = (options & BGL_DEPTH) ? 16 : 0;
|
||||
const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
|
||||
const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
|
||||
const GLint red = rgbFlag ? 8 : 0;
|
||||
const GLint green = rgbFlag ? 8 : 0;
|
||||
const GLint blue = rgbFlag ? 8 : 0;
|
||||
const GLint alpha = alphaFlag ? 8 : 0;
|
||||
|
||||
fOptions = options; // | BGL_INDIRECT;
|
||||
struct dd_function_table functions;
|
||||
|
||||
fVisual = _mesa_create_visual(dblFlag, stereoFlag, red, green,
|
||||
blue, alpha, depth, stencil, accum, accum, accum,
|
||||
alpha ? accum : 0, 1);
|
||||
|
||||
// Initialize device driver function table
|
||||
_mesa_init_driver_functions(&functions);
|
||||
|
||||
functions.GetString = _GetString;
|
||||
functions.UpdateState = _UpdateState;
|
||||
functions.MapRenderbuffer = _RenderBufferMap;
|
||||
functions.Flush = _Flush;
|
||||
|
||||
// create core context
|
||||
// We inherit gl_context to this class
|
||||
_mesa_initialize_context(this, API_OPENGL_COMPAT, fVisual, NULL,
|
||||
&functions);
|
||||
|
||||
/* Initialize the software rasterizer and helper modules. */
|
||||
_swrast_CreateContext(this);
|
||||
_vbo_CreateContext(this);
|
||||
_tnl_CreateContext(this);
|
||||
_swsetup_CreateContext(this);
|
||||
_swsetup_Wakeup(this);
|
||||
|
||||
// Use default TCL pipeline
|
||||
TNL_CONTEXT(this)->Driver.RunPipeline = _tnl_run_pipeline;
|
||||
|
||||
_mesa_meta_init(this);
|
||||
_mesa_enable_sw_extensions(this);
|
||||
|
||||
_mesa_compute_version(this);
|
||||
|
||||
_mesa_initialize_dispatch_tables(this);
|
||||
_mesa_initialize_vbo_vtxfmt(this);
|
||||
|
||||
// create core framebuffer
|
||||
fFrameBuffer = _mesa_create_framebuffer(fVisual);
|
||||
if (fFrameBuffer == NULL) {
|
||||
ERROR("%s: Unable to calloc GL FrameBuffer!\n", __func__);
|
||||
_mesa_destroy_visual(fVisual);
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup front render buffer
|
||||
fFrontRenderBuffer = _NewRenderBuffer(true);
|
||||
if (fFrontRenderBuffer == NULL) {
|
||||
ERROR("%s: FrontRenderBuffer is requested but unallocated!\n",
|
||||
__func__);
|
||||
_mesa_destroy_visual(fVisual);
|
||||
free(fFrameBuffer);
|
||||
return;
|
||||
}
|
||||
_mesa_add_renderbuffer(fFrameBuffer, BUFFER_FRONT_LEFT,
|
||||
&fFrontRenderBuffer->Base);
|
||||
|
||||
// Setup back render buffer (if requested)
|
||||
if (fVisual->doubleBufferMode) {
|
||||
fBackRenderBuffer = _NewRenderBuffer(false);
|
||||
if (fBackRenderBuffer == NULL) {
|
||||
ERROR("%s: BackRenderBuffer is requested but unallocated!\n",
|
||||
__func__);
|
||||
_mesa_destroy_visual(fVisual);
|
||||
free(fFrameBuffer);
|
||||
return;
|
||||
}
|
||||
_mesa_add_renderbuffer(fFrameBuffer, BUFFER_BACK_LEFT,
|
||||
&fBackRenderBuffer->Base);
|
||||
}
|
||||
|
||||
_swrast_add_soft_renderbuffers(fFrameBuffer, GL_FALSE,
|
||||
fVisual->haveDepthBuffer, fVisual->haveStencilBuffer,
|
||||
fVisual->haveAccumBuffer, alphaFlag, GL_FALSE);
|
||||
|
||||
BRect bounds = view->Bounds();
|
||||
fWidth = (GLint)bounds.Width();
|
||||
fHeight = (GLint)bounds.Height();
|
||||
|
||||
// some stupid applications (Quake2) don't even think about calling LockGL()
|
||||
// before using glGetString and its glGet*() friends...
|
||||
// so make sure there is at least a valid context.
|
||||
|
||||
if (!_mesa_get_current_context()) {
|
||||
LockGL();
|
||||
// not needed, we don't have a looper yet: UnlockLooper();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MesaSoftwareRast::~MesaSoftwareRast()
|
||||
{
|
||||
CALLED();
|
||||
_swsetup_DestroyContext(this);
|
||||
_swrast_DestroyContext(this);
|
||||
_tnl_DestroyContext(this);
|
||||
_vbo_DestroyContext(this);
|
||||
_mesa_destroy_visual(fVisual);
|
||||
_mesa_destroy_framebuffer(fFrameBuffer);
|
||||
_mesa_destroy_context(this);
|
||||
|
||||
free(fInfo);
|
||||
free(fFrameBuffer);
|
||||
|
||||
delete fBitmap;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::LockGL()
|
||||
{
|
||||
CALLED();
|
||||
BGLRenderer::LockGL();
|
||||
|
||||
_mesa_make_current(this, fFrameBuffer, fFrameBuffer);
|
||||
|
||||
color_space colorSpace = BScreen(GLView()->Window()).ColorSpace();
|
||||
|
||||
GLuint width = fWidth;
|
||||
GLuint height = fHeight;
|
||||
|
||||
BAutolock lock(fInfoLocker);
|
||||
if (fDirectModeEnabled && fInfo != NULL) {
|
||||
width = fInfo->window_bounds.right
|
||||
- fInfo->window_bounds.left + 1;
|
||||
height = fInfo->window_bounds.bottom
|
||||
- fInfo->window_bounds.top + 1;
|
||||
}
|
||||
|
||||
if (fColorSpace != colorSpace) {
|
||||
fColorSpace = colorSpace;
|
||||
_SetupRenderBuffer(&fFrontRenderBuffer->Base, fColorSpace);
|
||||
if (fVisual->doubleBufferMode)
|
||||
_SetupRenderBuffer(&fBackRenderBuffer->Base, fColorSpace);
|
||||
}
|
||||
|
||||
_CheckResize(width, height);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::UnlockGL()
|
||||
{
|
||||
CALLED();
|
||||
_mesa_make_current(this, NULL, NULL);
|
||||
BGLRenderer::UnlockGL();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::SwapBuffers(bool VSync)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
if (!fBitmap)
|
||||
return;
|
||||
|
||||
if (fVisual->doubleBufferMode)
|
||||
_mesa_notifySwapBuffers(this);
|
||||
|
||||
if (!fDirectModeEnabled || fInfo == NULL) {
|
||||
if (GLView()->LockLooperWithTimeout(1000) == B_OK) {
|
||||
GLView()->DrawBitmap(fBitmap, B_ORIGIN);
|
||||
GLView()->UnlockLooper();
|
||||
}
|
||||
} else {
|
||||
// TODO: Here the BGLView needs to be drawlocked.
|
||||
_CopyToDirect();
|
||||
}
|
||||
|
||||
if (VSync) {
|
||||
BScreen screen(GLView()->Window());
|
||||
screen.WaitForRetrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::Draw(BRect updateRect)
|
||||
{
|
||||
CALLED();
|
||||
if (fBitmap && (!fDirectModeEnabled || (fInfo == NULL)))
|
||||
GLView()->DrawBitmap(fBitmap, updateRect, updateRect);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MesaSoftwareRast::CopyPixelsOut(BPoint location, BBitmap* bitmap)
|
||||
{
|
||||
CALLED();
|
||||
color_space scs = fBitmap->ColorSpace();
|
||||
color_space dcs = bitmap->ColorSpace();
|
||||
|
||||
if (scs != dcs && (scs != B_RGBA32 || dcs != B_RGB32)) {
|
||||
fprintf(stderr, "CopyPixelsOut(): incompatible color space: %s != %s\n",
|
||||
color_space_name(scs),
|
||||
color_space_name(dcs));
|
||||
return B_BAD_TYPE;
|
||||
}
|
||||
|
||||
BRect sr = fBitmap->Bounds();
|
||||
BRect dr = bitmap->Bounds();
|
||||
|
||||
sr = sr & dr.OffsetBySelf(location);
|
||||
dr = sr.OffsetByCopy(-location.x, -location.y);
|
||||
|
||||
uint8* ps = (uint8*)fBitmap->Bits();
|
||||
uint8* pd = (uint8*)bitmap->Bits();
|
||||
uint32* s;
|
||||
uint32* d;
|
||||
uint32 y;
|
||||
for (y = (uint32)sr.top; y <= (uint32)sr.bottom; y++) {
|
||||
s = (uint32*)(ps + y * fBitmap->BytesPerRow());
|
||||
s += (uint32)sr.left;
|
||||
|
||||
d = (uint32*)(pd + (y + (uint32)(dr.top - sr.top))
|
||||
* bitmap->BytesPerRow());
|
||||
d += (uint32)dr.left;
|
||||
|
||||
memcpy(d, s, dr.IntegerWidth() * 4);
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MesaSoftwareRast::CopyPixelsIn(BBitmap* bitmap, BPoint location)
|
||||
{
|
||||
CALLED();
|
||||
color_space scs = bitmap->ColorSpace();
|
||||
color_space dcs = fBitmap->ColorSpace();
|
||||
|
||||
if (scs != dcs && (dcs != B_RGBA32 || scs != B_RGB32)) {
|
||||
fprintf(stderr, "CopyPixelsIn(): incompatible color space: %s != %s\n",
|
||||
color_space_name(scs),
|
||||
color_space_name(dcs));
|
||||
return B_BAD_TYPE;
|
||||
}
|
||||
|
||||
BRect sr = bitmap->Bounds();
|
||||
BRect dr = fBitmap->Bounds();
|
||||
|
||||
sr = sr & dr.OffsetBySelf(location);
|
||||
dr = sr.OffsetByCopy(-location.x, -location.y);
|
||||
|
||||
uint8* ps = (uint8*)bitmap->Bits();
|
||||
uint8* pd = (uint8*)fBitmap->Bits();
|
||||
uint32* s;
|
||||
uint32* d;
|
||||
uint32 y;
|
||||
for (y = (uint32)sr.top; y <= (uint32)sr.bottom; y++) {
|
||||
s = (uint32*)(ps + y * bitmap->BytesPerRow());
|
||||
s += (uint32)sr.left;
|
||||
|
||||
d = (uint32*)(pd + (y + (uint32)(dr.top - sr.top))
|
||||
* fBitmap->BytesPerRow());
|
||||
d += (uint32)dr.left;
|
||||
|
||||
memcpy(d, s, dr.IntegerWidth() * 4);
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::EnableDirectMode(bool enabled)
|
||||
{
|
||||
fDirectModeEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::DirectConnected(direct_buffer_info* info)
|
||||
{
|
||||
// TODO: I'm not sure we need to do this: BGLView already
|
||||
// keeps a local copy of the direct_buffer_info passed by
|
||||
// BDirectWindow::DirectConnected().
|
||||
BAutolock lock(fInfoLocker);
|
||||
if (info) {
|
||||
if (!fInfo) {
|
||||
fInfo = (direct_buffer_info*)malloc(DIRECT_BUFFER_INFO_AREA_SIZE);
|
||||
if (!fInfo)
|
||||
return;
|
||||
}
|
||||
memcpy(fInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE);
|
||||
} else if (fInfo) {
|
||||
free(fInfo);
|
||||
fInfo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::FrameResized(float width, float height)
|
||||
{
|
||||
BAutolock lock(fInfoLocker);
|
||||
_CheckResize((GLuint)width, (GLuint)height);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::_CheckResize(GLuint newWidth, GLuint newHeight)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
if (fBitmap && newWidth == fWidth
|
||||
&& newHeight == fHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
_mesa_resize_framebuffer(this, fFrameBuffer, newWidth, newHeight);
|
||||
fHeight = newHeight;
|
||||
fWidth = newWidth;
|
||||
|
||||
_AllocateBitmap();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::_AllocateBitmap()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
// allocate new size of back buffer bitmap
|
||||
delete fBitmap;
|
||||
fBitmap = NULL;
|
||||
|
||||
if (fWidth < 1 || fHeight < 1) {
|
||||
TRACE("%s: Cannot allocate bitmap < 1x1!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
BRect rect(0.0, 0.0, fWidth - 1, fHeight - 1);
|
||||
fBitmap = new BBitmap(rect, fColorSpace);
|
||||
|
||||
#if 0
|
||||
// Used for platform optimized drawing
|
||||
for (uint i = 0; i < fHeight; i++) {
|
||||
fRowAddr[fHeight - i - 1] = (GLvoid *)((GLubyte *)fBitmap->Bits()
|
||||
+ i * fBitmap->BytesPerRow());
|
||||
}
|
||||
#endif
|
||||
|
||||
fFrameBuffer->Width = fWidth;
|
||||
fFrameBuffer->Height = fHeight;
|
||||
TRACE("%s: Bitmap Size: %" B_PRIu32 "\n", __func__, fBitmap->BitsLength());
|
||||
|
||||
fFrontRenderBuffer->Buffer = (GLubyte*)fBitmap->Bits();
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - static
|
||||
|
||||
|
||||
const GLubyte*
|
||||
MesaSoftwareRast::_GetString(gl_context* ctx, GLenum name)
|
||||
{
|
||||
switch (name) {
|
||||
case GL_VENDOR:
|
||||
return (const GLubyte*) "Mesa Project";
|
||||
case GL_RENDERER:
|
||||
return (const GLubyte*) "Software Rasterizer";
|
||||
default:
|
||||
// Let core library handle all other cases
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::_UpdateState(gl_context* ctx, GLuint new_state)
|
||||
{
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
CALLED();
|
||||
_swrast_InvalidateState(ctx, new_state);
|
||||
_swsetup_InvalidateState(ctx, new_state);
|
||||
_vbo_InvalidateState(ctx, new_state);
|
||||
_tnl_InvalidateState(ctx, new_state);
|
||||
}
|
||||
|
||||
|
||||
GLboolean
|
||||
MesaSoftwareRast::_RenderBufferStorage(gl_context* ctx,
|
||||
struct gl_renderbuffer* render, GLenum internalFormat,
|
||||
GLuint width, GLuint height)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
render->Width = width;
|
||||
render->Height = height;
|
||||
|
||||
struct swrast_renderbuffer *swRenderBuffer = swrast_renderbuffer(render);
|
||||
|
||||
swRenderBuffer->RowStride = width * _mesa_get_format_bytes(render->Format);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
GLboolean
|
||||
MesaSoftwareRast::_RenderBufferStorageMalloc(gl_context* ctx,
|
||||
struct gl_renderbuffer* render, GLenum internalFormat,
|
||||
GLuint width, GLuint height)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
render->Width = width;
|
||||
render->Height = height;
|
||||
|
||||
struct swrast_renderbuffer *swRenderBuffer = swrast_renderbuffer(render);
|
||||
|
||||
if (swRenderBuffer != NULL) {
|
||||
free(swRenderBuffer->Buffer);
|
||||
swRenderBuffer->RowStride
|
||||
= width * _mesa_get_format_bytes(render->Format);
|
||||
|
||||
uint32 size = swRenderBuffer->RowStride * height;
|
||||
TRACE("%s: Allocate %" B_PRIu32 " bytes for RenderBuffer\n",
|
||||
__func__, size);
|
||||
swRenderBuffer->Buffer = (GLubyte*)malloc(size);
|
||||
if (!swRenderBuffer->Buffer) {
|
||||
ERROR("%s: Memory allocation failure!\n", __func__);
|
||||
return GL_FALSE;
|
||||
}
|
||||
} else {
|
||||
ERROR("%s: Couldn't obtain software renderbuffer!\n",
|
||||
__func__);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::_Flush(gl_context* ctx)
|
||||
{
|
||||
CALLED();
|
||||
MesaSoftwareRast* driverContext = static_cast<MesaSoftwareRast*>(ctx);
|
||||
|
||||
//MesaSoftwareRast* driverContext = (MesaSoftwareRast*)ctx->DriverCtx;
|
||||
if ((driverContext->fOptions & BGL_DOUBLE) == 0) {
|
||||
// TODO: SwapBuffers() can call _CopyToDirect(), which should
|
||||
// be always called with with the BGLView drawlocked.
|
||||
// This is not always the case if called from here.
|
||||
driverContext->SwapBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct swrast_renderbuffer*
|
||||
MesaSoftwareRast::_NewRenderBuffer(bool front)
|
||||
{
|
||||
CALLED();
|
||||
struct swrast_renderbuffer *swRenderBuffer
|
||||
= (struct swrast_renderbuffer*)calloc(1, sizeof *swRenderBuffer);
|
||||
|
||||
if (!swRenderBuffer) {
|
||||
ERROR("%s: Failed calloc RenderBuffer\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_mesa_init_renderbuffer(&swRenderBuffer->Base, 0);
|
||||
|
||||
swRenderBuffer->Base.ClassID = HAIKU_SWRAST_RENDERBUFFER_CLASS;
|
||||
swRenderBuffer->Base.RefCount = 1;
|
||||
swRenderBuffer->Base.Delete = _RenderBufferDelete;
|
||||
|
||||
if (!front)
|
||||
swRenderBuffer->Base.AllocStorage = _RenderBufferStorageMalloc;
|
||||
else
|
||||
swRenderBuffer->Base.AllocStorage = _RenderBufferStorage;
|
||||
|
||||
if (_SetupRenderBuffer(&swRenderBuffer->Base, fColorSpace) != B_OK) {
|
||||
free(swRenderBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return swRenderBuffer;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
MesaSoftwareRast::_SetupRenderBuffer(struct gl_renderbuffer* rb,
|
||||
color_space colorSpace)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
rb->InternalFormat = GL_RGBA;
|
||||
|
||||
switch (colorSpace) {
|
||||
case B_RGBA32:
|
||||
rb->_BaseFormat = GL_RGBA;
|
||||
rb->Format = MESA_FORMAT_ARGB8888;
|
||||
break;
|
||||
case B_RGB32:
|
||||
rb->_BaseFormat = GL_RGB;
|
||||
rb->Format = MESA_FORMAT_XRGB8888;
|
||||
break;
|
||||
case B_RGB24:
|
||||
rb->_BaseFormat = GL_RGB;
|
||||
rb->Format = MESA_FORMAT_RGB888;
|
||||
break;
|
||||
case B_RGB16:
|
||||
rb->_BaseFormat = GL_RGB;
|
||||
rb->Format = MESA_FORMAT_RGB565;
|
||||
break;
|
||||
case B_RGB15:
|
||||
rb->_BaseFormat = GL_RGB;
|
||||
rb->Format = MESA_FORMAT_ARGB1555;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unsupported screen color space %s\n",
|
||||
color_space_name(fColorSpace));
|
||||
debugger("Unsupported OpenGL color space");
|
||||
return B_ERROR;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*! Y inverted Map RenderBuffer function
|
||||
We use a BBitmap for storage which has Y inverted.
|
||||
If the Mesa provided Map function ever allows external
|
||||
control of this we can omit this function.
|
||||
*/
|
||||
void
|
||||
MesaSoftwareRast::_RenderBufferMap(gl_context *ctx,
|
||||
struct gl_renderbuffer *rb, GLuint x, GLuint y, GLuint w, GLuint h,
|
||||
GLbitfield mode, GLubyte **mapOut, GLint *rowStrideOut)
|
||||
{
|
||||
if (rb->ClassID == HAIKU_SWRAST_RENDERBUFFER_CLASS) {
|
||||
struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
|
||||
const GLuint bpp = _mesa_get_format_bytes(rb->Format);
|
||||
GLint rowStride = rb->Width * bpp; // in Bytes
|
||||
|
||||
y = rb->Height - y - 1;
|
||||
|
||||
*rowStrideOut = -rowStride;
|
||||
*mapOut = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
|
||||
} else {
|
||||
_swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
|
||||
mapOut, rowStrideOut);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::_RenderBufferDelete(struct gl_context *ctx,
|
||||
struct gl_renderbuffer* rb)
|
||||
{
|
||||
CALLED();
|
||||
if (rb != NULL) {
|
||||
struct swrast_renderbuffer *swRenderBuffer
|
||||
= swrast_renderbuffer(rb);
|
||||
if (swRenderBuffer != NULL)
|
||||
free(swRenderBuffer->Buffer);
|
||||
}
|
||||
free(rb);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MesaSoftwareRast::_CopyToDirect()
|
||||
{
|
||||
BAutolock lock(fInfoLocker);
|
||||
|
||||
// check the bitmap size still matches the size
|
||||
if (fInfo->window_bounds.bottom - fInfo->window_bounds.top
|
||||
!= fBitmap->Bounds().IntegerHeight()
|
||||
|| fInfo->window_bounds.right - fInfo->window_bounds.left
|
||||
!= fBitmap->Bounds().IntegerWidth())
|
||||
return;
|
||||
|
||||
uint8 bytesPerPixel = fInfo->bits_per_pixel / 8;
|
||||
uint32 bytesPerRow = fBitmap->BytesPerRow();
|
||||
for (uint32 i = 0; i < fInfo->clip_list_count; i++) {
|
||||
clipping_rect *clip = &fInfo->clip_list[i];
|
||||
int32 height = clip->bottom - clip->top + 1;
|
||||
int32 bytesWidth
|
||||
= (clip->right - clip->left + 1) * bytesPerPixel;
|
||||
uint8* p = (uint8*)fInfo->bits + clip->top
|
||||
* fInfo->bytes_per_row + clip->left * bytesPerPixel;
|
||||
uint8* b = (uint8*)fBitmap->Bits()
|
||||
+ (clip->top - fInfo->window_bounds.top) * bytesPerRow
|
||||
+ (clip->left - fInfo->window_bounds.left)
|
||||
* bytesPerPixel;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
memcpy(p, b, bytesWidth);
|
||||
p += fInfo->bytes_per_row;
|
||||
b += bytesPerRow;
|
||||
}
|
||||
}
|
||||
}
|
95
src/mesa/drivers/haiku/swrast/SoftwareRast.h
Normal file
95
src/mesa/drivers/haiku/swrast/SoftwareRast.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2006-2012, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Jérôme Duval, korli@users.berlios.de
|
||||
* Philippe Houdoin, philippe.houdoin@free.fr
|
||||
* Artur Wyszynski, harakash@gmail.com
|
||||
*/
|
||||
#ifndef MESASOFTWARERENDERER_H
|
||||
#define MESASOFTWARERENDERER_H
|
||||
|
||||
|
||||
#define HAIKU_SWRAST_RENDERBUFFER_CLASS 0x737752 // swR
|
||||
|
||||
|
||||
#include "GLRenderer.h"
|
||||
|
||||
extern "C" {
|
||||
#include "context.h"
|
||||
#include "main/version.h"
|
||||
#include "swrast/s_chan.h"
|
||||
#include "swrast/s_context.h"
|
||||
}
|
||||
|
||||
|
||||
class MesaSoftwareRast : public BGLRenderer, public gl_context {
|
||||
public:
|
||||
MesaSoftwareRast(BGLView* view,
|
||||
ulong bgl_options,
|
||||
BGLDispatcher* dispatcher);
|
||||
virtual ~MesaSoftwareRast();
|
||||
|
||||
virtual void LockGL();
|
||||
virtual void UnlockGL();
|
||||
|
||||
virtual void SwapBuffers(bool VSync = false);
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual status_t CopyPixelsOut(BPoint source, BBitmap* dest);
|
||||
virtual status_t CopyPixelsIn(BBitmap* source, BPoint dest);
|
||||
virtual void FrameResized(float width, float height);
|
||||
|
||||
virtual void EnableDirectMode(bool enabled);
|
||||
virtual void DirectConnected(direct_buffer_info* info);
|
||||
|
||||
private:
|
||||
static const GLubyte* _GetString(gl_context* ctx, GLenum name);
|
||||
void _CheckResize(GLuint newWidth, GLuint newHeight);
|
||||
static void _UpdateState(gl_context* ctx, GLuint newState);
|
||||
static void _Flush(gl_context *ctx);
|
||||
|
||||
struct swrast_renderbuffer* _NewRenderBuffer(bool front);
|
||||
status_t _SetupRenderBuffer(struct gl_renderbuffer* rb,
|
||||
color_space colorSpace);
|
||||
|
||||
/* Mesa callbacks */
|
||||
static void _RenderBufferDelete(struct gl_context *ctx,
|
||||
struct gl_renderbuffer* rb);
|
||||
static GLboolean _RenderBufferStorage(gl_context* ctx,
|
||||
struct gl_renderbuffer* render,
|
||||
GLenum internalFormat,
|
||||
GLuint width, GLuint height);
|
||||
static GLboolean _RenderBufferStorageMalloc(gl_context* ctx,
|
||||
struct gl_renderbuffer* render,
|
||||
GLenum internalFormat,
|
||||
GLuint width, GLuint height);
|
||||
static void _RenderBufferMap(gl_context *ctx,
|
||||
struct gl_renderbuffer *rb,
|
||||
GLuint x, GLuint y, GLuint w, GLuint h,
|
||||
GLbitfield mode, GLubyte **mapOut,
|
||||
GLint *rowStrideOut);
|
||||
|
||||
void _AllocateBitmap();
|
||||
void _CopyToDirect();
|
||||
|
||||
BBitmap* fBitmap;
|
||||
bool fDirectModeEnabled;
|
||||
direct_buffer_info* fInfo;
|
||||
BLocker fInfoLocker;
|
||||
ulong fOptions;
|
||||
|
||||
gl_config* fVisual;
|
||||
|
||||
struct gl_framebuffer* fFrameBuffer;
|
||||
struct swrast_renderbuffer* fFrontRenderBuffer;
|
||||
struct swrast_renderbuffer* fBackRenderBuffer;
|
||||
|
||||
GLuint fWidth;
|
||||
GLuint fHeight;
|
||||
color_space fColorSpace;
|
||||
|
||||
void* fRowAddr[SWRAST_MAX_HEIGHT];
|
||||
};
|
||||
|
||||
#endif // MESASOFTWARERENDERER_H
|
39
src/mesa/drivers/haiku/swrast/SoftwareRast.rdef
Normal file
39
src/mesa/drivers/haiku/swrast/SoftwareRast.rdef
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
resource app_signature "application/x-vnd.Haiku-swrast";
|
||||
|
||||
resource app_version {
|
||||
major = 9,
|
||||
middle = 0,
|
||||
minor = 0,
|
||||
variety = 0,
|
||||
internal = 0,
|
||||
short_info = "Software Rasterizer",
|
||||
long_info = "Haiku Mesa Software GL Rasterizer"
|
||||
};
|
||||
|
||||
resource vector_icon {
|
||||
$"6E6369660A0200140294A9FF18020014028DFFFF97058C0500020006023B10B7"
|
||||
$"37F036BA1A993D466848C719BEBE2000919292FFD5D5D5020016023900000000"
|
||||
$"000000003EE0004AE00048E0005EF884C702000203392E8D383001BAD97F3C12"
|
||||
$"8B4786BD48B8AD0D97BBFFFF7B4168DBE9FF4168DB97020002023A0C1238D099"
|
||||
$"BE44203F4BD14B38844678240DF56A7D9FE1EA064CC704016B0500090A044024"
|
||||
$"2438404C5C380A044028243C40505C3C0A042438243B5C3C5C380608BFBE4D59"
|
||||
$"4D59515957575659585560406044603C5E3A5C3CCB4FBFBA5E3ECA9DC11F564B"
|
||||
$"584A544C504C0606AF0F2F3D2F3D393D4034BF593542324130432F42364432C0"
|
||||
$"3FBC5A2F48354A2F480608AE9A22303EB5BD3AB42542B755422E412F3C29322D"
|
||||
$"32223C0204263726372538263F253E263F304430443143303C313D303C02043D"
|
||||
$"423D423C433D4A3C493D4A495049504A4F49474A484947060DAEAAAE014E445A"
|
||||
$"3456365E325E3D5D3F5A3A5542544E4D573A4E364439463342324A2242310A0A"
|
||||
$"0002020102403CA00C88888C8CC1401673C40D6544F2950A01010002403CA000"
|
||||
$"0000000000401673C40D65446CF80A08020304023EC16A0000000000003EC16A"
|
||||
$"45DD1844C6550A030105123EC16A0000000000003EC16A45DD1844C655011784"
|
||||
$"22040A040105023EC16A0000000000003EC16A45DD1844C6550A030108123EC1"
|
||||
$"6A0000000000003EC16A45DD1844C65501178422040A0503080706023EC16A00"
|
||||
$"00000000003EC16A45DD1844C6550A030206071A3EC16A0000000000003EC16A"
|
||||
$"45DD1844C65510FF0215810004178222040A060106023EC16A0000000000003E"
|
||||
$"C16A45DD1844C6550A070107023EC16A0000000000003EC16A45DD1844C655"
|
||||
};
|
@@ -197,6 +197,14 @@ osmesa_choose_line_function( struct gl_context *ctx )
|
||||
const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
|
||||
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
|
||||
if (ctx->DrawBuffer &&
|
||||
ctx->DrawBuffer->Visual.redBits == 32) {
|
||||
/* the special-case line functions in this file don't work
|
||||
* for float color channels.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctx->RenderMode != GL_RENDER) return NULL;
|
||||
if (ctx->Line.SmoothFlag) return NULL;
|
||||
if (ctx->Texture._EnabledUnits) return NULL;
|
||||
@@ -298,6 +306,14 @@ osmesa_choose_triangle_function( struct gl_context *ctx )
|
||||
const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
|
||||
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||
|
||||
if (ctx->DrawBuffer &&
|
||||
ctx->DrawBuffer->Visual.redBits == 32) {
|
||||
/* the special-case triangle functions in this file don't work
|
||||
* for float color channels.
|
||||
*/
|
||||
return (swrast_tri_func) NULL;
|
||||
}
|
||||
|
||||
if (ctx->RenderMode != GL_RENDER) return (swrast_tri_func) NULL;
|
||||
if (ctx->Polygon.SmoothFlag) return (swrast_tri_func) NULL;
|
||||
if (ctx->Polygon.StippleFlag) return (swrast_tri_func) NULL;
|
||||
|
@@ -1469,6 +1469,18 @@ check_vbo(AEcontext *actx, struct gl_buffer_object *vbo)
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
update_derived_client_arrays(struct gl_context *ctx)
|
||||
{
|
||||
struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
|
||||
|
||||
if (arrayObj->NewArrays) {
|
||||
_mesa_update_array_object_client_arrays(ctx, arrayObj);
|
||||
arrayObj->NewArrays = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a list of per-vertex functions to call for each glArrayElement call.
|
||||
* These functions access the array data (i.e. glVertex, glColor, glNormal,
|
||||
@@ -1486,12 +1498,6 @@ _ae_update_state(struct gl_context *ctx)
|
||||
|
||||
actx->nr_vbos = 0;
|
||||
|
||||
if (arrayObj->NewArrays) {
|
||||
/* update the derived client arrays */
|
||||
_mesa_update_array_object_client_arrays(ctx, arrayObj);
|
||||
arrayObj->NewArrays = 0;
|
||||
}
|
||||
|
||||
/* conventional vertex arrays */
|
||||
if (arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) {
|
||||
aa->array = &arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR_INDEX];
|
||||
@@ -1618,6 +1624,8 @@ _ae_map_vbos(struct gl_context *ctx)
|
||||
if (actx->mapped_vbos)
|
||||
return;
|
||||
|
||||
update_derived_client_arrays(ctx);
|
||||
|
||||
if (actx->NewState)
|
||||
_ae_update_state(ctx);
|
||||
|
||||
@@ -1669,6 +1677,8 @@ _ae_ArrayElement(GLint elt)
|
||||
const struct _glapi_table * const disp = GET_DISPATCH();
|
||||
GLboolean do_map;
|
||||
|
||||
update_derived_client_arrays(ctx);
|
||||
|
||||
/* If PrimitiveRestart is enabled and the index is the RestartIndex
|
||||
* then we call PrimitiveRestartNV and return.
|
||||
*/
|
||||
|
@@ -494,7 +494,7 @@ init_program_limits(struct gl_context *ctx, GLenum type,
|
||||
prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
|
||||
prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS;
|
||||
prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
|
||||
prog->MaxUniformComponents = MAX_GEOMETRY_UNIFORM_COMPONENTS;
|
||||
prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
|
||||
prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */
|
||||
prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */
|
||||
break;
|
||||
|
@@ -7,6 +7,7 @@ AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/gtest/include \
|
||||
-I$(top_srcdir)/src/mapi \
|
||||
-I$(top_srcdir)/src/mesa \
|
||||
-I$(top_builddir)/src/mesa \
|
||||
-I$(top_srcdir)/include \
|
||||
$(DEFINES) $(INCLUDE_DIRS)
|
||||
|
||||
|
@@ -390,11 +390,6 @@ update_array(struct gl_context *ctx,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!update_array_format(ctx, func, attrib, legalTypesMask, sizeMin, sizeMax,
|
||||
size, type, normalized, integer, 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (stride < 0) {
|
||||
_mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
|
||||
return;
|
||||
@@ -418,6 +413,11 @@ update_array(struct gl_context *ctx,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!update_array_format(ctx, func, attrib, legalTypesMask, sizeMin,
|
||||
sizeMax, size, type, normalized, integer, 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset the vertex attrib binding */
|
||||
vertex_attrib_binding(ctx, attrib, attrib);
|
||||
|
||||
|
Reference in New Issue
Block a user