diff options
author | Christoph Bumiller <[email protected]> | 2010-08-18 14:37:47 +0200 |
---|---|---|
committer | Christoph Bumiller <[email protected]> | 2010-08-18 14:37:47 +0200 |
commit | 3e54d63429fe7ca5db3c75c181abbaf7a7f55724 (patch) | |
tree | e129c36aaef712525f0a04fc5b06c445e3cf84df | |
parent | eaab76457818fad0926b84c663440e8987e1f19f (diff) | |
parent | 85d9bc236d6a8ff8f12cbc2150f8c3740354f573 (diff) |
Merge remote branch 'origin/master' into nv50-compiler
618 files changed, 17004 insertions, 12706 deletions
diff --git a/common.py b/common.py index f7dbe55aa8a..7a14a2c026d 100644 --- a/common.py +++ b/common.py @@ -87,7 +87,7 @@ def AddOptions(opts): opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine, allowed_values=('generic', 'ppc', 'x86', 'x86_64'))) opts.Add(EnumOption('platform', 'target platform', default_platform, - allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'embedded', 'cygwin'))) + allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'embedded', 'cygwin', 'sunos5', 'freebsd8'))) opts.Add('toolchain', 'compiler toolchain', 'default') opts.Add(BoolOption('llvm', 'use LLVM', default_llvm)) opts.Add(BoolOption('dri', 'build DRI drivers', default_dri)) diff --git a/configs/autoconf.in b/configs/autoconf.in index 7c6f123cac0..c7611a6f781 100644 --- a/configs/autoconf.in +++ b/configs/autoconf.in @@ -123,7 +123,7 @@ GLUT_LIB_DEPS = -L$(TOP)/$(LIB_DIR) @GLUT_MESA_DEPS@ \ GLW_LIB_DEPS = -L$(TOP)/$(LIB_DIR) @GLW_MESA_DEPS@ \ $(EXTRA_LIB_PATH) @GLW_LIB_DEPS@ APP_LIB_DEPS = $(EXTRA_LIB_PATH) @APP_LIB_DEPS@ -GLESv1_CM_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv1_LIB_DEPS@ +GLESv1_CM_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv1_CM_LIB_DEPS@ GLESv2_LIB_DEPS = $(EXTRA_LIB_PATH) @GLESv2_LIB_DEPS@ VG_LIB_DEPS = $(EXTRA_LIB_PATH) @VG_LIB_DEPS@ diff --git a/configure.ac b/configure.ac index 96195976a0e..9f3006230eb 100644 --- a/configure.ac +++ b/configure.ac @@ -643,7 +643,7 @@ AC_SUBST([GL_PC_REQ_PRIV]) AC_SUBST([GL_PC_LIB_PRIV]) AC_SUBST([GL_PC_CFLAGS]) AC_SUBST([DRI_PC_REQ_PRIV]) -AC_SUBST([GLESv1_LIB_DEPS]) +AC_SUBST([GLESv1_CM_LIB_DEPS]) AC_SUBST([GLESv1_CM_PC_LIB_PRIV]) AC_SUBST([GLESv2_LIB_DEPS]) AC_SUBST([GLESv2_PC_LIB_PRIV]) diff --git a/scons/gallium.py b/scons/gallium.py index f03716bad8a..03a4ef58815 100644 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -295,7 +295,6 @@ def generate(env): # - http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html ccflags += [ '-Wall', - '-Wmissing-field-initializers', '-Wno-long-long', '-ffast-math', '-fmessage-length=0', # be nice to Eclipse @@ -304,6 +303,10 @@ def generate(env): '-Wmissing-prototypes', '-std=gnu99', ] + if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.0'): + ccflags += [ + '-Wmissing-field-initializers', + ] if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.2'): ccflags += [ '-Werror=pointer-arith', diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index c6d79a64e8a..efb93bcf06b 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -177,9 +177,9 @@ EGLint dri2_to_egl_attribute_map[] = { EGL_Y_INVERTED_NOK, /* __DRI_ATTRIB_YINVERTED */ }; -static void +static struct dri2_egl_config * dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, - int depth, xcb_visualtype_t *visual) + int depth, EGLint surface_type) { struct dri2_egl_config *conf; struct dri2_egl_display *dri2_dpy; @@ -192,6 +192,10 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, _eglInitConfig(&base, disp, id); i = 0; + double_buffer = 0; + bind_to_texture_rgb = 0; + bind_to_texture_rgba = 0; + while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) { switch (attrib) { case __DRI_ATTRIB_RENDER_TYPE: @@ -242,35 +246,27 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, * return in the getBuffer callback to get the behaviour we want. */ if (double_buffer) - return; + return NULL; - if (visual != NULL) { - if (depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE)) - return; + if (depth > 0 && depth != _eglGetConfigKey(&base, EGL_BUFFER_SIZE)) + return NULL; - _eglSetConfigKey(&base, EGL_SURFACE_TYPE, - EGL_WINDOW_BIT | EGL_PIXMAP_BIT | EGL_PBUFFER_BIT | - EGL_SWAP_BEHAVIOR_PRESERVED_BIT); + _eglSetConfigKey(&base, EGL_NATIVE_RENDERABLE, EGL_TRUE); - _eglSetConfigKey(&base, EGL_NATIVE_VISUAL_ID, visual->visual_id); - _eglSetConfigKey(&base, EGL_NATIVE_VISUAL_TYPE, visual->_class); - } else { - _eglSetConfigKey(&base, EGL_SURFACE_TYPE, - EGL_PIXMAP_BIT | EGL_PBUFFER_BIT); + _eglSetConfigKey(&base, EGL_SURFACE_TYPE, surface_type); + if (surface_type & (EGL_PIXMAP_BIT | EGL_PBUFFER_BIT)) { + _eglSetConfigKey(&base, EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb); + if (_eglGetConfigKey(&base, EGL_ALPHA_SIZE) > 0) + _eglSetConfigKey(&base, + EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba); } - _eglSetConfigKey(&base, EGL_NATIVE_RENDERABLE, EGL_TRUE); - _eglSetConfigKey(&base, EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb); - if (_eglGetConfigKey(&base, EGL_ALPHA_SIZE) > 0) - _eglSetConfigKey(&base, - EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba); - _eglSetConfigKey(&base, EGL_RENDERABLE_TYPE, disp->ClientAPIsMask); _eglSetConfigKey(&base, EGL_CONFORMANT, disp->ClientAPIsMask); if (!_eglValidateConfig(&base, EGL_FALSE)) { _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id); - return; + return NULL; } conf = malloc(sizeof *conf); @@ -279,6 +275,8 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, conf->dri_config = dri_config; _eglAddConfig(disp, &conf->base); } + + return conf; } /** @@ -613,10 +611,19 @@ dri2_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy, xcb_depth_iterator_t d; xcb_visualtype_t *visuals; int i, j, id; + struct dri2_egl_config *conf; + EGLint surface_type; s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); d = xcb_screen_allowed_depths_iterator(s.data); id = 1; + + surface_type = + EGL_WINDOW_BIT | + EGL_PIXMAP_BIT | + EGL_PBUFFER_BIT | + EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + while (d.rem > 0) { EGLBoolean class_added[6] = { 0, }; @@ -626,9 +633,16 @@ dri2_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy, continue; class_added[visuals[i]._class] = EGL_TRUE; - for (j = 0; dri2_dpy->driver_configs[j]; j++) - dri2_add_config(disp, dri2_dpy->driver_configs[j], - id++, d.data->depth, &visuals[i]); + for (j = 0; dri2_dpy->driver_configs[j]; j++) { + conf = dri2_add_config(disp, dri2_dpy->driver_configs[j], + id++, d.data->depth, surface_type); + if (conf == NULL) + continue; + _eglSetConfigKey(&conf->base, + EGL_NATIVE_VISUAL_ID, visuals[i].visual_id); + _eglSetConfigKey(&conf->base, + EGL_NATIVE_VISUAL_TYPE, visuals[i]._class); + } } xcb_depth_next(&d); @@ -738,6 +752,12 @@ dri2_create_screen(_EGLDisplay *disp) if (api_mask & (1 << __DRI_API_GLES2)) disp->ClientAPIsMask |= EGL_OPENGL_ES2_BIT; + if (dri2_dpy->dri2->base.version >= 2) { + disp->Extensions.KHR_surfaceless_gles1 = EGL_TRUE; + disp->Extensions.KHR_surfaceless_gles2 = EGL_TRUE; + disp->Extensions.KHR_surfaceless_opengl = EGL_TRUE; + } + return EGL_TRUE; cleanup_dri_screen: @@ -948,6 +968,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor) { struct dri2_egl_display *dri2_dpy; + int i; dri2_dpy = malloc(sizeof *dri2_dpy); if (!dri2_dpy) @@ -970,10 +991,17 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp, if (!dri2_create_screen(disp)) goto cleanup_driver; + for (i = 0; dri2_dpy->driver_configs[i]; i++) + dri2_add_config(disp, dri2_dpy->driver_configs[i], i + 1, 0, 0); + disp->Extensions.KHR_image_base = EGL_TRUE; disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE; disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE; + /* we're supporting EGL 1.4 */ + *major = 1; + *minor = 4; + return EGL_TRUE; cleanup_driver: @@ -1041,6 +1069,7 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_context *dri2_ctx_shared = dri2_egl_context(share_list); struct dri2_egl_config *dri2_config = dri2_egl_config(conf); + const __DRIconfig *dri_config; int api; dri2_ctx = malloc(sizeof *dri2_ctx); @@ -1074,11 +1103,16 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf, return NULL; } + if (conf != NULL) + dri_config = dri2_config->dri_config; + else + dri_config = NULL; + if (dri2_dpy->dri2->base.version >= 2) { dri2_ctx->dri_context = dri2_dpy->dri2->createNewContextForAPI(dri2_dpy->dri_screen, api, - dri2_config->dri_config, + dri_config, dri2_ctx_shared ? dri2_ctx_shared->dri_context : NULL, dri2_ctx); diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 09271140b13..4dc8707cfbc 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -379,7 +379,11 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, _EGLContext *context; EGLContext ret; - _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv); + if (config) + _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT, drv); + else + drv = _eglCheckDisplay(disp, __FUNCTION__); + if (!share && share_list != EGL_NO_CONTEXT) RETURN_EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT); diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c index a9af3200976..ea8e47d02bb 100644 --- a/src/egl/main/eglconfig.c +++ b/src/egl/main/eglconfig.c @@ -314,8 +314,10 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching) EGL_VG_ALPHA_FORMAT_PRE_BIT | EGL_MULTISAMPLE_RESOLVE_BOX_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; +#ifdef EGL_MESA_screen_surface if (conf->Display->Extensions.MESA_screen_surface) mask |= EGL_SCREEN_BIT_MESA; +#endif break; case EGL_RENDERABLE_TYPE: case EGL_CONFORMANT: diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index d5a1e79a994..9fc529613e5 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -83,7 +83,7 @@ _eglParseContextAttribList(_EGLContext *ctx, const EGLint *attrib_list) } } - if (err == EGL_SUCCESS) { + if (err == EGL_SUCCESS && ctx->Config) { EGLint renderable_type, api_bit; renderable_type = GET_CONFIG_ATTRIB(ctx->Config, EGL_RENDERABLE_TYPE); @@ -220,45 +220,49 @@ _eglBindContextToSurfaces(_EGLContext *newCtx, * surface (oldDraw), the old bindings are broken first and the new one is * created. */ - oldCtx = newDraw->CurrentContext; - if (newCtx != oldCtx) { - if (oldCtx) { - assert(oldCtx->DrawSurface == newDraw); - oldCtx->DrawSurface = NULL; + if (newDraw) { + oldCtx = newDraw->CurrentContext; + if (newCtx != oldCtx) { + if (oldCtx) { + assert(oldCtx->DrawSurface == newDraw); + oldCtx->DrawSurface = NULL; + } + + newDraw->CurrentContext = newCtx; } + } - if (newCtx) { - _EGLSurface *oldDraw = newCtx->DrawSurface; - if (oldDraw) - oldDraw->CurrentContext = NULL; - - newCtx->DrawSurface = newDraw; - *draw = oldDraw; - } + if (newCtx) { + _EGLSurface *oldDraw = newCtx->DrawSurface; + if (oldDraw) + oldDraw->CurrentContext = NULL; - newDraw->CurrentContext = newCtx; + newCtx->DrawSurface = newDraw; + *draw = oldDraw; } /* likewise */ - if (newRead != newDraw) + if (newRead && newRead != newDraw) { oldCtx = newRead->CurrentContext; - if (newCtx != oldCtx) { - if (oldCtx) { - assert(oldCtx->ReadSurface == newRead); - oldCtx->ReadSurface = NULL; - } + if (newCtx != oldCtx) { + if (oldCtx) { + assert(oldCtx->ReadSurface == newRead); + oldCtx->ReadSurface = NULL; + } - if (newCtx) { - _EGLSurface *oldRead = newCtx->ReadSurface; - if (oldRead) - oldRead->CurrentContext = NULL; - - newCtx->ReadSurface = newRead; - *read = oldRead; + newRead->CurrentContext = newCtx; } + } - newRead->CurrentContext = newCtx; + if (newCtx) { + _EGLSurface *oldRead = newCtx->ReadSurface; + if (oldRead) + oldRead->CurrentContext = NULL; + + newCtx->ReadSurface = newRead; + *read = oldRead; } + } @@ -297,7 +301,9 @@ static EGLBoolean _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) { _EGLThreadInfo *t = _eglGetCurrentThread(); + _EGLDisplay *dpy; EGLint conflict_api; + EGLBoolean surfaceless; if (_eglIsCurrentThreadDummy()) return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); @@ -309,8 +315,23 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) return EGL_TRUE; } - /* ctx/draw/read must be all given */ - if (draw == NULL || read == NULL) + dpy = ctx->Resource.Display; + switch (_eglGetContextAPIBit(ctx)) { + case EGL_OPENGL_ES_BIT: + surfaceless = dpy->Extensions.KHR_surfaceless_gles1; + break; + case EGL_OPENGL_ES2_BIT: + surfaceless = dpy->Extensions.KHR_surfaceless_gles2; + break; + case EGL_OPENGL_BIT: + surfaceless = dpy->Extensions.KHR_surfaceless_opengl; + break; + default: + surfaceless = EGL_FALSE; + break; + } + + if (!surfaceless && (draw == NULL || read == NULL)) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); /* context stealing from another thread is not allowed */ @@ -331,12 +352,13 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) * * The latter is more restrictive so we can check only the latter case. */ - if ((draw->CurrentContext && draw->CurrentContext != ctx) || - (read->CurrentContext && read->CurrentContext != ctx)) + if ((draw && draw->CurrentContext && draw->CurrentContext != ctx) || + (read && read->CurrentContext && read->CurrentContext != ctx)) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); /* simply require the configs to be equal */ - if (draw->Config != ctx->Config || read->Config != ctx->Config) + if ((draw && draw->Config != ctx->Config) || + (read && read->Config != ctx->Config)) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); switch (ctx->ClientAPI) { @@ -387,7 +409,6 @@ _eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read) *draw = oldCtx->DrawSurface; *read = oldCtx->ReadSurface; - assert(*draw && *read); _eglBindContextToSurfaces(NULL, draw, read); } diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c index c697bf796dc..c0e8c119a94 100644 --- a/src/egl/main/eglcurrent.c +++ b/src/egl/main/eglcurrent.c @@ -1,9 +1,9 @@ #include <stdlib.h> #include <string.h> -#include "eglglobals.h" #include "egllog.h" #include "eglmutex.h" #include "eglcurrent.h" +#include "eglglobals.h" /* This should be kept in sync with _eglInitThreadInfo() */ @@ -300,12 +300,14 @@ _eglError(EGLint errCode, const char *msg) case EGL_BAD_SURFACE: s = "EGL_BAD_SURFACE"; break; +#ifdef EGL_MESA_screen_surface case EGL_BAD_SCREEN_MESA: s = "EGL_BAD_SCREEN_MESA"; break; case EGL_BAD_MODE_MESA: s = "EGL_BAD_MODE_MESA"; break; +#endif default: s = "other"; } diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 0b2f26a4c07..a2cee08bf6f 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -60,6 +60,9 @@ struct _egl_extensions EGLBoolean KHR_gl_texture_cubemap_image; EGLBoolean KHR_gl_texture_3D_image; EGLBoolean KHR_gl_renderbuffer_image; + EGLBoolean KHR_surfaceless_gles1; + EGLBoolean KHR_surfaceless_gles2; + EGLBoolean KHR_surfaceless_opengl; EGLBoolean NOK_swap_region; EGLBoolean NOK_texture_from_pixmap; diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index 1e3d7d24aa7..8fc9e792b06 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -14,7 +14,6 @@ #include "egldefines.h" #include "egldisplay.h" #include "egldriver.h" -#include "eglglobals.h" #include "egllog.h" #include "eglmisc.h" #include "eglmode.h" diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index 725a25eca63..52eebb07f6c 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -11,7 +11,6 @@ struct _egl_global _eglGlobal = { &_eglGlobalMutex, /* Mutex */ NULL, /* DisplayList */ - 1, /* FreeScreenHandle */ 2, /* NumAtExitCalls */ { /* default AtExitCalls, called in reverse order */ diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h index e8bf5416e2a..c3771a8ef10 100644 --- a/src/egl/main/eglglobals.h +++ b/src/egl/main/eglglobals.h @@ -16,8 +16,6 @@ struct _egl_global /* the list of all displays */ _EGLDisplay *DisplayList; - EGLScreenMESA FreeScreenHandle; - EGLint NumAtExitCalls; void (*AtExitCalls[10])(void); }; diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c index 281138c7523..985d1e0069d 100644 --- a/src/egl/main/eglmisc.c +++ b/src/egl/main/eglmisc.c @@ -97,6 +97,10 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy) _EGL_CHECK_EXTENSION(KHR_gl_texture_3D_image); _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image); + _EGL_CHECK_EXTENSION(KHR_surfaceless_gles1); + _EGL_CHECK_EXTENSION(KHR_surfaceless_gles2); + _EGL_CHECK_EXTENSION(KHR_surfaceless_opengl); + _EGL_CHECK_EXTENSION(NOK_swap_region); _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap); #undef _EGL_CHECK_EXTENSION diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c index 859e9318b4a..37594cdb42d 100644 --- a/src/egl/main/eglmode.c +++ b/src/egl/main/eglmode.c @@ -10,6 +10,9 @@ #include "eglstring.h" +#ifdef EGL_MESA_screen_surface + + #define MIN2(A, B) (((A) < (B)) ? (A) : (B)) @@ -353,3 +356,6 @@ _eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m) { return m->Name; } + + +#endif /* EGL_MESA_screen_surface */ diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h index a089a5e1943..9167cbc4b9b 100644 --- a/src/egl/main/eglmode.h +++ b/src/egl/main/eglmode.h @@ -4,6 +4,9 @@ #include "egltypedefs.h" +#ifdef EGL_MESA_screen_surface + + #define EGL_NO_MODE_MESA 0 @@ -54,4 +57,7 @@ extern const char * _eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m); +#endif /* EGL_MESA_screen_surface */ + + #endif /* EGLMODE_INCLUDED */ diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c index 8f96fd935c7..8b8966f3ffd 100644 --- a/src/egl/main/eglscreen.c +++ b/src/egl/main/eglscreen.c @@ -16,7 +16,6 @@ #include <string.h> #include "egldisplay.h" -#include "eglglobals.h" #include "eglcurrent.h" #include "eglmode.h" #include "eglconfig.h" @@ -25,6 +24,14 @@ #include "eglmutex.h" +#ifdef EGL_MESA_screen_surface + + +/* ugh, no atomic op? */ +static _EGL_DECLARE_MUTEX(_eglNextScreenHandleMutex); +static EGLScreenMESA _eglNextScreenHandle = 1; + + /** * Return a new screen handle/ID. * NOTE: we never reuse these! @@ -33,10 +40,10 @@ static EGLScreenMESA _eglAllocScreenHandle(void) { EGLScreenMESA s; - - _eglLockMutex(_eglGlobal.Mutex); - s = _eglGlobal.FreeScreenHandle++; - _eglUnlockMutex(_eglGlobal.Mutex); + + _eglLockMutex(&_eglNextScreenHandleMutex); + s = _eglNextScreenHandle++; + _eglUnlockMutex(&_eglNextScreenHandleMutex); return s; } @@ -263,3 +270,5 @@ _eglDestroyScreen(_EGLScreen *scrn) free(scrn); } + +#endif /* EGL_MESA_screen_surface */ diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h index 0fd71f71fc8..3db20478ad6 100644 --- a/src/egl/main/eglscreen.h +++ b/src/egl/main/eglscreen.h @@ -5,6 +5,9 @@ #include "egltypedefs.h" +#ifdef EGL_MESA_screen_surface + + /** * Per-screen information. * Note that an EGL screen doesn't have a size. A screen may be set to @@ -86,4 +89,7 @@ PUBLIC void _eglDestroyScreen(_EGLScreen *scrn); +#endif /* EGL_MESA_screen_surface */ + + #endif /* EGLSCREEN_INCLUDED */ diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c index d46bdb0672e..52f5c240c65 100644 --- a/src/egl/main/eglsurface.c +++ b/src/egl/main/eglsurface.c @@ -30,6 +30,50 @@ _eglClampSwapInterval(_EGLSurface *surf, EGLint interval) } +#ifdef EGL_MESA_screen_surface +static EGLint +_eglParseScreenSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) +{ + EGLint i, err = EGL_SUCCESS; + + if (!attrib_list) + return EGL_SUCCESS; + + for (i = 0; attrib_list[i] != EGL_NONE; i++) { + EGLint attr = attrib_list[i++]; + EGLint val = attrib_list[i]; + + switch (attr) { + case EGL_WIDTH: + if (val < 0) { + err = EGL_BAD_PARAMETER; + break; + } + surf->Width = val; + break; + case EGL_HEIGHT: + if (val < 0) { + err = EGL_BAD_PARAMETER; + break; + } + surf->Height = val; + break; + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (err != EGL_SUCCESS) { + _eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr); + break; + } + } + + return err; +} +#endif /* EGL_MESA_screen_surface */ + + /** * Parse the list of surface attributes and return the proper error code. */ @@ -44,6 +88,11 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) if (!attrib_list) return EGL_SUCCESS; +#ifdef EGL_MESA_screen_surface + if (type == EGL_SCREEN_BIT_MESA) + return _eglParseScreenSurfaceAttribList(surf, attrib_list); +#endif + if (dpy->Extensions.NOK_texture_from_pixmap) texture_type |= EGL_PIXMAP_BIT; @@ -52,12 +101,8 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) EGLint val = attrib_list[i]; switch (attr) { - /* common (except for screen surfaces) attributes */ + /* common attributes */ case EGL_VG_COLORSPACE: - if (type == EGL_SCREEN_BIT_MESA) { - err = EGL_BAD_ATTRIBUTE; - break; - } switch (val) { case EGL_VG_COLORSPACE_sRGB: case EGL_VG_COLORSPACE_LINEAR: @@ -71,10 +116,6 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) surf->VGColorspace = val; break; case EGL_VG_ALPHA_FORMAT: - if (type == EGL_SCREEN_BIT_MESA) { - err = EGL_BAD_ATTRIBUTE; - break; - } switch (val) { case EGL_VG_ALPHA_FORMAT_NONPRE: case EGL_VG_ALPHA_FORMAT_PRE: @@ -101,7 +142,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) break; /* pbuffer surface attributes */ case EGL_WIDTH: - if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) { + if (type != EGL_PBUFFER_BIT) { err = EGL_BAD_ATTRIBUTE; break; } @@ -112,7 +153,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) surf->Width = val; break; case EGL_HEIGHT: - if (type != EGL_PBUFFER_BIT && type != EGL_SCREEN_BIT_MESA) { + if (type != EGL_PBUFFER_BIT) { err = EGL_BAD_ATTRIBUTE; break; } @@ -129,6 +170,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list) } surf->LargestPbuffer = !!val; break; + /* for eglBindTexImage */ case EGL_TEXTURE_FORMAT: if (!(type & texture_type)) { err = EGL_BAD_ATTRIBUTE; @@ -210,10 +252,12 @@ _eglInitSurface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, case EGL_PBUFFER_BIT: func = "eglCreatePBufferSurface"; break; +#ifdef EGL_MESA_screen_surface case EGL_SCREEN_BIT_MESA: func = "eglCreateScreenSurface"; renderBuffer = EGL_SINGLE_BUFFER; /* XXX correct? */ break; +#endif default: _eglLog(_EGL_WARNING, "Bad type in _eglInitSurface"); return EGL_FALSE; diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template index 43203b1756e..bff399ec64f 100644 --- a/src/gallium/Makefile.template +++ b/src/gallium/Makefile.template @@ -23,6 +23,10 @@ INCLUDES = \ -I$(TOP)/src/gallium/drivers \ $(LIBRARY_INCLUDES) +ifeq ($(MESA_LLVM),1) +LIBRARY_DEFINES += $(LLVM_CFLAGS) +endif + ##### TARGETS ##### diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index dcebab7c0f2..9544e90a965 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -131,6 +131,7 @@ C_SOURCES = \ util/u_sampler.c \ util/u_simple_shaders.c \ util/u_snprintf.c \ + util/u_staging.c \ util/u_surface.c \ util/u_surfaces.c \ util/u_texture.c \ @@ -149,6 +150,7 @@ C_SOURCES = \ GALLIVM_SOURCES = \ gallivm/lp_bld_arit.c \ + gallivm/lp_bld_assert.c \ gallivm/lp_bld_const.c \ gallivm/lp_bld_conv.c \ gallivm/lp_bld_debug.c \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index 72a16617db8..3124e20ce84 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -34,14 +34,14 @@ env.CodeGenerate( target = 'util/u_format_table.c', script = '#src/gallium/auxiliary/util/u_format_table.py', source = ['#src/gallium/auxiliary/util/u_format.csv'], - command = 'python $SCRIPT $SOURCE > $TARGET' + command = python_cmd + ' $SCRIPT $SOURCE > $TARGET' ) env.CodeGenerate( target = 'util/u_half.c', script = 'util/u_half.py', source = [], - command = 'python $SCRIPT > $TARGET' + command = python_cmd + ' $SCRIPT > $TARGET' ) env.Depends('util/u_format_table.c', [ @@ -180,6 +180,7 @@ source = [ 'util/u_sampler.c', 'util/u_simple_shaders.c', 'util/u_snprintf.c', + 'util/u_staging.c', 'util/u_surface.c', 'util/u_surfaces.c', 'util/u_texture.c', @@ -198,6 +199,7 @@ source = [ if env['llvm']: source += [ 'gallivm/lp_bld_arit.c', + 'gallivm/lp_bld_assert.c', 'gallivm/lp_bld_const.c', 'gallivm/lp_bld_conv.c', 'gallivm/lp_bld_debug.c', diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index c127f741881..995b675b9a1 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -288,12 +288,19 @@ draw_set_mapped_constant_buffer(struct draw_context *draw, shader_type == PIPE_SHADER_GEOMETRY); debug_assert(slot < PIPE_MAX_CONSTANT_BUFFERS); - if (shader_type == PIPE_SHADER_VERTEX) { + switch (shader_type) { + case PIPE_SHADER_VERTEX: draw->pt.user.vs_constants[slot] = buffer; + draw->pt.user.vs_constants_size[slot] = size; draw_vs_set_constants(draw, slot, buffer, size); - } else if (shader_type == PIPE_SHADER_GEOMETRY) { + break; + case PIPE_SHADER_GEOMETRY: draw->pt.user.gs_constants[slot] = buffer; + draw->pt.user.gs_constants_size[slot] = size; draw_gs_set_constants(draw, slot, buffer, size); + break; + default: + assert(0 && "invalid shader type in draw_set_mapped_constant_buffer"); } } diff --git a/src/gallium/auxiliary/draw/draw_decompose_tmp.h b/src/gallium/auxiliary/draw/draw_decompose_tmp.h new file mode 100644 index 00000000000..a52d2b50588 --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_decompose_tmp.h @@ -0,0 +1,425 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Keith Whitwell <[email protected]> + * Chia-I Wu <[email protected]> + */ + +/* these macros are optional */ +#ifndef LOCAL_VARS +#define LOCAL_VARS +#endif +#ifndef FUNC_ENTER +#define FUNC_ENTER do {} while (0) +#endif +#ifndef FUNC_EXIT +#define FUNC_EXIT do {} while (0) +#endif +#ifndef LINE_ADJ +#define LINE_ADJ(flags, a0, i0, i1, a1) LINE(flags, i0, i1) +#endif +#ifndef TRIANGLE_ADJ +#define TRIANGLE_ADJ(flags, i0, a0, i1, a1, i2, a2) TRIANGLE(flags, i0, i1, i2) +#endif + +static void +FUNC(FUNC_VARS) +{ + unsigned idx[6], i; + ushort flags; + LOCAL_VARS + + FUNC_ENTER; + + /* prim, count, and last_vertex_last should have been defined */ + if (0) { + debug_printf("%s: prim 0x%x, count %d, last_vertex_last %d\n", + __FUNCTION__, prim, count, last_vertex_last); + } + + switch (prim) { + case PIPE_PRIM_POINTS: + for (i = 0; i < count; i++) { + idx[0] = GET_ELT(i); + POINT(idx[0]); + } + break; + + case PIPE_PRIM_LINES: + flags = DRAW_PIPE_RESET_STIPPLE; + for (i = 0; i + 1 < count; i += 2) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + LINE(flags, idx[0], idx[1]); + } + break; + + case PIPE_PRIM_LINE_LOOP: + case PIPE_PRIM_LINE_STRIP: + if (count >= 2) { + flags = DRAW_PIPE_RESET_STIPPLE; + idx[1] = GET_ELT(0); + idx[2] = idx[1]; + + for (i = 1; i < count; i++, flags = 0) { + idx[0] = idx[1]; + idx[1] = GET_ELT(i); + LINE(flags, idx[0], idx[1]); + } + /* close the loop */ + if (prim == PIPE_PRIM_LINE_LOOP) + LINE(flags, idx[1], idx[2]); + } + break; + + case PIPE_PRIM_TRIANGLES: + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + for (i = 0; i + 2 < count; i += 3) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + idx[2] = GET_ELT(i + 2); + TRIANGLE(flags, idx[0], idx[1], idx[2]); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP: + if (count >= 3) { + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + idx[1] = GET_ELT(0); + idx[2] = GET_ELT(1); + + if (last_vertex_last) { + for (i = 0; i + 2 < count; i++) { + idx[0] = idx[1]; + idx[1] = idx[2]; + idx[2] = GET_ELT(i + 2); + /* always emit idx[2] last */ + if (i & 1) + TRIANGLE(flags, idx[1], idx[0], idx[2]); + else + TRIANGLE(flags, idx[0], idx[1], idx[2]); + } + } + else { + for (i = 0; i + 2 < count; i++) { + idx[0] = idx[1]; + idx[1] = idx[2]; + idx[2] = GET_ELT(i + 2); + /* always emit idx[0] first */ + if (i & 1) + TRIANGLE(flags, idx[0], idx[2], idx[1]); + else + TRIANGLE(flags, idx[0], idx[1], idx[2]); + } + } + } + break; + + case PIPE_PRIM_TRIANGLE_FAN: + if (count >= 3) { + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + idx[0] = GET_ELT(0); + idx[2] = GET_ELT(1); + + /* idx[0] is neither the first nor the last vertex */ + if (last_vertex_last) { + for (i = 0; i + 2 < count; i++) { + idx[1] = idx[2]; + idx[2] = GET_ELT(i + 2); + /* always emit idx[2] last */ + TRIANGLE(flags, idx[0], idx[1], idx[2]); + } + } + else { + for (i = 0; i + 2 < count; i++) { + idx[1] = idx[2]; + idx[2] = GET_ELT(i + 2); + /* always emit idx[1] first */ + TRIANGLE(flags, idx[1], idx[2], idx[0]); + } + } + } + break; + + case PIPE_PRIM_QUADS: + if (last_vertex_last) { + for (i = 0; i + 3 < count; i += 4) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + + flags = DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_2; + /* always emit idx[3] last */ + TRIANGLE(flags, idx[0], idx[1], idx[3]); + + flags = DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1; + TRIANGLE(flags, idx[1], idx[2], idx[3]); + } + } + else { + for (i = 0; i + 3 < count; i += 4) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + + flags = DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1; + /* XXX should always emit idx[0] first */ + /* always emit idx[3] first */ + TRIANGLE(flags, idx[3], idx[0], idx[1]); + + flags = DRAW_PIPE_EDGE_FLAG_1 | + DRAW_PIPE_EDGE_FLAG_2; + TRIANGLE(flags, idx[3], idx[1], idx[2]); + } + } + break; + + case PIPE_PRIM_QUAD_STRIP: + if (count >= 4) { + idx[2] = GET_ELT(0); + idx[3] = GET_ELT(1); + + if (last_vertex_last) { + for (i = 0; i + 3 < count; i += 2) { + idx[0] = idx[2]; + idx[1] = idx[3]; + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + + /* always emit idx[3] last */ + flags = DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_2; + TRIANGLE(flags, idx[2], idx[0], idx[3]); + + flags = DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1; + TRIANGLE(flags, idx[0], idx[1], idx[3]); + } + } + else { + for (i = 0; i + 3 < count; i += 2) { + idx[0] = idx[2]; + idx[1] = idx[3]; + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + + flags = DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1; + /* XXX should always emit idx[0] first */ + /* always emit idx[3] first */ + TRIANGLE(flags, idx[3], idx[2], idx[0]); + + flags = DRAW_PIPE_EDGE_FLAG_1 | + DRAW_PIPE_EDGE_FLAG_2; + TRIANGLE(flags, idx[3], idx[0], idx[1]); + } + } + } + break; + + case PIPE_PRIM_POLYGON: + if (count >= 3) { + ushort edge_next, edge_finish; + + if (last_vertex_last) { + flags = (DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_2 | + DRAW_PIPE_EDGE_FLAG_0); + edge_next = DRAW_PIPE_EDGE_FLAG_0; + edge_finish = DRAW_PIPE_EDGE_FLAG_1; + } + else { + flags = (DRAW_PIPE_RESET_STIPPLE | + DRAW_PIPE_EDGE_FLAG_0 | + DRAW_PIPE_EDGE_FLAG_1); + edge_next = DRAW_PIPE_EDGE_FLAG_1; + edge_finish = DRAW_PIPE_EDGE_FLAG_2; + } + + idx[0] = GET_ELT(0); + idx[2] = GET_ELT(1); + + for (i = 0; i + 2 < count; i++, flags = edge_next) { + idx[1] = idx[2]; + idx[2] = GET_ELT(i + 2); + + if (i + 3 == count) + flags |= edge_finish; + + /* idx[0] is both the first and the last vertex */ + if (last_vertex_last) + TRIANGLE(flags, idx[1], idx[2], idx[0]); + else + TRIANGLE(flags, idx[0], idx[1], idx[2]); + } + } + break; + + case PIPE_PRIM_LINES_ADJACENCY: + flags = DRAW_PIPE_RESET_STIPPLE; + for (i = 0; i + 3 < count; i += 4) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]); + } + break; + + case PIPE_PRIM_LINE_STRIP_ADJACENCY: + if (count >= 4) { + flags = DRAW_PIPE_RESET_STIPPLE; + idx[1] = GET_ELT(0); + idx[2] = GET_ELT(1); + idx[3] = GET_ELT(2); + + for (i = 1; i + 2 < count; i++, flags = 0) { + idx[0] = idx[1]; + idx[1] = idx[2]; + idx[2] = idx[3]; + idx[3] = GET_ELT(i + 2); + LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]); + } + } + break; + + case PIPE_PRIM_TRIANGLES_ADJACENCY: + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + for (i = 0; i + 5 < count; i += 6) { + idx[0] = GET_ELT(i); + idx[1] = GET_ELT(i + 1); + idx[2] = GET_ELT(i + 2); + idx[3] = GET_ELT(i + 3); + idx[4] = GET_ELT(i + 4); + idx[5] = GET_ELT(i + 5); + TRIANGLE_ADJ(flags, idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]); + } + break; + + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: + if (count >= 6) { + flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL; + idx[0] = GET_ELT(1); + idx[2] = GET_ELT(0); + idx[4] = GET_ELT(2); + idx[3] = GET_ELT(4); + + /* + * The vertices of the i-th triangle are stored in + * idx[0,2,4] = { 2*i, 2*i+2, 2*i+4 }; + * + * The adjacent vertices are stored in + * idx[1,3,5] = { 2*i-2, 2*i+6, 2*i+3 }. + * + * However, there are two exceptions: + * + * For the first triangle, idx[1] = 1; + * For the last triangle, idx[3] = 2*i+5. + */ + if (last_vertex_last) { + for (i = 0; i + 5 < count; i += 2) { + idx[1] = idx[0]; + + idx[0] = idx[2]; + idx[2] = idx[4]; + idx[4] = idx[3]; + + idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5)); + idx[5] = GET_ELT(i + 3); + + /* + * alternate the first two vertices (idx[0] and idx[2]) and the + * corresponding adjacent vertices (idx[3] and idx[5]) to have + * the correct orientation + */ + if (i & 2) { + TRIANGLE_ADJ(flags, + idx[2], idx[1], idx[0], idx[5], idx[4], idx[3]); + } + else { + TRIANGLE_ADJ(flags, + idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]); + } + } + } + else { + for (i = 0; i + 5 < count; i += 2) { + idx[1] = idx[0]; + + idx[0] = idx[2]; + idx[2] = idx[4]; + idx[4] = idx[3]; + + idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5)); + idx[5] = GET_ELT(i + 3); + + /* + * alternate the last two vertices (idx[2] and idx[4]) and the + * corresponding adjacent vertices (idx[1] and idx[5]) to have + * the correct orientation + */ + if (i & 2) { + TRIANGLE_ADJ(flags, + idx[0], idx[5], idx[4], idx[3], idx[2], idx[1]); + } + else { + TRIANGLE_ADJ(flags, + idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]); + } + } + } + } + break; + + default: + assert(0); + break; + } + + FUNC_EXIT; +} + +#undef LOCAL_VARS +#undef FUNC_ENTER +#undef FUNC_EXIT +#undef LINE_ADJ +#undef TRIANGLE_ADJ + +#undef FUNC +#undef FUNC_VARS +#undef GET_ELT +#undef POINT +#undef LINE +#undef TRIANGLE diff --git a/src/gallium/auxiliary/draw/draw_gs.c b/src/gallium/auxiliary/draw/draw_gs.c index 79a57a67f3e..4a1013e79a5 100644 --- a/src/gallium/auxiliary/draw/draw_gs.c +++ b/src/gallium/auxiliary/draw/draw_gs.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2009 VMWare Inc. + * Copyright 2009 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -75,7 +75,10 @@ draw_gs_set_constants(struct draw_context *draw, const void *constants, unsigned size) { - /* noop */ + /* noop. added here for symmetry with the VS + * code and in case we'll ever want to allign + * the constants, e.g. when we'll change to a + * different interpreter */ } @@ -370,32 +373,23 @@ static void gs_tri_adj(struct draw_geometry_shader *shader, gs_flush(shader, 1); } -#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,i0,i1,i2) -#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5) -#define LINE(gs,i0,i1) gs_line(gs,i0,i1) -#define LINE_ADJ(gs,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3) -#define POINT(gs,i0) gs_point(gs,i0) -#define FUNC gs_run -#define LOCAL_VARS +#define FUNC gs_run +#define GET_ELT(idx) (idx) #include "draw_gs_tmp.h" -#define TRIANGLE(gs,i0,i1,i2) gs_tri(gs,elts[i0],elts[i1],elts[i2]) -#define TRI_ADJ(gs,i0,i1,i2,i3,i4,i5) \ - gs_tri_adj(gs,elts[i0],elts[i1],elts[i2],elts[i3], \ - elts[i4],elts[i5]) -#define LINE(gs,i0,i1) gs_line(gs,elts[i0],elts[i1]) -#define LINE_ADJ(gs,i0,i1,i2,i3) gs_line_adj(gs,elts[i0], \ - elts[i1], \ - elts[i2],elts[i3]) -#define POINT(gs,i0) gs_point(gs,elts[i0]) -#define FUNC gs_run_elts -#define LOCAL_VARS \ - const ushort *elts = input_prims->elts; +#define FUNC gs_run_elts +#define LOCAL_VARS const ushort *elts = input_prims->elts; +#define GET_ELT(idx) (elts[idx] & ~DRAW_PIPE_FLAG_MASK) #include "draw_gs_tmp.h" + +/** + * Execute geometry shader using TGSI interpreter. + */ int draw_geometry_shader_run(struct draw_geometry_shader *shader, const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS], const struct draw_vertex_info *input_verts, const struct draw_prim_info *input_prim, struct draw_vertex_info *output_verts, @@ -405,7 +399,6 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, unsigned input_stride = input_verts->vertex_size; unsigned vertex_size = input_verts->vertex_size; struct tgsi_exec_machine *machine = shader->machine; - unsigned int i; unsigned num_input_verts = input_prim->linear ? input_verts->count : input_prim->count; @@ -447,9 +440,8 @@ int draw_geometry_shader_run(struct draw_geometry_shader *shader, } shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned)); - for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { - machine->Consts[i] = constants[i]; - } + tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, + constants, constants_size); if (input_prim->linear) gs_run(shader, input_prim, input_verts, diff --git a/src/gallium/auxiliary/draw/draw_gs.h b/src/gallium/auxiliary/draw/draw_gs.h index 2cb634818c2..67bc1aa73ff 100644 --- a/src/gallium/auxiliary/draw/draw_gs.h +++ b/src/gallium/auxiliary/draw/draw_gs.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2009 VMWare Inc. + * Copyright 2009 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -73,6 +73,7 @@ struct draw_geometry_shader { */ int draw_geometry_shader_run(struct draw_geometry_shader *shader, const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS], const struct draw_vertex_info *input_verts, const struct draw_prim_info *input_prim, struct draw_vertex_info *output_verts, diff --git a/src/gallium/auxiliary/draw/draw_gs_tmp.h b/src/gallium/auxiliary/draw/draw_gs_tmp.h index 7a8683cf7c2..4a17af0dea3 100644 --- a/src/gallium/auxiliary/draw/draw_gs_tmp.h +++ b/src/gallium/auxiliary/draw/draw_gs_tmp.h @@ -1,152 +1,34 @@ - -static void FUNC( struct draw_geometry_shader *shader, - const struct draw_prim_info *input_prims, - const struct draw_vertex_info *input_verts, - struct draw_prim_info *output_prims, - struct draw_vertex_info *output_verts) -{ - struct draw_context *draw = shader->draw; - - boolean flatfirst = (draw->rasterizer->flatshade && - draw->rasterizer->flatshade_first); - unsigned i, j; - unsigned count = input_prims->count; - LOCAL_VARS - - if (0) debug_printf("%s %d\n", __FUNCTION__, count); - - debug_assert(input_prims->primitive_count == 1); - - switch (input_prims->prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i++) { - POINT( shader, i + 0 ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - LINE( shader , i + 0 , i + 1 ); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - - for (i = 1; i < count; i++) { - LINE( shader, i - 1, i ); - } - - LINE( shader, i - 1, 0 ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - LINE( shader, i - 1, i ); - } - break; - - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - TRIANGLE( shader, i + 0, i + 1, i + 2 ); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( shader, - i + 0, - i + 1 + (i&1), - i + 2 - (i&1) ); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( shader, - i + 0 + (i&1), - i + 1 - (i&1), - i + 2 ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( shader, - i + 1, - i + 2, - 0 ); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( shader, - 0, - i + 1, - i + 2 ); - } - } - } - break; - - case PIPE_PRIM_POLYGON: - { - for (i = 0; i+2 < count; i++) { - - if (flatfirst) { - TRIANGLE( shader, 0, i + 1, i + 2 ); - } - else { - TRIANGLE( shader, i + 1, i + 2, 0 ); - } - } - } - break; - - case PIPE_PRIM_LINES_ADJACENCY: - for (i = 0; i+3 < count; i += 4) { - LINE_ADJ( shader , i + 0 , i + 1, i + 2, i + 3 ); - } - break; - case PIPE_PRIM_LINE_STRIP_ADJACENCY: - for (i = 1; i + 2 < count; i++) { - LINE_ADJ( shader, i - 1, i, i + 1, i + 2 ); - } - break; - - case PIPE_PRIM_TRIANGLES_ADJACENCY: - for (i = 0; i+5 < count; i += 5) { - TRI_ADJ( shader, i + 0, i + 1, i + 2, - i + 3, i + 4, i + 5); - } - break; - case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: - for (i = 0, j = 0; i+5 < count; i += 2, ++j) { - TRI_ADJ( shader, - i + 0, - i + 1 + 2*(j&1), - i + 2 + 2*(j&1), - i + 3 - 2*(j&1), - i + 4 - 2*(j&1), - i + 5); - } - break; - - default: - debug_assert(!"Unsupported primitive in geometry shader"); - break; - } -} - - -#undef TRIANGLE -#undef TRI_ADJ -#undef POINT -#undef LINE -#undef LINE_ADJ -#undef FUNC -#undef LOCAL_VARS +#define FUNC_VARS struct draw_geometry_shader *gs, \ + const struct draw_prim_info *input_prims, \ + const struct draw_vertex_info *input_verts, \ + struct draw_prim_info *output_prims, \ + struct draw_vertex_info *output_verts + +#define FUNC_ENTER \ + /* declare more local vars */ \ + struct draw_context *draw = gs->draw; \ + const unsigned prim = input_prims->prim; \ + const unsigned count = input_prims->count; \ + const boolean last_vertex_last = \ + !(draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); \ + do { \ + debug_assert(input_prims->primitive_count == 1); \ + switch (prim) { \ + case PIPE_PRIM_QUADS: \ + case PIPE_PRIM_QUAD_STRIP: \ + case PIPE_PRIM_POLYGON: \ + debug_assert(!"unexpected primitive type in GS"); \ + return; \ + default: \ + break; \ + } \ + } while (0) \ + +#define POINT(i0) gs_point(gs,i0) +#define LINE(flags,i0,i1) gs_line(gs,i0,i1) +#define TRIANGLE(flags,i0,i1,i2) gs_tri(gs,i0,i1,i2) +#define LINE_ADJ(flags,i0,i1,i2,i3) gs_line_adj(gs,i0,i1,i2,i3) +#define TRIANGLE_ADJ(flags,i0,i1,i2,i3,i4,i5) gs_tri_adj(gs,i0,i1,i2,i3,i4,i5) + +#include "draw_decompose_tmp.h" diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 19f96c37ab4..8d53601d195 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -37,6 +37,8 @@ #include "gallivm/lp_bld_debug.h" #include "gallivm/lp_bld_tgsi.h" #include "gallivm/lp_bld_printf.h" +#include "gallivm/lp_bld_intr.h" +#include "gallivm/lp_bld_init.h" #include "tgsi/tgsi_exec.h" #include "tgsi/tgsi_dump.h" @@ -681,7 +683,6 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) unsigned i, j; struct lp_build_context bld; struct lp_build_loop_state lp_loop; - struct lp_type vs_type = lp_type_float_vec(32); const int max_vertices = 4; LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS]; void *code; @@ -730,7 +731,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) builder = LLVMCreateBuilder(); LLVMPositionBuilderAtEnd(builder, block); - lp_build_context_init(&bld, builder, vs_type); + lp_build_context_init(&bld, builder, lp_type_int(32)); end = lp_build_add(&bld, start, count); @@ -793,6 +794,11 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) sampler->destroy(sampler); +#ifdef PIPE_ARCH_X86 + /* Avoid corrupting the FPU stack on 32bit OSes. */ + lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); +#endif + LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); @@ -820,6 +826,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) if (gallivm_debug & GALLIVM_DEBUG_ASM) { lp_disassemble(code); } + lp_func_delete_body(variant->function); } @@ -837,9 +844,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian struct draw_context *draw = llvm->draw; unsigned i, j; struct lp_build_context bld; - struct lp_build_context bld_int; struct lp_build_loop_state lp_loop; - struct lp_type vs_type = lp_type_float_vec(32); const int max_vertices = 4; LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS]; LLVMValueRef fetch_max; @@ -891,8 +896,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian builder = LLVMCreateBuilder(); LLVMPositionBuilderAtEnd(builder, block); - lp_build_context_init(&bld, builder, vs_type); - lp_build_context_init(&bld_int, builder, lp_type_int(32)); + lp_build_context_init(&bld, builder, lp_type_int(32)); step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0); @@ -927,7 +931,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian /* make sure we're not out of bounds which can happen * if fetch_count % 4 != 0, because on the last iteration * a few of the 4 vertex fetches will be out of bounds */ - true_index = lp_build_min(&bld_int, true_index, fetch_max); + true_index = lp_build_min(&bld, true_index, fetch_max); fetch_ptr = LLVMBuildGEP(builder, fetch_elts, &true_index, 1, ""); @@ -963,6 +967,11 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian sampler->destroy(sampler); +#ifdef PIPE_ARCH_X86 + /* Avoid corrupting the FPU stack on 32bit OSes. */ + lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); +#endif + LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); @@ -990,6 +999,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian if (gallivm_debug & GALLIVM_DEBUG_ASM) { lp_disassemble(code); } + lp_func_delete_body(variant->function_elts); } void diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c index 8cd75ecf9a3..58995e07248 100644 --- a/src/gallium/auxiliary/draw/draw_pipe.c +++ b/src/gallium/auxiliary/draw/draw_pipe.c @@ -169,77 +169,50 @@ static void do_triangle( struct draw_context *draw, /* * Set up macros for draw_pt_decompose.h template code. * This code uses vertex indexes / elements. + * + * Flags are needed by the stipple and unfilled stages. When the two stages + * are active, vcache_run_extras is called and the flags are stored in the + * higher bits of i0. Otherwise, flags do not matter. */ -/* emit first quad vertex as first vertex in triangles */ -#define QUAD_FIRST_PV(i0,i1,i2,i3) \ - do_triangle( draw, \ - ( DRAW_PIPE_RESET_STIPPLE | \ - DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_1 ), \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK)); \ - do_triangle( draw, \ - ( DRAW_PIPE_EDGE_FLAG_1 | \ - DRAW_PIPE_EDGE_FLAG_2 ), \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK)) - -/* emit last quad vertex as last vertex in triangles */ -#define QUAD_LAST_PV(i0,i1,i2,i3) \ - do_triangle( draw, \ - ( DRAW_PIPE_RESET_STIPPLE | \ - DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_2 ), \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK)); \ - do_triangle( draw, \ - ( DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_1 ), \ - verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK)) - -#define TRIANGLE(flags,i0,i1,i2) \ - do_triangle( draw, \ - elts[i0], /* flags */ \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK) ); - -#define LINE(flags,i0,i1) \ - do_line( draw, \ - elts[i0], \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK) ); +#define TRIANGLE(flags,i0,i1,i2) \ + do { \ + assert(!((i1) & DRAW_PIPE_FLAG_MASK)); \ + assert(!((i2) & DRAW_PIPE_FLAG_MASK)); \ + do_triangle( draw, \ + i0, /* flags */ \ + verts + stride * (i0 & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i1), \ + verts + stride * (i2) ); \ + } while (0) + +#define LINE(flags,i0,i1) \ + do { \ + assert(!((i1) & DRAW_PIPE_FLAG_MASK)); \ + do_line( draw, \ + i0, /* flags */ \ + verts + stride * (i0 & ~DRAW_PIPE_FLAG_MASK), \ + verts + stride * (i1) ); \ + } while (0) #define POINT(i0) \ - do_point( draw, \ - verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK) ) + do { \ + assert(!((i0) & DRAW_PIPE_FLAG_MASK)); \ + do_point( draw, verts + stride * (i0) ); \ + } while (0) + +#define GET_ELT(idx) (elts[idx]) -#define FUNC pipe_run -#define ARGS \ +#define FUNC pipe_run_elts +#define FUNC_VARS \ struct draw_context *draw, \ unsigned prim, \ struct vertex_header *vertices, \ unsigned stride, \ - const ushort *elts - -#define LOCAL_VARS \ - char *verts = (char *)vertices; \ - boolean flatfirst = (draw->rasterizer->flatshade && \ - draw->rasterizer->flatshade_first); \ - unsigned i; \ - ushort flags - -#define FLUSH + const ushort *elts, \ + unsigned count #include "draw_pt_decompose.h" -#undef ARGS -#undef LOCAL_VARS @@ -269,14 +242,29 @@ void draw_pipeline_run( struct draw_context *draw, i < prim_info->primitive_count; start += prim_info->primitive_lengths[i], i++) { - unsigned count = prim_info->primitive_lengths[i]; - - pipe_run(draw, - prim_info->prim, - vert_info->verts, - vert_info->stride, - prim_info->elts + start, - count); + const unsigned count = prim_info->primitive_lengths[i]; + +#if DEBUG + /* make sure none of the element indexes go outside the vertex buffer */ + { + unsigned max_index = 0x0, i; + /* find the largest element index */ + for (i = 0; i < count; i++) { + unsigned int index = (prim_info->elts[start + i] + & ~DRAW_PIPE_FLAG_MASK); + if (index > max_index) + max_index = index; + } + assert(max_index <= vert_info->count); + } +#endif + + pipe_run_elts(draw, + prim_info->prim, + vert_info->verts, + vert_info->stride, + prim_info->elts + start, + count); } draw->pipeline.verts = NULL; @@ -289,70 +277,30 @@ void draw_pipeline_run( struct draw_context *draw, * This code is for non-indexed (aka linear) rendering (no elts). */ -/* emit first quad vertex as first vertex in triangles */ -#define QUAD_FIRST_PV(i0,i1,i2,i3) \ - do_triangle( draw, \ - ( DRAW_PIPE_RESET_STIPPLE | \ - DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_1 ), \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK)); \ - do_triangle( draw, \ - ( DRAW_PIPE_EDGE_FLAG_1 | \ - DRAW_PIPE_EDGE_FLAG_2 ), \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK)) - -/* emit last quad vertex as last vertex in triangles */ -#define QUAD_LAST_PV(i0,i1,i2,i3) \ - do_triangle( draw, \ - ( DRAW_PIPE_RESET_STIPPLE | \ - DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_2 ), \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK)); \ - do_triangle( draw, \ - ( DRAW_PIPE_EDGE_FLAG_0 | \ - DRAW_PIPE_EDGE_FLAG_1 ), \ - verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK)) - -#define TRIANGLE(flags,i0,i1,i2) \ - do_triangle( draw, \ - flags, /* flags */ \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK)) - -#define LINE(flags,i0,i1) \ - do_line( draw, \ - flags, \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \ - verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK)) +#define TRIANGLE(flags,i0,i1,i2) \ + do_triangle( draw, flags, \ + verts + stride * (i0), \ + verts + stride * (i1), \ + verts + stride * (i2) ) -#define POINT(i0) \ - do_point( draw, \ - verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK) ) +#define LINE(flags,i0,i1) \ + do_line( draw, flags, \ + verts + stride * (i0), \ + verts + stride * (i1) ) -#define FUNC pipe_run_linear -#define ARGS \ - struct draw_context *draw, \ - unsigned prim, \ - struct vertex_header *vertices, \ - unsigned stride +#define POINT(i0) \ + do_point( draw, verts + stride * (i0) ) -#define LOCAL_VARS \ - char *verts = (char *)vertices; \ - boolean flatfirst = (draw->rasterizer->flatshade && \ - draw->rasterizer->flatshade_first); \ - unsigned i; \ - ushort flags -#define FLUSH +#define GET_ELT(idx) (idx) + +#define FUNC pipe_run_linear +#define FUNC_VARS \ + struct draw_context *draw, \ + unsigned prim, \ + struct vertex_header *vertices, \ + unsigned stride, \ + unsigned count #include "draw_pt_decompose.h" @@ -378,6 +326,8 @@ void draw_pipeline_run_linear( struct draw_context *draw, draw->pipeline.vertex_stride = vert_info->stride; draw->pipeline.vertex_count = count; + assert(count <= vert_info->count); + pipe_run_linear(draw, prim_info->prim, (struct vertex_header*)verts, diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c index 1cf6ee7a7f9..8a3d499febb 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_clip.c +++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c @@ -68,8 +68,7 @@ struct clip_stage { }; -/* This is a bit confusing: - */ +/** Cast wrapper */ static INLINE struct clip_stage *clip_stage( struct draw_stage *stage ) { return (struct clip_stage *)stage; @@ -81,18 +80,22 @@ static INLINE struct clip_stage *clip_stage( struct draw_stage *stage ) /* All attributes are float[4], so this is easy: */ -static void interp_attr( float *fdst, +static void interp_attr( float dst[4], float t, - const float *fin, - const float *fout ) + const float in[4], + const float out[4] ) { - fdst[0] = LINTERP( t, fout[0], fin[0] ); - fdst[1] = LINTERP( t, fout[1], fin[1] ); - fdst[2] = LINTERP( t, fout[2], fin[2] ); - fdst[3] = LINTERP( t, fout[3], fin[3] ); + dst[0] = LINTERP( t, out[0], in[0] ); + dst[1] = LINTERP( t, out[1], in[1] ); + dst[2] = LINTERP( t, out[2], in[2] ); + dst[3] = LINTERP( t, out[3], in[3] ); } +/** + * Copy front/back, primary/secondary colors from src vertex to dst vertex. + * Used when flat shading. + */ static void copy_colors( struct draw_stage *stage, struct vertex_header *dst, const struct vertex_header *src ) @@ -121,20 +124,17 @@ static void interp( const struct clip_stage *clip, /* Vertex header. */ - { - dst->clipmask = 0; - dst->edgeflag = 0; /* will get overwritten later */ - dst->pad = 0; - dst->vertex_id = UNDEFINED_VERTEX_ID; - } + dst->clipmask = 0; + dst->edgeflag = 0; /* will get overwritten later */ + dst->pad = 0; + dst->vertex_id = UNDEFINED_VERTEX_ID; - /* Clip coordinates: interpolate normally + /* Interpolate the clip-space coords. */ - { - interp_attr(dst->clip, t, in->clip, out->clip); - } + interp_attr(dst->clip, t, in->clip, out->clip); - /* Do the projective divide and insert window coordinates: + /* Do the projective divide and viewport transformation to get + * new window coordinates: */ { const float *pos = dst->clip; diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index 058aeedc17a..397d4bf653c 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -163,9 +163,11 @@ struct draw_context /** vertex arrays */ const void *vbuffer[PIPE_MAX_ATTRIBS]; - /** constant buffer (for vertex/geometry shader) */ + /** constant buffers (for vertex/geometry shader) */ const void *vs_constants[PIPE_MAX_CONSTANT_BUFFERS]; + unsigned vs_constants_size[PIPE_MAX_CONSTANT_BUFFERS]; const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS]; + unsigned gs_constants_size[PIPE_MAX_CONSTANT_BUFFERS]; } user; boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */ @@ -198,6 +200,7 @@ struct draw_context struct pipe_viewport_state viewport; boolean identity_viewport; + /** Vertex shader state */ struct { struct draw_vertex_shader *vertex_shader; uint num_vs_outputs; /**< convenience, from vertex_shader */ @@ -227,6 +230,7 @@ struct draw_context struct translate_cache *emit_cache; } vs; + /** Geometry shader state */ struct { struct draw_geometry_shader *geometry_shader; uint num_gs_outputs; /**< convenience, from geometry_shader */ @@ -239,6 +243,7 @@ struct draw_context struct tgsi_sampler **samplers; } gs; + /** Stream output (vertex feedback) state */ struct { struct pipe_stream_output_state state; void *buffers[PIPE_MAX_SO_BUFFERS]; diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 92d4113b4c6..248927505da 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -259,6 +259,12 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count) for (j = 0; j < draw->pt.nr_vertex_elements; j++) { uint buf = draw->pt.vertex_element[j].vertex_buffer_index; ubyte *ptr = (ubyte *) draw->pt.user.vbuffer[buf]; + + if (draw->pt.vertex_element[j].instance_divisor) { + ii = draw->instance_id / draw->pt.vertex_element[j].instance_divisor; + } + + ptr += draw->pt.vertex_buffer[buf].buffer_offset; ptr += draw->pt.vertex_buffer[buf].stride * ii; ptr += draw->pt.vertex_element[j].src_offset; @@ -341,19 +347,22 @@ draw_arrays_instanced(struct draw_context *draw, unsigned reduced_prim = u_reduced_prim(mode); unsigned instance; + assert(instanceCount > 0); + if (reduced_prim != draw->reduced_prim) { draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE); draw->reduced_prim = reduced_prim; } if (0) - draw_print_arrays(draw, mode, start, MIN2(count, 20)); - - if (0) { - unsigned int i; debug_printf("draw_arrays(mode=%u start=%u count=%u):\n", mode, start, count); + + if (0) tgsi_dump(draw->vs.vertex_shader->state.tokens, 0); + + if (0) { + unsigned int i; debug_printf("Elements:\n"); for (i = 0; i < draw->pt.nr_vertex_elements; i++) { debug_printf(" %u: src_offset=%u inst_div=%u vbuf=%u format=%s\n", @@ -374,6 +383,9 @@ draw_arrays_instanced(struct draw_context *draw, } } + if (0) + draw_print_arrays(draw, mode, start, MIN2(count, 20)); + for (instance = 0; instance < instanceCount; instance++) { draw->instance_id = instance + startInstance; draw_pt_arrays(draw, mode, start, count); diff --git a/src/gallium/auxiliary/draw/draw_pt_decompose.h b/src/gallium/auxiliary/draw/draw_pt_decompose.h index 52f9593d46e..3127aad7310 100644 --- a/src/gallium/auxiliary/draw/draw_pt_decompose.h +++ b/src/gallium/auxiliary/draw/draw_pt_decompose.h @@ -1,194 +1,7 @@ +#define LOCAL_VARS \ + char *verts = (char *) vertices; \ + const boolean last_vertex_last = \ + !(draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); - -static void FUNC( ARGS, - unsigned count ) -{ - LOCAL_VARS; - - switch (prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - POINT( (i + 0) ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - LINE( DRAW_PIPE_RESET_STIPPLE, - (i + 0), - (i + 1)); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - flags = DRAW_PIPE_RESET_STIPPLE; - - for (i = 1; i < count; i++, flags = 0) { - LINE( flags, - (i - 1), - (i )); - } - - LINE( flags, - (i - 1), - (0 )); - } - break; - - case PIPE_PRIM_LINE_STRIP: - flags = DRAW_PIPE_RESET_STIPPLE; - for (i = 1; i < count; i++, flags = 0) { - LINE( flags, - (i - 1), - (i )); - } - break; - - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (i + 0), - (i + 1), - (i + 2 )); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - /* Emit first triangle vertex as first triangle vertex */ - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (i + 0), - (i + 1 + (i&1)), - (i + 2 - (i&1)) ); - } - } - else { - for (i = 0; i+2 < count; i++) { - /* Emit last triangle vertex as last triangle vertex */ - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (i + 0 + (i&1)), - (i + 1 - (i&1)), - (i + 2 )); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (i + 1), - (i + 2), - 0 ); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - (0), - (i + 1), - (i + 2 )); - } - } - } - break; - - - case PIPE_PRIM_QUADS: - /* GL quads don't follow provoking vertex convention */ - if (flatfirst) { - for (i = 0; i+3 < count; i += 4) { - /* emit last quad vertex as first triangle vertex */ - QUAD_FIRST_PV( (i + 3), - (i + 0), - (i + 1), - (i + 2) ); - } - } - else { - for (i = 0; i+3 < count; i += 4) { - /* emit last quad vertex as last triangle vertex */ - QUAD_LAST_PV( (i + 0), - (i + 1), - (i + 2), - (i + 3) ); - } - } - break; - - case PIPE_PRIM_QUAD_STRIP: - /* GL quad strips don't follow provoking vertex convention */ - if (flatfirst) { - for (i = 0; i+3 < count; i += 2) { - /* emit last quad vertex as first triangle vertex */ - QUAD_FIRST_PV( (i + 3), - (i + 2), - (i + 0), - (i + 1) ); - - } - } - else { - for (i = 0; i+3 < count; i += 2) { - /* emit last quad vertex as last triangle vertex */ - QUAD_LAST_PV( (i + 2), - (i + 0), - (i + 1), - (i + 3) ); - } - } - break; - - case PIPE_PRIM_POLYGON: - /* GL polygons don't follow provoking vertex convention */ - { - /* These bitflags look a little odd because we submit the - * vertices as (1,2,0) to satisfy flatshade requirements. - */ - const ushort edge_first = DRAW_PIPE_EDGE_FLAG_2; - const ushort edge_middle = DRAW_PIPE_EDGE_FLAG_0; - const ushort edge_last = DRAW_PIPE_EDGE_FLAG_1; - - flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle; - - for (i = 0; i+2 < count; i++, flags = edge_middle) { - - if (i + 3 == count) - flags |= edge_last; - - if (flatfirst) { - /* emit first polygon vertex as first triangle vertex */ - TRIANGLE( flags, - (0), - (i + 1), - (i + 2) ); - } - else { - /* emit first polygon vertex as last triangle vertex */ - TRIANGLE( flags, - (i + 1), - (i + 2), - (0)); - } - } - } - break; - - default: - assert(0); - break; - } - - FLUSH; -} - - -#undef TRIANGLE -#undef QUAD_FIRST_PV -#undef QUAD_LAST_PV -#undef POINT -#undef LINE -#undef FUNC +#include "draw_decompose_tmp.h" diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c index 0229bcc7fe1..5568fbb9f88 100644 --- a/src/gallium/auxiliary/draw/draw_pt_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_emit.c @@ -182,6 +182,7 @@ void draw_pt_emit( struct pt_emit *emit, 0, ~0); + /* fetch/translate vertex attribs to fill hw_verts[] */ translate->run( translate, 0, vertex_count, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c index 121dfc414a4..5b16c3788e5 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c @@ -176,6 +176,7 @@ static void emit(struct pt_emit *emit, static void draw_vertex_shader_run(struct draw_vertex_shader *vshader, const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS], const struct draw_vertex_info *input_verts, struct draw_vertex_info *output_verts ) { @@ -190,6 +191,7 @@ static void draw_vertex_shader_run(struct draw_vertex_shader *vshader, (const float (*)[4])input_verts->verts->data, ( float (*)[4])output_verts->verts->data, constants, + const_size, input_verts->count, input_verts->vertex_size, input_verts->vertex_size); @@ -236,6 +238,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, if (fpme->opt & PT_SHADE) { draw_vertex_shader_run(vshader, draw->pt.user.vs_constants, + draw->pt.user.vs_constants_size, vert_info, &vs_vert_info); @@ -246,6 +249,7 @@ static void fetch_pipeline_generic( struct draw_pt_middle_end *middle, if ((fpme->opt & PT_SHADE) && gshader) { draw_geometry_shader_run(gshader, draw->pt.user.gs_constants, + draw->pt.user.gs_constants_size, vert_info, prim_info, &gs_vert_info, diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index bc074df8c2a..4b99bee86a0 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2010 VMWare, Inc. + * Copyright 2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -254,6 +254,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, if ((opt & PT_SHADE) && gshader) { draw_geometry_shader_run(gshader, draw->pt.user.gs_constants, + draw->pt.user.gs_constants_size, vert_info, prim_info, &gs_vert_info, diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c index 5d82934889b..f7f4f24d354 100644 --- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c @@ -218,25 +218,15 @@ static void so_tri(struct pt_so_emit *so, int i0, int i1, int i2) } -#define TRIANGLE(gs,i0,i1,i2) so_tri(so,i0,i1,i2) -#define LINE(gs,i0,i1) so_line(so,i0,i1) -#define POINT(gs,i0) so_point(so,i0) -#define FUNC so_run_linear -#define LOCAL_VARS +#define FUNC so_run_linear +#define GET_ELT(idx) (start + (idx)) #include "draw_so_emit_tmp.h" -#undef LOCAL_VARS -#undef FUNC -#define TRIANGLE(gs,i0,i1,i2) so_tri(gs,elts[i0],elts[i1],elts[i2]) -#define LINE(gs,i0,i1) so_line(gs,elts[i0],elts[i1]) -#define POINT(gs,i0) so_point(gs,elts[i0]) -#define FUNC so_run_elts -#define LOCAL_VARS \ - const ushort *elts = input_prims->elts; +#define FUNC so_run_elts +#define LOCAL_VARS const ushort *elts = input_prims->elts; +#define GET_ELT(idx) (elts[start + (idx)] & ~DRAW_PIPE_FLAG_MASK) #include "draw_so_emit_tmp.h" -#undef LOCAL_VARS -#undef FUNC void draw_pt_so_emit( struct pt_so_emit *emit, diff --git a/src/gallium/auxiliary/draw/draw_pt_util.c b/src/gallium/auxiliary/draw/draw_pt_util.c index 3236d38e6ab..182a597cca2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_util.c +++ b/src/gallium/auxiliary/draw/draw_pt_util.c @@ -53,7 +53,7 @@ void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr) break; case PIPE_PRIM_LINES_ADJACENCY: *first = 4; - *incr = 2; + *incr = 4; break; case PIPE_PRIM_LINE_STRIP_ADJACENCY: *first = 4; @@ -65,7 +65,7 @@ void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr) break; case PIPE_PRIM_TRIANGLES_ADJACENCY: *first = 6; - *incr = 3; + *incr = 6; break; case PIPE_PRIM_TRIANGLE_STRIP: case PIPE_PRIM_TRIANGLE_FAN: @@ -75,7 +75,7 @@ void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr) break; case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: *first = 6; - *incr = 1; + *incr = 2; break; case PIPE_PRIM_QUADS: *first = 4; diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h index a292346be95..55e43b2a714 100644 --- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h +++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h @@ -1,6 +1,11 @@ static unsigned trim( unsigned count, unsigned first, unsigned incr ) { - return count - (count - first) % incr; + /* + * count either has been trimmed in draw_pt_arrays or is set to + * (driver)_fetch_max which is hopefully always larger than first. + */ + assert(count >= first); + return count - (count - first) % incr; } static void FUNC(struct draw_pt_front_end *frontend, diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c index 8ef94c3163c..a848b54f7d2 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache.c +++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c @@ -95,7 +95,7 @@ static INLINE void vcache_check_flush( struct vcache_frontend *vcache ) { if (vcache->draw_count + 6 >= DRAW_MAX || - vcache->fetch_count + 4 >= FETCH_MAX) { + vcache->fetch_count + 6 >= FETCH_MAX) { vcache_flush( vcache ); } } @@ -180,59 +180,61 @@ vcache_point( struct vcache_frontend *vcache, } -static INLINE void -vcache_quad( struct vcache_frontend *vcache, - unsigned i0, - unsigned i1, - unsigned i2, - unsigned i3 ) +static INLINE void +vcache_line_adj_flags( struct vcache_frontend *vcache, + unsigned flags, + unsigned a0, unsigned i0, unsigned i1, unsigned a1 ) { - if (vcache->draw->rasterizer->flatshade_first) { - /* pass last quad vertex as first triangle vertex */ - vcache_triangle( vcache, i3, i0, i1 ); - vcache_triangle( vcache, i3, i1, i2 ); - } - else { - /* pass last quad vertex as last triangle vertex */ - vcache_triangle( vcache, i0, i1, i3 ); - vcache_triangle( vcache, i1, i2, i3 ); - } + vcache_elt(vcache, a0, 0); + vcache_elt(vcache, i0, flags); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, a1, 0); + vcache_check_flush(vcache); } -static INLINE void -vcache_ef_quad( struct vcache_frontend *vcache, - unsigned i0, - unsigned i1, - unsigned i2, - unsigned i3 ) +static INLINE void +vcache_line_adj( struct vcache_frontend *vcache, + unsigned a0, unsigned i0, unsigned i1, unsigned a1 ) { - if (vcache->draw->rasterizer->flatshade_first) { - /* pass last quad vertex as first triangle vertex */ - vcache_triangle_flags( vcache, - ( DRAW_PIPE_RESET_STIPPLE | - DRAW_PIPE_EDGE_FLAG_0 | - DRAW_PIPE_EDGE_FLAG_1 ), - i3, i0, i1 ); - - vcache_triangle_flags( vcache, - ( DRAW_PIPE_EDGE_FLAG_1 | - DRAW_PIPE_EDGE_FLAG_2 ), - i3, i1, i2 ); - } - else { - /* pass last quad vertex as last triangle vertex */ - vcache_triangle_flags( vcache, - ( DRAW_PIPE_RESET_STIPPLE | - DRAW_PIPE_EDGE_FLAG_0 | - DRAW_PIPE_EDGE_FLAG_2 ), - i0, i1, i3 ); - - vcache_triangle_flags( vcache, - ( DRAW_PIPE_EDGE_FLAG_0 | - DRAW_PIPE_EDGE_FLAG_1 ), - i1, i2, i3 ); - } + vcache_elt(vcache, a0, 0); + vcache_elt(vcache, i0, 0); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, a1, 0); + vcache_check_flush(vcache); +} + + +static INLINE void +vcache_triangle_adj_flags( struct vcache_frontend *vcache, + unsigned flags, + unsigned i0, unsigned a0, + unsigned i1, unsigned a1, + unsigned i2, unsigned a2 ) +{ + vcache_elt(vcache, i0, flags); + vcache_elt(vcache, a0, 0); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, a1, 0); + vcache_elt(vcache, i2, 0); + vcache_elt(vcache, a2, 0); + vcache_check_flush(vcache); +} + + +static INLINE void +vcache_triangle_adj( struct vcache_frontend *vcache, + unsigned i0, unsigned a0, + unsigned i1, unsigned a1, + unsigned i2, unsigned a2 ) +{ + vcache_elt(vcache, i0, 0); + vcache_elt(vcache, a0, 0); + vcache_elt(vcache, i1, 0); + vcache_elt(vcache, a1, 0); + vcache_elt(vcache, i2, 0); + vcache_elt(vcache, a2, 0); + vcache_check_flush(vcache); } @@ -240,17 +242,23 @@ vcache_ef_quad( struct vcache_frontend *vcache, * this. The two paths aren't too different though - it may be * possible to reunify them. */ -#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle_flags(vc,flags,i0,i1,i2) -#define QUAD(vc,i0,i1,i2,i3) vcache_ef_quad(vc,i0,i1,i2,i3) -#define LINE(vc,flags,i0,i1) vcache_line_flags(vc,flags,i0,i1) -#define POINT(vc,i0) vcache_point(vc,i0) +#define TRIANGLE(flags,i0,i1,i2) vcache_triangle_flags(vcache,flags,i0,i1,i2) +#define LINE(flags,i0,i1) vcache_line_flags(vcache,flags,i0,i1) +#define POINT(i0) vcache_point(vcache,i0) +#define LINE_ADJ(flags,a0,i0,i1,a1) \ + vcache_line_adj_flags(vcache,flags,a0,i0,i1,a1) +#define TRIANGLE_ADJ(flags,i0,a0,i1,a1,i2,a2) \ + vcache_triangle_adj_flags(vcache,flags,i0,a0,i1,a1,i2,a2) #define FUNC vcache_run_extras #include "draw_pt_vcache_tmp.h" -#define TRIANGLE(vc,flags,i0,i1,i2) vcache_triangle(vc,i0,i1,i2) -#define QUAD(vc,i0,i1,i2,i3) vcache_quad(vc,i0,i1,i2,i3) -#define LINE(vc,flags,i0,i1) vcache_line(vc,i0,i1) -#define POINT(vc,i0) vcache_point(vc,i0) +#define TRIANGLE(flags,i0,i1,i2) vcache_triangle(vcache,i0,i1,i2) +#define LINE(flags,i0,i1) vcache_line(vcache,i0,i1) +#define POINT(i0) vcache_point(vcache,i0) +#define LINE_ADJ(flags,a0,i0,i1,a1) \ + vcache_line_adj(vcache,a0,i0,i1,a1) +#define TRIANGLE_ADJ(flags,i0,a0,i1,a1,i2,a2) \ + vcache_triangle_adj(vcache,i0,a0,i1,a1,i2,a2) #define FUNC vcache_run #include "draw_pt_vcache_tmp.h" @@ -339,6 +347,25 @@ format_from_get_elt( pt_elt_func get_elt ) #endif +/** + * Check if any vertex attributes use instance divisors. + * Note that instance divisors complicate vertex fetching so we need + * to take the vcache path when they're in use. + */ +static boolean +any_instance_divisors(const struct draw_context *draw) +{ + uint i; + + for (i = 0; i < draw->pt.nr_vertex_elements; i++) { + uint div = draw->pt.vertex_element[i].instance_divisor; + if (div) + return TRUE; + } + return FALSE; +} + + static INLINE void vcache_check_run( struct draw_pt_front_end *frontend, pt_elt_func get_elt, @@ -382,6 +409,9 @@ vcache_check_run( struct draw_pt_front_end *frontend, if (max_index >= (unsigned) DRAW_PIPE_MAX_VERTICES) goto fail; + if (any_instance_divisors(draw)) + goto fail; + fetch_count = max_index + 1 - min_index; if (0) @@ -518,7 +548,18 @@ vcache_prepare( struct draw_pt_front_end *frontend, * which is a separate issue. */ vcache->input_prim = in_prim; - vcache->output_prim = u_reduced_prim(in_prim); + switch (in_prim) { + case PIPE_PRIM_LINES_ADJACENCY: + case PIPE_PRIM_LINE_STRIP_ADJACENCY: + vcache->output_prim = PIPE_PRIM_LINES_ADJACENCY; + break; + case PIPE_PRIM_TRIANGLES_ADJACENCY: + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: + vcache->output_prim = PIPE_PRIM_TRIANGLES_ADJACENCY; + break; + default: + vcache->output_prim = u_reduced_prim(in_prim); + } vcache->middle = middle; vcache->opt = opt; diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h index dac68ad4398..1a3748d5f0b 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_vcache_tmp.h @@ -1,198 +1,19 @@ +#define FUNC_VARS \ + struct draw_pt_front_end *frontend, \ + pt_elt_func get_elt, \ + const void *elts, \ + int elt_bias, \ + unsigned count +#define LOCAL_VARS \ + struct vcache_frontend *vcache = (struct vcache_frontend *) frontend; \ + struct draw_context *draw = vcache->draw; \ + const unsigned prim = vcache->input_prim; \ + const boolean last_vertex_last = !(draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); -static void FUNC( struct draw_pt_front_end *frontend, - pt_elt_func get_elt, - const void *elts, - int elt_bias, - unsigned count ) -{ - struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; - struct draw_context *draw = vcache->draw; +#define GET_ELT(idx) (get_elt(elts, idx) + elt_bias) - boolean flatfirst = (draw->rasterizer->flatshade && - draw->rasterizer->flatshade_first); - unsigned i; - ushort flags; +#define FUNC_EXIT do { vcache_flush(vcache); } while (0) - if (0) debug_printf("%s %d\n", __FUNCTION__, count); - - - switch (vcache->input_prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i ++) { - POINT( vcache, - get_elt(elts, i + 0) + elt_bias ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - LINE( vcache, - DRAW_PIPE_RESET_STIPPLE, - get_elt(elts, i + 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - flags = DRAW_PIPE_RESET_STIPPLE; - - for (i = 1; i < count; i++, flags = 0) { - LINE( vcache, - flags, - get_elt(elts, i - 1) + elt_bias, - get_elt(elts, i ) + elt_bias); - } - - LINE( vcache, - flags, - get_elt(elts, i - 1) + elt_bias, - get_elt(elts, 0 ) + elt_bias); - } - break; - - case PIPE_PRIM_LINE_STRIP: - flags = DRAW_PIPE_RESET_STIPPLE; - for (i = 1; i < count; i++, flags = 0) { - LINE( vcache, - flags, - get_elt(elts, i - 1) + elt_bias, - get_elt(elts, i ) + elt_bias); - } - break; - - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2 ) + elt_bias); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 0) + elt_bias, - get_elt(elts, i + 1 + (i&1)) + elt_bias, - get_elt(elts, i + 2 - (i&1)) + elt_bias); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 0 + (i&1)) + elt_bias, - get_elt(elts, i + 1 - (i&1)) + elt_bias, - get_elt(elts, i + 2 ) + elt_bias); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2) + elt_bias, - get_elt(elts, 0 ) + elt_bias); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( vcache, - DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL, - get_elt(elts, 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2 ) + elt_bias); - } - } - } - break; - - - case PIPE_PRIM_QUADS: - for (i = 0; i+3 < count; i += 4) { - QUAD( vcache, - get_elt(elts, i + 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2) + elt_bias, - get_elt(elts, i + 3) + elt_bias ); - } - break; - - case PIPE_PRIM_QUAD_STRIP: - for (i = 0; i+3 < count; i += 2) { - QUAD( vcache, - get_elt(elts, i + 2) + elt_bias, - get_elt(elts, i + 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 3) + elt_bias ); - } - break; - - case PIPE_PRIM_POLYGON: - { - /* These bitflags look a little odd because we submit the - * vertices as (1,2,0) to satisfy flatshade requirements. - */ - ushort edge_next, edge_finish; - - if (flatfirst) { - flags = (DRAW_PIPE_RESET_STIPPLE | - DRAW_PIPE_EDGE_FLAG_1 | - DRAW_PIPE_EDGE_FLAG_2); - edge_next = DRAW_PIPE_EDGE_FLAG_2; - edge_finish = DRAW_PIPE_EDGE_FLAG_0; - } - else { - flags = (DRAW_PIPE_RESET_STIPPLE | - DRAW_PIPE_EDGE_FLAG_2 | - DRAW_PIPE_EDGE_FLAG_0); - edge_next = DRAW_PIPE_EDGE_FLAG_0; - edge_finish = DRAW_PIPE_EDGE_FLAG_1; - } - - for (i = 0; i+2 < count; i++, flags = edge_next) { - - if (i + 3 == count) - flags |= edge_finish; - - if (flatfirst) { - TRIANGLE( vcache, - flags, - get_elt(elts, 0) + elt_bias, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2) + elt_bias ); - } - else { - TRIANGLE( vcache, - flags, - get_elt(elts, i + 1) + elt_bias, - get_elt(elts, i + 2) + elt_bias, - get_elt(elts, 0) + elt_bias); - } - } - } - break; - - default: - assert(0); - break; - } - - vcache_flush( vcache ); -} - - -#undef TRIANGLE -#undef QUAD -#undef POINT -#undef LINE -#undef FUNC +#include "draw_decompose_tmp.h" diff --git a/src/gallium/auxiliary/draw/draw_so_emit_tmp.h b/src/gallium/auxiliary/draw/draw_so_emit_tmp.h index 01212a8e536..6d8937a0b41 100644 --- a/src/gallium/auxiliary/draw/draw_so_emit_tmp.h +++ b/src/gallium/auxiliary/draw/draw_so_emit_tmp.h @@ -1,123 +1,33 @@ - -static void FUNC( struct pt_so_emit *so, - const struct draw_prim_info *input_prims, - const struct draw_vertex_info *input_verts, - unsigned start, - unsigned count) -{ - struct draw_context *draw = so->draw; - - boolean flatfirst = (draw->rasterizer->flatshade && - draw->rasterizer->flatshade_first); - unsigned i; - LOCAL_VARS - - if (0) debug_printf("%s %d\n", __FUNCTION__, count); - - debug_assert(input_prims->primitive_count == 1); - - switch (input_prims->prim) { - case PIPE_PRIM_POINTS: - for (i = 0; i < count; i++) { - POINT( so, start + i + 0 ); - } - break; - - case PIPE_PRIM_LINES: - for (i = 0; i+1 < count; i += 2) { - LINE( so , start + i + 0 , start + i + 1 ); - } - break; - - case PIPE_PRIM_LINE_LOOP: - if (count >= 2) { - - for (i = 1; i < count; i++) { - LINE( so, start + i - 1, start + i ); - } - - LINE( so, start + i - 1, start ); - } - break; - - case PIPE_PRIM_LINE_STRIP: - for (i = 1; i < count; i++) { - LINE( so, start + i - 1, start + i ); - } - break; - - case PIPE_PRIM_TRIANGLES: - for (i = 0; i+2 < count; i += 3) { - TRIANGLE( so, start + i + 0, start + i + 1, start + i + 2 ); - } - break; - - case PIPE_PRIM_TRIANGLE_STRIP: - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( so, - start + i + 0, - start + i + 1 + (i&1), - start + i + 2 - (i&1) ); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( so, - start + i + 0 + (i&1), - start + i + 1 - (i&1), - start + i + 2 ); - } - } - break; - - case PIPE_PRIM_TRIANGLE_FAN: - if (count >= 3) { - if (flatfirst) { - for (i = 0; i+2 < count; i++) { - TRIANGLE( so, - start + i + 1, - start + i + 2, - start ); - } - } - else { - for (i = 0; i+2 < count; i++) { - TRIANGLE( so, - start, - start + i + 1, - start + i + 2 ); - } - } - } - break; - - case PIPE_PRIM_POLYGON: - { - /* These bitflags look a little odd because we submit the - * vertices as (1,2,0) to satisfy flatshade requirements. - */ - - for (i = 0; i+2 < count; i++) { - - if (flatfirst) { - TRIANGLE( so, start + 0, start + i + 1, start + i + 2 ); - } - else { - TRIANGLE( so, start + i + 1, start + i + 2, start + 0 ); - } - } - } - break; - - default: - debug_assert(!"Unsupported primitive in stream output"); - break; - } -} - - -#undef TRIANGLE -#undef POINT -#undef LINE -#undef FUNC +#define FUNC_VARS \ + struct pt_so_emit *so, \ + const struct draw_prim_info *input_prims, \ + const struct draw_vertex_info *input_verts, \ + unsigned start, \ + unsigned count + +#define FUNC_ENTER \ + /* declare more local vars */ \ + struct draw_context *draw = so->draw; \ + const unsigned prim = input_prims->prim; \ + const boolean last_vertex_last = \ + !(draw->rasterizer->flatshade && \ + draw->rasterizer->flatshade_first); \ + do { \ + debug_assert(input_prims->primitive_count == 1); \ + switch (prim) { \ + case PIPE_PRIM_LINES_ADJACENCY: \ + case PIPE_PRIM_LINE_STRIP_ADJACENCY: \ + case PIPE_PRIM_TRIANGLES_ADJACENCY: \ + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: \ + debug_assert(!"unexpected primitive type in stream output"); \ + return; \ + default: \ + break; \ + } \ + } while (0) \ + +#define POINT(i0) so_point(so,i0) +#define LINE(flags,i0,i1) so_line(so,i0,i1) +#define TRIANGLE(flags,i0,i1,i2) so_tri(so,i0,i1,i2) + +#include "draw_decompose_tmp.h" diff --git a/src/gallium/auxiliary/draw/draw_vertex.h b/src/gallium/auxiliary/draw/draw_vertex.h index 3af31ffe126..e63cf5f4f98 100644 --- a/src/gallium/auxiliary/draw/draw_vertex.h +++ b/src/gallium/auxiliary/draw/draw_vertex.h @@ -166,7 +166,7 @@ static INLINE enum pipe_format draw_translate_vinfo_format(enum attrib_emit emit } } -static INLINE enum attrib_emit draw_translate_vinfo_size(enum attrib_emit emit) +static INLINE unsigned draw_translate_vinfo_size(enum attrib_emit emit) { switch (emit) { case EMIT_OMIT: diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 57ea63fc060..fb665b08fff 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -48,18 +48,30 @@ DEBUG_GET_ONCE_BOOL_OPTION(gallium_dump_vs, "GALLIUM_DUMP_VS", FALSE) + +/** + * Set a vertex shader constant buffer. + * \param slot which constant buffer in [0, PIPE_MAX_CONSTANT_BUFFERS-1] + * \param constants the mapped buffer + * \param size size of buffer in bytes + */ void draw_vs_set_constants(struct draw_context *draw, unsigned slot, const void *constants, unsigned size) { - if (((uintptr_t)constants) & 0xf) { + const int alignment = 16; + + /* check if buffer is 16-byte aligned */ + if (((uintptr_t)constants) & (alignment - 1)) { + /* if not, copy the constants into a new, 16-byte aligned buffer */ if (size > draw->vs.const_storage_size[slot]) { if (draw->vs.aligned_constant_storage[slot]) { align_free((void *)draw->vs.aligned_constant_storage[slot]); } - draw->vs.aligned_constant_storage[slot] = align_malloc(size, 16); + draw->vs.aligned_constant_storage[slot] = + align_malloc(size, alignment); } assert(constants); memcpy((void *)draw->vs.aligned_constant_storage[slot], diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index a7319945234..f9a038788fb 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -133,7 +133,8 @@ struct draw_vertex_shader { void (*run_linear)( struct draw_vertex_shader *shader, const float (*input)[4], float (*output)[4], - const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ); diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index bc34d390dae..dab3eb1ca8e 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -85,7 +85,8 @@ static void vs_exec_run_linear( struct draw_vertex_shader *shader, const float (*input)[4], float (*output)[4], - const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ) @@ -95,9 +96,8 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, unsigned int i, j; unsigned slot; - for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { - machine->Consts[i] = constants[i]; - } + tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, + constants, const_size); for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c index 6c13df79132..d13ad24fff0 100644 --- a/src/gallium/auxiliary/draw/draw_vs_llvm.c +++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c @@ -49,6 +49,7 @@ vs_llvm_run_linear( struct draw_vertex_shader *shader, const float (*input)[4], float (*output)[4], const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ) diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index 14c95082a9d..0b0c6077c6f 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -84,6 +84,7 @@ vs_sse_run_linear( struct draw_vertex_shader *base, const float (*input)[4], float (*output)[4], const void *constants[PIPE_MAX_CONSTANT_BUFFERS], + const unsigned const_size[PIPE_MAX_CONSTANT_BUFFERS], unsigned count, unsigned input_stride, unsigned output_stride ) diff --git a/src/gallium/auxiliary/draw/draw_vs_varient.c b/src/gallium/auxiliary/draw/draw_vs_varient.c index 6eb26927f27..eacd1601877 100644 --- a/src/gallium/auxiliary/draw/draw_vs_varient.c +++ b/src/gallium/auxiliary/draw/draw_vs_varient.c @@ -149,7 +149,8 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient, vsvg->base.vs->run_linear( vsvg->base.vs, temp_buffer, temp_buffer, - vsvg->base.vs->draw->pt.user.vs_constants, + vsvg->base.vs->draw->pt.user.vs_constants, + vsvg->base.vs->draw->pt.user.vs_constants_size, count, temp_vertex_stride, temp_vertex_stride); @@ -214,7 +215,8 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient, vsvg->base.vs->run_linear( vsvg->base.vs, temp_buffer, temp_buffer, - vsvg->base.vs->draw->pt.user.vs_constants, + vsvg->base.vs->draw->pt.user.vs_constants, + vsvg->base.vs->draw->pt.user.vs_constants_size, count, temp_vertex_stride, temp_vertex_stride); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c index f5f2623e467..7b35dd4bb49 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2009 VMware, Inc. + * Copyright 2009-2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -59,6 +59,19 @@ #include "lp_bld_arit.h" +/* + * XXX: Increasing eliminates some artifacts, but adds others, most + * noticeably corruption in the Earth halo in Google Earth. + */ +#define RCP_NEWTON_STEPS 0 + +#define RSQRT_NEWTON_STEPS 0 + +#define EXP_POLY_DEGREE 3 + +#define LOG_POLY_DEGREE 5 + + /** * Generate min(a, b) * No checks for special case values of a or b = 1 or 0 are done. @@ -72,6 +85,9 @@ lp_build_min_simple(struct lp_build_context *bld, const char *intrinsic = NULL; LLVMValueRef cond; + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); + /* TODO: optimize the constant case */ if(type.width * type.length == 128) { @@ -118,6 +134,9 @@ lp_build_max_simple(struct lp_build_context *bld, const char *intrinsic = NULL; LLVMValueRef cond; + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); + /* TODO: optimize the constant case */ if(type.width * type.length == 128) { @@ -160,6 +179,8 @@ lp_build_comp(struct lp_build_context *bld, { const struct lp_type type = bld->type; + assert(lp_check_value(type, a)); + if(a == bld->one) return bld->zero; if(a == bld->zero) @@ -173,9 +194,15 @@ lp_build_comp(struct lp_build_context *bld, } if(LLVMIsConstant(a)) - return LLVMConstSub(bld->one, a); + if (type.floating) + return LLVMConstFSub(bld->one, a); + else + return LLVMConstSub(bld->one, a); else - return LLVMBuildSub(bld->builder, bld->one, a, ""); + if (type.floating) + return LLVMBuildFSub(bld->builder, bld->one, a, ""); + else + return LLVMBuildSub(bld->builder, bld->one, a, ""); } @@ -190,6 +217,9 @@ lp_build_add(struct lp_build_context *bld, const struct lp_type type = bld->type; LLVMValueRef res; + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); + if(a == bld->zero) return b; if(b == bld->zero) @@ -217,9 +247,15 @@ lp_build_add(struct lp_build_context *bld, } if(LLVMIsConstant(a) && LLVMIsConstant(b)) - res = LLVMConstAdd(a, b); + if (type.floating) + res = LLVMConstFAdd(a, b); + else + res = LLVMConstAdd(a, b); else - res = LLVMBuildAdd(bld->builder, a, b, ""); + if (type.floating) + res = LLVMBuildFAdd(bld->builder, a, b, ""); + else + res = LLVMBuildAdd(bld->builder, a, b, ""); /* clamp to ceiling of 1.0 */ if(bld->type.norm && (bld->type.floating || bld->type.fixed)) @@ -240,6 +276,8 @@ lp_build_sum_vector(struct lp_build_context *bld, LLVMValueRef index, res; unsigned i; + assert(lp_check_value(type, a)); + if (a == bld->zero) return bld->zero; if (a == bld->undef) @@ -253,9 +291,16 @@ lp_build_sum_vector(struct lp_build_context *bld, for (i = 1; i < type.length; i++) { index = LLVMConstInt(LLVMInt32Type(), i, 0); - res = LLVMBuildAdd(bld->builder, res, - LLVMBuildExtractElement(bld->builder, a, index, ""), - ""); + if (type.floating) + res = LLVMBuildFAdd(bld->builder, res, + LLVMBuildExtractElement(bld->builder, + a, index, ""), + ""); + else + res = LLVMBuildAdd(bld->builder, res, + LLVMBuildExtractElement(bld->builder, + a, index, ""), + ""); } return res; @@ -273,6 +318,9 @@ lp_build_sub(struct lp_build_context *bld, const struct lp_type type = bld->type; LLVMValueRef res; + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); + if(b == bld->zero) return a; if(a == bld->undef || b == bld->undef) @@ -300,9 +348,15 @@ lp_build_sub(struct lp_build_context *bld, } if(LLVMIsConstant(a) && LLVMIsConstant(b)) - res = LLVMConstSub(a, b); + if (type.floating) + res = LLVMConstFSub(a, b); + else + res = LLVMConstSub(a, b); else - res = LLVMBuildSub(bld->builder, a, b, ""); + if (type.floating) + res = LLVMBuildFSub(bld->builder, a, b, ""); + else + res = LLVMBuildSub(bld->builder, a, b, ""); if(bld->type.norm && (bld->type.floating || bld->type.fixed)) res = lp_build_max_simple(bld, res, bld->zero); @@ -360,6 +414,10 @@ lp_build_mul_u8n(LLVMBuilderRef builder, LLVMValueRef c8; LLVMValueRef ab; + assert(!i16_type.floating); + assert(lp_check_value(i16_type, a)); + assert(lp_check_value(i16_type, b)); + c8 = lp_build_const_int_vec(i16_type, 8); #if 0 @@ -395,6 +453,9 @@ lp_build_mul(struct lp_build_context *bld, LLVMValueRef shift; LLVMValueRef res; + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); + if(a == bld->zero) return bld->zero; if(a == bld->one) @@ -433,7 +494,10 @@ lp_build_mul(struct lp_build_context *bld, shift = NULL; if(LLVMIsConstant(a) && LLVMIsConstant(b)) { - res = LLVMConstMul(a, b); + if (type.floating) + res = LLVMConstFMul(a, b); + else + res = LLVMConstMul(a, b); if(shift) { if(type.sign) res = LLVMConstAShr(res, shift); @@ -442,7 +506,10 @@ lp_build_mul(struct lp_build_context *bld, } } else { - res = LLVMBuildMul(bld->builder, a, b, ""); + if (type.floating) + res = LLVMBuildFMul(bld->builder, a, b, ""); + else + res = LLVMBuildMul(bld->builder, a, b, ""); if(shift) { if(type.sign) res = LLVMBuildAShr(bld->builder, res, shift, ""); @@ -465,6 +532,8 @@ lp_build_mul_imm(struct lp_build_context *bld, { LLVMValueRef factor; + assert(lp_check_value(bld->type, a)); + if(b == 0) return bld->zero; @@ -472,7 +541,7 @@ lp_build_mul_imm(struct lp_build_context *bld, return a; if(b == -1) - return LLVMBuildNeg(bld->builder, a, ""); + return lp_build_negate(bld, a); if(b == 2 && bld->type.floating) return lp_build_add(bld, a, a); @@ -518,6 +587,9 @@ lp_build_div(struct lp_build_context *bld, { const struct lp_type type = bld->type; + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); + if(a == bld->zero) return bld->zero; if(a == bld->one) @@ -529,13 +601,24 @@ lp_build_div(struct lp_build_context *bld, if(a == bld->undef || b == bld->undef) return bld->undef; - if(LLVMIsConstant(a) && LLVMIsConstant(b)) - return LLVMConstFDiv(a, b); + if(LLVMIsConstant(a) && LLVMIsConstant(b)) { + if (type.floating) + return LLVMConstFDiv(a, b); + else if (type.sign) + return LLVMConstSDiv(a, b); + else + return LLVMConstUDiv(a, b); + } if(util_cpu_caps.has_sse && type.width == 32 && type.length == 4) return lp_build_mul(bld, a, lp_build_rcp(bld, b)); - return LLVMBuildFDiv(bld->builder, a, b, ""); + if (type.floating) + return LLVMBuildFDiv(bld->builder, a, b, ""); + else if (type.sign) + return LLVMBuildSDiv(bld->builder, a, b, ""); + else + return LLVMBuildUDiv(bld->builder, a, b, ""); } @@ -555,6 +638,10 @@ lp_build_lerp(struct lp_build_context *bld, LLVMValueRef delta; LLVMValueRef res; + assert(lp_check_value(bld->type, x)); + assert(lp_check_value(bld->type, v0)); + assert(lp_check_value(bld->type, v1)); + delta = lp_build_sub(bld, v1, v0); res = lp_build_mul(bld, x, delta); @@ -596,6 +683,9 @@ lp_build_min(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { + assert(lp_check_value(bld->type, a)); + assert(lp_check_value(bld->type, b)); + if(a == bld->undef || b == bld->undef) return bld->undef; @@ -624,6 +714,9 @@ lp_build_max(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { + assert(lp_check_value(bld->type, a)); + assert(lp_check_value(bld->type, b)); + if(a == bld->undef || b == bld->undef) return bld->undef; @@ -653,6 +746,10 @@ lp_build_clamp(struct lp_build_context *bld, LLVMValueRef min, LLVMValueRef max) { + assert(lp_check_value(bld->type, a)); + assert(lp_check_value(bld->type, min)); + assert(lp_check_value(bld->type, max)); + a = lp_build_min(bld, a, max); a = lp_build_max(bld, a, min); return a; @@ -669,6 +766,8 @@ lp_build_abs(struct lp_build_context *bld, const struct lp_type type = bld->type; LLVMTypeRef vec_type = lp_build_vec_type(type); + assert(lp_check_value(type, a)); + if(!type.sign) return a; @@ -702,7 +801,16 @@ LLVMValueRef lp_build_negate(struct lp_build_context *bld, LLVMValueRef a) { - return LLVMBuildNeg(bld->builder, a, ""); + assert(lp_check_value(bld->type, a)); + +#if HAVE_LLVM >= 0x0207 + if (bld->type.floating) + a = LLVMBuildFNeg(bld->builder, a, ""); + else +#endif + a = LLVMBuildNeg(bld->builder, a, ""); + + return a; } @@ -715,6 +823,8 @@ lp_build_sgn(struct lp_build_context *bld, LLVMValueRef cond; LLVMValueRef res; + assert(lp_check_value(type, a)); + /* Handle non-zero case */ if(!type.sign) { /* if not zero then sign must be positive */ @@ -773,6 +883,7 @@ lp_build_set_sign(struct lp_build_context *bld, LLVMValueRef val, res; assert(type.floating); + assert(lp_check_value(type, a)); /* val = reinterpret_cast<int>(a) */ val = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); @@ -1021,7 +1132,7 @@ lp_build_iround(struct lp_build_context *bld, half = LLVMBuildOr(bld->builder, sign, half, ""); half = LLVMBuildBitCast(bld->builder, half, vec_type, ""); - res = LLVMBuildAdd(bld->builder, a, half, ""); + res = LLVMBuildFAdd(bld->builder, a, half, ""); } res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, ""); @@ -1070,7 +1181,7 @@ lp_build_ifloor(struct lp_build_context *bld, offset = LLVMBuildAnd(bld->builder, offset, sign, ""); offset = LLVMBuildBitCast(bld->builder, offset, vec_type, "ifloor.offset"); - res = LLVMBuildAdd(bld->builder, a, offset, "ifloor.res"); + res = LLVMBuildFAdd(bld->builder, a, offset, "ifloor.res"); } /* round to nearest (toward zero) */ @@ -1120,7 +1231,7 @@ lp_build_iceil(struct lp_build_context *bld, offset = LLVMBuildAnd(bld->builder, offset, sign, ""); offset = LLVMBuildBitCast(bld->builder, offset, vec_type, "iceil.offset"); - res = LLVMBuildAdd(bld->builder, a, offset, "iceil.res"); + res = LLVMBuildFAdd(bld->builder, a, offset, "iceil.res"); } /* round to nearest (toward zero) */ @@ -1138,6 +1249,8 @@ lp_build_sqrt(struct lp_build_context *bld, LLVMTypeRef vec_type = lp_build_vec_type(type); char intrinsic[32]; + assert(lp_check_value(type, a)); + /* TODO: optimize the constant case */ /* TODO: optimize the constant case */ @@ -1148,12 +1261,39 @@ lp_build_sqrt(struct lp_build_context *bld, } +/** + * Do one Newton-Raphson step to improve reciprocate precision: + * + * x_{i+1} = x_i * (2 - a * x_i) + * + * See also: + * - http://en.wikipedia.org/wiki/Division_(digital)#Newton.E2.80.93Raphson_division + * - http://softwarecommunity.intel.com/articles/eng/1818.htm + */ +static INLINE LLVMValueRef +lp_build_rcp_refine(struct lp_build_context *bld, + LLVMValueRef a, + LLVMValueRef rcp_a) +{ + LLVMValueRef two = lp_build_const_vec(bld->type, 2.0); + LLVMValueRef res; + + res = LLVMBuildFMul(bld->builder, a, rcp_a, ""); + res = LLVMBuildFSub(bld->builder, two, res, ""); + res = LLVMBuildFMul(bld->builder, rcp_a, res, ""); + + return res; +} + + LLVMValueRef lp_build_rcp(struct lp_build_context *bld, LLVMValueRef a) { const struct lp_type type = bld->type; + assert(lp_check_value(type, a)); + if(a == bld->zero) return bld->undef; if(a == bld->one) @@ -1167,32 +1307,16 @@ lp_build_rcp(struct lp_build_context *bld, return LLVMConstFDiv(bld->one, a); if(util_cpu_caps.has_sse && type.width == 32 && type.length == 4) { - /* - * XXX: Added precision is not always necessary, so only enable this - * when we have a better system in place to track minimum precision. - */ - -#if 0 - /* - * Do one Newton-Raphson step to improve precision: - * - * x1 = (2 - a * rcp(a)) * rcp(a) - */ - - LLVMValueRef two = lp_build_const_vec(bld->type, 2.0); - LLVMValueRef rcp_a; LLVMValueRef res; + unsigned i; - rcp_a = lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rcp.ps", lp_build_vec_type(type), a); + res = lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rcp.ps", bld->vec_type, a); - res = LLVMBuildMul(bld->builder, a, rcp_a, ""); - res = LLVMBuildSub(bld->builder, two, res, ""); - res = LLVMBuildMul(bld->builder, res, rcp_a, ""); + for (i = 0; i < RCP_NEWTON_STEPS; ++i) { + res = lp_build_rcp_refine(bld, a, res); + } - return rcp_a; -#else - return lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rcp.ps", lp_build_vec_type(type), a); -#endif + return res; } return LLVMBuildFDiv(bld->builder, bld->one, a, ""); @@ -1200,6 +1324,33 @@ lp_build_rcp(struct lp_build_context *bld, /** + * Do one Newton-Raphson step to improve rsqrt precision: + * + * x_{i+1} = 0.5 * x_i * (3.0 - a * x_i * x_i) + * + * See also: + * - http://softwarecommunity.intel.com/articles/eng/1818.htm + */ +static INLINE LLVMValueRef +lp_build_rsqrt_refine(struct lp_build_context *bld, + LLVMValueRef a, + LLVMValueRef rsqrt_a) +{ + LLVMValueRef half = lp_build_const_vec(bld->type, 0.5); + LLVMValueRef three = lp_build_const_vec(bld->type, 3.0); + LLVMValueRef res; + + res = LLVMBuildFMul(bld->builder, rsqrt_a, rsqrt_a, ""); + res = LLVMBuildFMul(bld->builder, a, res, ""); + res = LLVMBuildFSub(bld->builder, three, res, ""); + res = LLVMBuildFMul(bld->builder, rsqrt_a, res, ""); + res = LLVMBuildFMul(bld->builder, half, res, ""); + + return res; +} + + +/** * Generate 1/sqrt(a) */ LLVMValueRef @@ -1208,10 +1359,22 @@ lp_build_rsqrt(struct lp_build_context *bld, { const struct lp_type type = bld->type; + assert(lp_check_value(type, a)); + assert(type.floating); - if(util_cpu_caps.has_sse && type.width == 32 && type.length == 4) - return lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rsqrt.ps", lp_build_vec_type(type), a); + if(util_cpu_caps.has_sse && type.width == 32 && type.length == 4) { + LLVMValueRef res; + unsigned i; + + res = lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rsqrt.ps", bld->vec_type, a); + + for (i = 0; i < RSQRT_NEWTON_STEPS; ++i) { + res = lp_build_rsqrt_refine(bld, a, res); + } + + return res; + } return lp_build_rcp(bld, lp_build_sqrt(bld, a)); } @@ -1270,7 +1433,7 @@ lp_build_sin(struct lp_build_context *bld, */ LLVMValueRef FOPi = lp_build_const_v4sf(1.27323954473516); - LLVMValueRef scale_y = LLVMBuildMul(b, x_abs, FOPi, "scale_y"); + LLVMValueRef scale_y = LLVMBuildFMul(b, x_abs, FOPi, "scale_y"); /* * store the integer part of y in mm0 @@ -1344,9 +1507,9 @@ lp_build_sin(struct lp_build_context *bld, * xmm2 = _mm_mul_ps(y, xmm2); * xmm3 = _mm_mul_ps(y, xmm3); */ - LLVMValueRef xmm1 = LLVMBuildMul(b, y_2, DP1, "xmm1"); - LLVMValueRef xmm2 = LLVMBuildMul(b, y_2, DP2, "xmm2"); - LLVMValueRef xmm3 = LLVMBuildMul(b, y_2, DP3, "xmm3"); + LLVMValueRef xmm1 = LLVMBuildFMul(b, y_2, DP1, "xmm1"); + LLVMValueRef xmm2 = LLVMBuildFMul(b, y_2, DP2, "xmm2"); + LLVMValueRef xmm3 = LLVMBuildFMul(b, y_2, DP3, "xmm3"); /* * x = _mm_add_ps(x, xmm1); @@ -1354,16 +1517,16 @@ lp_build_sin(struct lp_build_context *bld, * x = _mm_add_ps(x, xmm3); */ - LLVMValueRef x_1 = LLVMBuildAdd(b, x_abs, xmm1, "x_1"); - LLVMValueRef x_2 = LLVMBuildAdd(b, x_1, xmm2, "x_2"); - LLVMValueRef x_3 = LLVMBuildAdd(b, x_2, xmm3, "x_3"); + LLVMValueRef x_1 = LLVMBuildFAdd(b, x_abs, xmm1, "x_1"); + LLVMValueRef x_2 = LLVMBuildFAdd(b, x_1, xmm2, "x_2"); + LLVMValueRef x_3 = LLVMBuildFAdd(b, x_2, xmm3, "x_3"); /* * Evaluate the first polynom (0 <= x <= Pi/4) * * z = _mm_mul_ps(x,x); */ - LLVMValueRef z = LLVMBuildMul(b, x_3, x_3, "z"); + LLVMValueRef z = LLVMBuildFMul(b, x_3, x_3, "z"); /* * _PS_CONST(coscof_p0, 2.443315711809948E-005); @@ -1378,12 +1541,12 @@ lp_build_sin(struct lp_build_context *bld, * y = *(v4sf*)_ps_coscof_p0; * y = _mm_mul_ps(y, z); */ - LLVMValueRef y_3 = LLVMBuildMul(b, z, coscof_p0, "y_3"); - LLVMValueRef y_4 = LLVMBuildAdd(b, y_3, coscof_p1, "y_4"); - LLVMValueRef y_5 = LLVMBuildMul(b, y_4, z, "y_5"); - LLVMValueRef y_6 = LLVMBuildAdd(b, y_5, coscof_p2, "y_6"); - LLVMValueRef y_7 = LLVMBuildMul(b, y_6, z, "y_7"); - LLVMValueRef y_8 = LLVMBuildMul(b, y_7, z, "y_8"); + LLVMValueRef y_3 = LLVMBuildFMul(b, z, coscof_p0, "y_3"); + LLVMValueRef y_4 = LLVMBuildFAdd(b, y_3, coscof_p1, "y_4"); + LLVMValueRef y_5 = LLVMBuildFMul(b, y_4, z, "y_5"); + LLVMValueRef y_6 = LLVMBuildFAdd(b, y_5, coscof_p2, "y_6"); + LLVMValueRef y_7 = LLVMBuildFMul(b, y_6, z, "y_7"); + LLVMValueRef y_8 = LLVMBuildFMul(b, y_7, z, "y_8"); /* @@ -1392,10 +1555,10 @@ lp_build_sin(struct lp_build_context *bld, * y = _mm_add_ps(y, *(v4sf*)_ps_1); */ LLVMValueRef half = lp_build_const_v4sf(0.5); - LLVMValueRef tmp = LLVMBuildMul(b, z, half, "tmp"); - LLVMValueRef y_9 = LLVMBuildSub(b, y_8, tmp, "y_8"); + LLVMValueRef tmp = LLVMBuildFMul(b, z, half, "tmp"); + LLVMValueRef y_9 = LLVMBuildFSub(b, y_8, tmp, "y_8"); LLVMValueRef one = lp_build_const_v4sf(1.0); - LLVMValueRef y_10 = LLVMBuildAdd(b, y_9, one, "y_9"); + LLVMValueRef y_10 = LLVMBuildFAdd(b, y_9, one, "y_9"); /* * _PS_CONST(sincof_p0, -1.9515295891E-4); @@ -1419,13 +1582,13 @@ lp_build_sin(struct lp_build_context *bld, * y2 = _mm_add_ps(y2, x); */ - LLVMValueRef y2_3 = LLVMBuildMul(b, z, sincof_p0, "y2_3"); - LLVMValueRef y2_4 = LLVMBuildAdd(b, y2_3, sincof_p1, "y2_4"); - LLVMValueRef y2_5 = LLVMBuildMul(b, y2_4, z, "y2_5"); - LLVMValueRef y2_6 = LLVMBuildAdd(b, y2_5, sincof_p2, "y2_6"); - LLVMValueRef y2_7 = LLVMBuildMul(b, y2_6, z, "y2_7"); - LLVMValueRef y2_8 = LLVMBuildMul(b, y2_7, x_3, "y2_8"); - LLVMValueRef y2_9 = LLVMBuildAdd(b, y2_8, x_3, "y2_9"); + LLVMValueRef y2_3 = LLVMBuildFMul(b, z, sincof_p0, "y2_3"); + LLVMValueRef y2_4 = LLVMBuildFAdd(b, y2_3, sincof_p1, "y2_4"); + LLVMValueRef y2_5 = LLVMBuildFMul(b, y2_4, z, "y2_5"); + LLVMValueRef y2_6 = LLVMBuildFAdd(b, y2_5, sincof_p2, "y2_6"); + LLVMValueRef y2_7 = LLVMBuildFMul(b, y2_6, z, "y2_7"); + LLVMValueRef y2_8 = LLVMBuildFMul(b, y2_7, x_3, "y2_8"); + LLVMValueRef y2_9 = LLVMBuildFAdd(b, y2_8, x_3, "y2_9"); /* * select the correct result from the two polynoms @@ -1481,7 +1644,7 @@ lp_build_cos(struct lp_build_context *bld, */ LLVMValueRef FOPi = lp_build_const_v4sf(1.27323954473516); - LLVMValueRef scale_y = LLVMBuildMul(b, x_abs, FOPi, "scale_y"); + LLVMValueRef scale_y = LLVMBuildFMul(b, x_abs, FOPi, "scale_y"); /* * store the integer part of y in mm0 @@ -1561,9 +1724,9 @@ lp_build_cos(struct lp_build_context *bld, * xmm2 = _mm_mul_ps(y, xmm2); * xmm3 = _mm_mul_ps(y, xmm3); */ - LLVMValueRef xmm1 = LLVMBuildMul(b, y_2, DP1, "xmm1"); - LLVMValueRef xmm2 = LLVMBuildMul(b, y_2, DP2, "xmm2"); - LLVMValueRef xmm3 = LLVMBuildMul(b, y_2, DP3, "xmm3"); + LLVMValueRef xmm1 = LLVMBuildFMul(b, y_2, DP1, "xmm1"); + LLVMValueRef xmm2 = LLVMBuildFMul(b, y_2, DP2, "xmm2"); + LLVMValueRef xmm3 = LLVMBuildFMul(b, y_2, DP3, "xmm3"); /* * x = _mm_add_ps(x, xmm1); @@ -1571,16 +1734,16 @@ lp_build_cos(struct lp_build_context *bld, * x = _mm_add_ps(x, xmm3); */ - LLVMValueRef x_1 = LLVMBuildAdd(b, x_abs, xmm1, "x_1"); - LLVMValueRef x_2 = LLVMBuildAdd(b, x_1, xmm2, "x_2"); - LLVMValueRef x_3 = LLVMBuildAdd(b, x_2, xmm3, "x_3"); + LLVMValueRef x_1 = LLVMBuildFAdd(b, x_abs, xmm1, "x_1"); + LLVMValueRef x_2 = LLVMBuildFAdd(b, x_1, xmm2, "x_2"); + LLVMValueRef x_3 = LLVMBuildFAdd(b, x_2, xmm3, "x_3"); /* * Evaluate the first polynom (0 <= x <= Pi/4) * * z = _mm_mul_ps(x,x); */ - LLVMValueRef z = LLVMBuildMul(b, x_3, x_3, "z"); + LLVMValueRef z = LLVMBuildFMul(b, x_3, x_3, "z"); /* * _PS_CONST(coscof_p0, 2.443315711809948E-005); @@ -1595,12 +1758,12 @@ lp_build_cos(struct lp_build_context *bld, * y = *(v4sf*)_ps_coscof_p0; * y = _mm_mul_ps(y, z); */ - LLVMValueRef y_3 = LLVMBuildMul(b, z, coscof_p0, "y_3"); - LLVMValueRef y_4 = LLVMBuildAdd(b, y_3, coscof_p1, "y_4"); - LLVMValueRef y_5 = LLVMBuildMul(b, y_4, z, "y_5"); - LLVMValueRef y_6 = LLVMBuildAdd(b, y_5, coscof_p2, "y_6"); - LLVMValueRef y_7 = LLVMBuildMul(b, y_6, z, "y_7"); - LLVMValueRef y_8 = LLVMBuildMul(b, y_7, z, "y_8"); + LLVMValueRef y_3 = LLVMBuildFMul(b, z, coscof_p0, "y_3"); + LLVMValueRef y_4 = LLVMBuildFAdd(b, y_3, coscof_p1, "y_4"); + LLVMValueRef y_5 = LLVMBuildFMul(b, y_4, z, "y_5"); + LLVMValueRef y_6 = LLVMBuildFAdd(b, y_5, coscof_p2, "y_6"); + LLVMValueRef y_7 = LLVMBuildFMul(b, y_6, z, "y_7"); + LLVMValueRef y_8 = LLVMBuildFMul(b, y_7, z, "y_8"); /* @@ -1609,10 +1772,10 @@ lp_build_cos(struct lp_build_context *bld, * y = _mm_add_ps(y, *(v4sf*)_ps_1); */ LLVMValueRef half = lp_build_const_v4sf(0.5); - LLVMValueRef tmp = LLVMBuildMul(b, z, half, "tmp"); - LLVMValueRef y_9 = LLVMBuildSub(b, y_8, tmp, "y_8"); + LLVMValueRef tmp = LLVMBuildFMul(b, z, half, "tmp"); + LLVMValueRef y_9 = LLVMBuildFSub(b, y_8, tmp, "y_8"); LLVMValueRef one = lp_build_const_v4sf(1.0); - LLVMValueRef y_10 = LLVMBuildAdd(b, y_9, one, "y_9"); + LLVMValueRef y_10 = LLVMBuildFAdd(b, y_9, one, "y_9"); /* * _PS_CONST(sincof_p0, -1.9515295891E-4); @@ -1636,13 +1799,13 @@ lp_build_cos(struct lp_build_context *bld, * y2 = _mm_add_ps(y2, x); */ - LLVMValueRef y2_3 = LLVMBuildMul(b, z, sincof_p0, "y2_3"); - LLVMValueRef y2_4 = LLVMBuildAdd(b, y2_3, sincof_p1, "y2_4"); - LLVMValueRef y2_5 = LLVMBuildMul(b, y2_4, z, "y2_5"); - LLVMValueRef y2_6 = LLVMBuildAdd(b, y2_5, sincof_p2, "y2_6"); - LLVMValueRef y2_7 = LLVMBuildMul(b, y2_6, z, "y2_7"); - LLVMValueRef y2_8 = LLVMBuildMul(b, y2_7, x_3, "y2_8"); - LLVMValueRef y2_9 = LLVMBuildAdd(b, y2_8, x_3, "y2_9"); + LLVMValueRef y2_3 = LLVMBuildFMul(b, z, sincof_p0, "y2_3"); + LLVMValueRef y2_4 = LLVMBuildFAdd(b, y2_3, sincof_p1, "y2_4"); + LLVMValueRef y2_5 = LLVMBuildFMul(b, y2_4, z, "y2_5"); + LLVMValueRef y2_6 = LLVMBuildFAdd(b, y2_5, sincof_p2, "y2_6"); + LLVMValueRef y2_7 = LLVMBuildFMul(b, y2_6, z, "y2_7"); + LLVMValueRef y2_8 = LLVMBuildFMul(b, y2_7, x_3, "y2_8"); + LLVMValueRef y2_9 = LLVMBuildFAdd(b, y2_8, x_3, "y2_9"); /* * select the correct result from the two polynoms @@ -1695,6 +1858,8 @@ lp_build_exp(struct lp_build_context *bld, /* log2(e) = 1/log(2) */ LLVMValueRef log2e = lp_build_const_vec(bld->type, 1.4426950408889634); + assert(lp_check_value(bld->type, x)); + return lp_build_mul(bld, log2e, lp_build_exp2(bld, x)); } @@ -1709,14 +1874,12 @@ lp_build_log(struct lp_build_context *bld, /* log(2) */ LLVMValueRef log2 = lp_build_const_vec(bld->type, 0.69314718055994529); + assert(lp_check_value(bld->type, x)); + return lp_build_mul(bld, log2, lp_build_exp2(bld, x)); } -#define EXP_POLY_DEGREE 3 -#define LOG_POLY_DEGREE 5 - - /** * Generate polynomial. * Ex: coeffs[0] + x * coeffs[1] + x^2 * coeffs[2]. @@ -1731,6 +1894,8 @@ lp_build_polynomial(struct lp_build_context *bld, LLVMValueRef res = NULL; unsigned i; + assert(lp_check_value(bld->type, x)); + /* TODO: optimize the constant case */ if(LLVMIsConstant(x)) debug_printf("%s: inefficient/imprecise constant arithmetic\n", @@ -1802,6 +1967,8 @@ lp_build_exp2_approx(struct lp_build_context *bld, LLVMValueRef expfpart = NULL; LLVMValueRef res = NULL; + assert(lp_check_value(bld->type, x)); + if(p_exp2_int_part || p_frac_part || p_exp2) { /* TODO: optimize the constant case */ if(LLVMIsConstant(x)) @@ -1817,7 +1984,7 @@ lp_build_exp2_approx(struct lp_build_context *bld, ipart = lp_build_floor(bld, x); /* fpart = x - ipart */ - fpart = LLVMBuildSub(bld->builder, x, ipart, ""); + fpart = LLVMBuildFSub(bld->builder, x, ipart, ""); } if(p_exp2_int_part || p_exp2) { @@ -1832,7 +1999,7 @@ lp_build_exp2_approx(struct lp_build_context *bld, expfpart = lp_build_polynomial(bld, fpart, lp_build_exp2_polynomial, Elements(lp_build_exp2_polynomial)); - res = LLVMBuildMul(bld->builder, expipart, expfpart, ""); + res = LLVMBuildFMul(bld->builder, expipart, expfpart, ""); } if(p_exp2_int_part) @@ -1915,6 +2082,8 @@ lp_build_log2_approx(struct lp_build_context *bld, LLVMValueRef logmant = NULL; LLVMValueRef res = NULL; + assert(lp_check_value(bld->type, x)); + if(p_exp || p_floor_log2 || p_log2) { /* TODO: optimize the constant case */ if(LLVMIsConstant(x)) @@ -1945,9 +2114,9 @@ lp_build_log2_approx(struct lp_build_context *bld, Elements(lp_build_log2_polynomial)); /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/ - logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), ""); + logmant = LLVMBuildFMul(bld->builder, logmant, LLVMBuildFSub(bld->builder, mant, bld->one, ""), ""); - res = LLVMBuildAdd(bld->builder, logmant, logexp, ""); + res = LLVMBuildFAdd(bld->builder, logmant, logexp, ""); } if(p_exp) { diff --git a/src/gallium/auxiliary/gallivm/lp_bld_assert.c b/src/gallium/auxiliary/gallivm/lp_bld_assert.c new file mode 100644 index 00000000000..f2ebd868a8d --- /dev/null +++ b/src/gallium/auxiliary/gallivm/lp_bld_assert.c @@ -0,0 +1,101 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "lp_bld_assert.h" +#include "lp_bld_init.h" +#include "lp_bld_printf.h" + + +/** + * A call to lp_build_assert() will build a function call to this function. + */ +static void +lp_assert(int condition, const char *msg) +{ + if (!condition) { + debug_printf("LLVM assertion '%s' failed!\n", msg); + assert(condition); + } +} + + + +/** + * lp_build_assert. + * + * Build an assertion in LLVM IR by building a function call to the + * lp_assert() function above. + * + * \param condition should be an 'i1' or 'i32' value + * \param msg a string to print if the assertion fails. + */ +LLVMValueRef +lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition, + const char *msg) +{ + LLVMModuleRef module; + LLVMTypeRef arg_types[2]; + LLVMValueRef msg_string, assert_func, params[2], r; + + module = LLVMGetGlobalParent(LLVMGetBasicBlockParent( + LLVMGetInsertBlock(builder))); + + msg_string = lp_build_const_string_variable(module, msg, strlen(msg) + 1); + + arg_types[0] = LLVMInt32Type(); + arg_types[1] = LLVMPointerType(LLVMInt8Type(), 0); + + /* lookup the lp_assert function */ + assert_func = LLVMGetNamedFunction(module, "lp_assert"); + + /* Create the assertion function if not found */ + if (!assert_func) { + LLVMTypeRef func_type = + LLVMFunctionType(LLVMVoidType(), arg_types, 2, 0); + + assert_func = LLVMAddFunction(module, "lp_assert", func_type); + LLVMSetFunctionCallConv(assert_func, LLVMCCallConv); + LLVMSetLinkage(assert_func, LLVMExternalLinkage); + LLVMAddGlobalMapping(lp_build_engine, assert_func, + func_to_pointer((func_pointer)lp_assert)); + } + assert(assert_func); + + /* build function call param list */ + params[0] = LLVMBuildZExt(builder, condition, arg_types[0], ""); + params[1] = LLVMBuildBitCast(builder, msg_string, arg_types[1], ""); + + /* check arg types */ + assert(LLVMTypeOf(params[0]) == arg_types[0]); + assert(LLVMTypeOf(params[1]) == arg_types[1]); + + r = LLVMBuildCall(builder, assert_func, params, 2, ""); + + return r; +} diff --git a/src/gallium/state_trackers/dri/drm/dri2.h b/src/gallium/auxiliary/gallivm/lp_bld_assert.h index 07adfe4f6c5..ddd879dc2c6 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_assert.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2009, VMware, Inc. + * Copyright 2010 VMware, Inc. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -25,13 +25,17 @@ * **************************************************************************/ -#ifndef DRI2_H -#define DRI2_H +#ifndef LP_BLD_ASSERT_H +#define LP_BLD_ASSERT_H -#include "dri_drawable.h" -#include "dri_wrapper.h" -const __DRIconfig ** -dri2_init_screen(__DRIscreen * sPriv); +#include "lp_bld.h" + + +LLVMValueRef +lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition, + const char *msg); + + +#endif -#endif /* DRI2_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c index 77012f1fac6..8b477313d48 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_conv.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c @@ -117,8 +117,8 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder, scale = (double)mask/ubound; bias = (double)((unsigned long long)1 << (mantissa - n)); - res = LLVMBuildMul(builder, src, lp_build_const_vec(src_type, scale), ""); - res = LLVMBuildAdd(builder, res, lp_build_const_vec(src_type, bias), ""); + res = LLVMBuildFMul(builder, src, lp_build_const_vec(src_type, scale), ""); + res = LLVMBuildFAdd(builder, res, lp_build_const_vec(src_type, bias), ""); res = LLVMBuildBitCast(builder, res, int_vec_type, ""); if(dst_width > n) { @@ -175,6 +175,8 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder, double scale; double bias; + assert(dst_type.floating); + mantissa = lp_mantissa(dst_type); n = MIN2(mantissa, src_width); @@ -199,8 +201,8 @@ lp_build_unsigned_norm_to_float(LLVMBuilderRef builder, res = LLVMBuildBitCast(builder, res, vec_type, ""); - res = LLVMBuildSub(builder, res, bias_, ""); - res = LLVMBuildMul(builder, res, lp_build_const_vec(dst_type, scale), ""); + res = LLVMBuildFSub(builder, res, bias_, ""); + res = LLVMBuildFMul(builder, res, lp_build_const_vec(dst_type, scale), ""); return res; } @@ -296,7 +298,7 @@ lp_build_conv(LLVMBuilderRef builder, if (dst_scale != 1.0) { LLVMValueRef scale = lp_build_const_vec(tmp_type, dst_scale); for(i = 0; i < num_tmps; ++i) - tmp[i] = LLVMBuildMul(builder, tmp[i], scale, ""); + tmp[i] = LLVMBuildFMul(builder, tmp[i], scale, ""); } /* Use an equally sized integer for intermediate computations */ @@ -391,7 +393,7 @@ lp_build_conv(LLVMBuilderRef builder, if (src_scale != 1.0) { LLVMValueRef scale = lp_build_const_vec(tmp_type, 1.0/src_scale); for(i = 0; i < num_tmps; ++i) - tmp[i] = LLVMBuildMul(builder, tmp[i], scale, ""); + tmp[i] = LLVMBuildFMul(builder, tmp[i], scale, ""); } } } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c index 0f01fc1d75f..247cb83ce6c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c @@ -240,7 +240,7 @@ lp_build_unpack_arith_rgba_aos(LLVMBuilderRef builder, */ if (normalized) - scaled = LLVMBuildMul(builder, casted, LLVMConstVector(scales, 4), ""); + scaled = LLVMBuildFMul(builder, casted, LLVMConstVector(scales, 4), ""); else scaled = casted; @@ -322,7 +322,7 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder, } if (normalized) - scaled = LLVMBuildMul(builder, unswizzled, LLVMConstVector(scales, 4), ""); + scaled = LLVMBuildFMul(builder, unswizzled, LLVMConstVector(scales, 4), ""); else scaled = unswizzled; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c index 9f405921b0a..c724a4453e6 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c @@ -197,7 +197,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder, if (format_desc->channel[chan].normalized) { double scale = 1.0 / ((1 << (format_desc->channel[chan].size - 1)) - 1); LLVMValueRef scale_val = lp_build_const_vec(type, scale); - input = LLVMBuildMul(builder, input, scale_val, ""); + input = LLVMBuildFMul(builder, input, scale_val, ""); } } else { @@ -227,7 +227,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder, double scale = 1.0 / ((1 << (format_desc->channel[chan].size/2)) - 1); LLVMValueRef scale_val = lp_build_const_vec(type, scale); input = LLVMBuildSIToFP(builder, input, lp_build_vec_type(type), ""); - input = LLVMBuildMul(builder, input, scale_val, ""); + input = LLVMBuildFMul(builder, input, scale_val, ""); } else { /* FIXME */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c index 69353dea09e..60d8bcfa55e 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_init.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c @@ -45,6 +45,8 @@ static const struct debug_named_value lp_bld_debug_flags[] = { { "nopt", GALLIVM_DEBUG_NO_OPT, NULL }, DEBUG_NAMED_VALUE_END }; + +DEBUG_GET_ONCE_FLAGS_OPTION(gallivm_debug, "GALLIVM_DEBUG", lp_bld_debug_flags, 0) #endif @@ -89,7 +91,7 @@ void lp_build_init(void) { #ifdef DEBUG - gallivm_debug = debug_get_flags_option("GALLIVM_DEBUG", lp_bld_debug_flags, 0 ); + gallivm_debug = debug_get_option_gallivm_debug(); #endif lp_set_target_options(); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h index a32ced9b4c3..f26fdac4663 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_init.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h @@ -44,5 +44,7 @@ extern LLVMPassManagerRef lp_build_pass; void lp_build_init(void); +extern void +lp_func_delete_body(LLVMValueRef func); #endif /* !LP_BLD_INIT_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c index 39854e43b19..7d7db3b0d92 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_logic.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c @@ -83,6 +83,8 @@ lp_build_compare(LLVMBuilderRef builder, assert(func >= PIPE_FUNC_NEVER); assert(func <= PIPE_FUNC_ALWAYS); + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); if(func == PIPE_FUNC_NEVER) return zeros; @@ -363,9 +365,55 @@ lp_build_cmp(struct lp_build_context *bld, /** + * Return (mask & a) | (~mask & b); + */ +LLVMValueRef +lp_build_select_bitwise(struct lp_build_context *bld, + LLVMValueRef mask, + LLVMValueRef a, + LLVMValueRef b) +{ + struct lp_type type = bld->type; + LLVMValueRef res; + + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); + + if (a == b) { + return a; + } + + if(type.floating) { + LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); + a = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); + b = LLVMBuildBitCast(bld->builder, b, int_vec_type, ""); + } + + a = LLVMBuildAnd(bld->builder, a, mask, ""); + + /* This often gets translated to PANDN, but sometimes the NOT is + * pre-computed and stored in another constant. The best strategy depends + * on available registers, so it is not a big deal -- hopefully LLVM does + * the right decision attending the rest of the program. + */ + b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), ""); + + res = LLVMBuildOr(bld->builder, a, b, ""); + + if(type.floating) { + LLVMTypeRef vec_type = lp_build_vec_type(type); + res = LLVMBuildBitCast(bld->builder, res, vec_type, ""); + } + + return res; +} + + +/** * Return mask ? a : b; * - * mask is a bitwise mask, composed of 0 or ~0 for each element. + * mask is a bitwise mask, composed of 0 or ~0 for each element. Any other value + * will yield unpredictable results. */ LLVMValueRef lp_build_select(struct lp_build_context *bld, @@ -376,6 +424,9 @@ lp_build_select(struct lp_build_context *bld, struct lp_type type = bld->type; LLVMValueRef res; + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); + if(a == b) return a; @@ -424,27 +475,7 @@ lp_build_select(struct lp_build_context *bld, } } else { - if(type.floating) { - LLVMTypeRef int_vec_type = lp_build_int_vec_type(type); - a = LLVMBuildBitCast(bld->builder, a, int_vec_type, ""); - b = LLVMBuildBitCast(bld->builder, b, int_vec_type, ""); - } - - a = LLVMBuildAnd(bld->builder, a, mask, ""); - - /* This often gets translated to PANDN, but sometimes the NOT is - * pre-computed and stored in another constant. The best strategy depends - * on available registers, so it is not a big deal -- hopefully LLVM does - * the right decision attending the rest of the program. - */ - b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), ""); - - res = LLVMBuildOr(bld->builder, a, b, ""); - - if(type.floating) { - LLVMTypeRef vec_type = lp_build_vec_type(type); - res = LLVMBuildBitCast(bld->builder, res, vec_type, ""); - } + res = lp_build_select_bitwise(bld, mask, a, b); } return res; @@ -461,6 +492,9 @@ lp_build_select_aos(struct lp_build_context *bld, const unsigned n = type.length; unsigned i, j; + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); + if(a == b) return a; if(cond[0] && cond[1] && cond[2] && cond[3]) @@ -516,7 +550,22 @@ lp_build_select_aos(struct lp_build_context *bld, LLVMValueRef lp_build_andc(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b) { + const struct lp_type type = bld->type; + + assert(lp_check_value(type, a)); + assert(lp_check_value(type, b)); + + /* can't do bitwise ops on floating-point values */ + if(type.floating) { + a = LLVMBuildBitCast(bld->builder, a, bld->int_vec_type, ""); + b = LLVMBuildBitCast(bld->builder, b, bld->int_vec_type, ""); + } + b = LLVMBuildNot(bld->builder, b, ""); b = LLVMBuildAnd(bld->builder, a, b, ""); + + if(type.floating) { + b = LLVMBuildBitCast(bld->builder, b, bld->vec_type, ""); + } return b; } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.h b/src/gallium/auxiliary/gallivm/lp_bld_logic.h index 29f9fc3b205..4e7b4c9938e 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_logic.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.h @@ -63,6 +63,11 @@ lp_build_cmp(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b); +LLVMValueRef +lp_build_select_bitwise(struct lp_build_context *bld, + LLVMValueRef mask, + LLVMValueRef a, + LLVMValueRef b); LLVMValueRef lp_build_select(struct lp_build_context *bld, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index 5a9488b5f79..6d5410d9701 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -39,6 +39,7 @@ #include <llvm/Target/TargetOptions.h> #include <llvm/ExecutionEngine/ExecutionEngine.h> #include <llvm/ExecutionEngine/JITEventListener.h> +#include <llvm/Support/CommandLine.h> #include "pipe/p_config.h" #include "util/u_debug.h" @@ -141,4 +142,35 @@ lp_set_target_options(void) #if 0 llvm::UnsafeFPMath = true; #endif + +#if 0 + /* + * LLVM will generate MMX instructions for vectors <= 64 bits, leading to + * innefficient code, and in 32bit systems, to the corruption of the FPU + * stack given that it expects the user to generate the EMMS instructions. + * + * See also: + * - http://llvm.org/bugs/show_bug.cgi?id=3287 + * - http://l4.me.uk/post/2009/06/07/llvm-wrinkle-3-configuration-what-configuration/ + * + * XXX: Unfortunately this is not working. + */ + static boolean first = FALSE; + if (first) { + static const char* options[] = { + "prog", + "-disable-mmx" + }; + llvm::cl::ParseCommandLineOptions(2, const_cast<char**>(options)); + first = FALSE; + } +#endif +} + + +extern "C" void +lp_func_delete_body(LLVMValueRef FF) +{ + llvm::Function *func = llvm::unwrap<llvm::Function>(FF); + func->deleteBody(); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.c b/src/gallium/auxiliary/gallivm/lp_bld_pack.c index 7748f8f0999..b7b630f2e8d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_pack.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.c @@ -171,14 +171,13 @@ lp_build_unpack2(LLVMBuilderRef builder, msb = lp_build_zero(src_type); /* Interleave bits */ - if(util_cpu_caps.little_endian) { +#ifdef PIPE_ARCH_LITTLE_ENDIAN *dst_lo = lp_build_interleave2(builder, src_type, src, msb, 0); *dst_hi = lp_build_interleave2(builder, src_type, src, msb, 1); - } - else { +#else *dst_lo = lp_build_interleave2(builder, src_type, msb, src, 0); *dst_hi = lp_build_interleave2(builder, src_type, msb, src, 1); - } +#endif /* Cast the result into the new type (twice as wide) */ @@ -261,13 +260,14 @@ lp_build_pack2(LLVMBuilderRef builder, #endif LLVMTypeRef dst_vec_type = lp_build_vec_type(dst_type); LLVMValueRef shuffle; - LLVMValueRef res; + LLVMValueRef res = NULL; assert(!src_type.floating); assert(!dst_type.floating); assert(src_type.width == dst_type.width * 2); assert(src_type.length * 2 == dst_type.length); + /* Check for special cases first */ if(util_cpu_caps.has_sse2 && src_type.width * src_type.length == 128) { switch(src_type.width) { case 32: @@ -283,8 +283,8 @@ lp_build_pack2(LLVMBuilderRef builder, return lp_build_intrinsic_binary(builder, "llvm.x86.sse41.packusdw", dst_vec_type, lo, hi); } else { - assert(0); - return LLVMGetUndef(dst_vec_type); + /* use generic shuffle below */ + res = NULL; } } break; @@ -310,10 +310,13 @@ lp_build_pack2(LLVMBuilderRef builder, break; } - res = LLVMBuildBitCast(builder, res, dst_vec_type, ""); - return res; + if (res) { + res = LLVMBuildBitCast(builder, res, dst_vec_type, ""); + return res; + } } + /* generic shuffle */ lo = LLVMBuildBitCast(builder, lo, dst_vec_type, ""); hi = LLVMBuildBitCast(builder, hi, dst_vec_type, ""); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_quad.c b/src/gallium/auxiliary/gallivm/lp_bld_quad.c index ca36046d222..7b1088939b9 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_quad.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_quad.c @@ -85,7 +85,7 @@ lp_build_scalar_ddx(struct lp_build_context *bld, LLVMValueRef idx_right = LLVMConstInt(LLVMInt32Type(), LP_BLD_QUAD_TOP_RIGHT, 0); LLVMValueRef a_left = LLVMBuildExtractElement(bld->builder, a, idx_left, ""); LLVMValueRef a_right = LLVMBuildExtractElement(bld->builder, a, idx_right, ""); - return LLVMBuildSub(bld->builder, a_right, a_left, ""); + return lp_build_sub(bld, a_right, a_left); } @@ -97,5 +97,5 @@ lp_build_scalar_ddy(struct lp_build_context *bld, LLVMValueRef idx_bottom = LLVMConstInt(LLVMInt32Type(), LP_BLD_QUAD_BOTTOM_LEFT, 0); LLVMValueRef a_top = LLVMBuildExtractElement(bld->builder, a, idx_top, ""); LLVMValueRef a_bottom = LLVMBuildExtractElement(bld->builder, a, idx_bottom, ""); - return LLVMBuildSub(bld->builder, a_bottom, a_top, ""); + return lp_build_sub(bld, a_bottom, a_top); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 1a20d74cac8..806c7d56a87 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -40,7 +40,6 @@ #include "util/u_memory.h" #include "util/u_math.h" #include "util/u_format.h" -#include "util/u_cpu_detect.h" #include "lp_bld_debug.h" #include "lp_bld_type.h" #include "lp_bld_const.h" @@ -811,7 +810,7 @@ lp_build_minify(struct lp_build_sample_context *bld, LLVMValueRef base_size, LLVMValueRef level) { - LLVMValueRef size = LLVMBuildAShr(bld->builder, base_size, level, "minify"); + LLVMValueRef size = LLVMBuildLShr(bld->builder, base_size, level, "minify"); size = lp_build_max(&bld->int_coord_bld, size, bld->int_coord_bld.one); return size; } @@ -888,17 +887,17 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, /* Compute rho = max of all partial derivatives scaled by texture size. * XXX this could be vectorized somewhat */ - rho = LLVMBuildMul(bld->builder, + rho = LLVMBuildFMul(bld->builder, lp_build_max(float_bld, dsdx, dsdy), lp_build_int_to_float(float_bld, width), ""); if (dims > 1) { LLVMValueRef max; - max = LLVMBuildMul(bld->builder, + max = LLVMBuildFMul(bld->builder, lp_build_max(float_bld, dtdx, dtdy), lp_build_int_to_float(float_bld, height), ""); rho = lp_build_max(float_bld, rho, max); if (dims > 2) { - max = LLVMBuildMul(bld->builder, + max = LLVMBuildFMul(bld->builder, lp_build_max(float_bld, drdx, drdy), lp_build_int_to_float(float_bld, depth), ""); rho = lp_build_max(float_bld, rho, max); @@ -912,12 +911,12 @@ lp_build_lod_selector(struct lp_build_sample_context *bld, if (lod_bias) { lod_bias = LLVMBuildExtractElement(bld->builder, lod_bias, index0, ""); - lod = LLVMBuildAdd(bld->builder, lod, lod_bias, "shader_lod_bias"); + lod = LLVMBuildFAdd(bld->builder, lod, lod_bias, "shader_lod_bias"); } } /* add sampler lod bias */ - lod = LLVMBuildAdd(bld->builder, lod, sampler_lod_bias, "sampler_lod_bias"); + lod = LLVMBuildFAdd(bld->builder, lod, sampler_lod_bias, "sampler_lod_bias"); /* clamp lod */ lod = lp_build_clamp(float_bld, lod, min_lod, max_lod); @@ -1219,8 +1218,7 @@ lp_build_cube_ima(struct lp_build_context *coord_bld, LLVMValueRef coord) /* ima = -0.5 / abs(coord); */ LLVMValueRef negHalf = lp_build_const_vec(coord_bld->type, -0.5); LLVMValueRef absCoord = lp_build_abs(coord_bld, coord); - LLVMValueRef ima = lp_build_mul(coord_bld, negHalf, - lp_build_rcp(coord_bld, absCoord)); + LLVMValueRef ima = lp_build_div(coord_bld, negHalf, absCoord); return ima; } @@ -1841,7 +1839,11 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld, unsigned i, j; for(j = 0; j < h16.type.length; j += 4) { - unsigned subindex = util_cpu_caps.little_endian ? 0 : 1; +#ifdef PIPE_ARCH_LITTLE_ENDIAN + unsigned subindex = 0; +#else + unsigned subindex = 1; +#endif LLVMValueRef index; index = LLVMConstInt(elem_type, j/2 + subindex, 0); @@ -2029,6 +2031,8 @@ lp_build_sample_soa(LLVMBuilderRef builder, debug_printf("Sample from %s\n", util_format_name(fmt)); } + assert(type.floating); + /* Setup our build context */ memset(&bld, 0, sizeof bld); bld.builder = builder; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 21236839fb7..0aa64affacc 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -489,7 +489,7 @@ get_indirect_offsets(struct lp_build_tgsi_soa_context *bld, int_vec_type, ""); /* addr_vec = addr_vec * 4 */ - addr_vec = lp_build_mul(&bld->base, addr_vec, vec4); + addr_vec = lp_build_mul(&bld->int_bld, addr_vec, vec4); return addr_vec; } @@ -533,7 +533,7 @@ emit_fetch( reg->Register.Index * 4 + swizzle); /* index_vec = index_vec + addr_vec */ - index_vec = lp_build_add(&bld->base, index_vec, addr_vec); + index_vec = lp_build_add(&bld->int_bld, index_vec, addr_vec); /* Gather values from the constant buffer */ res = build_gather(bld, bld->consts_ptr, index_vec); @@ -612,11 +612,9 @@ emit_fetch( case TGSI_UTIL_SIGN_SET: /* TODO: Use bitwese OR for floating point */ res = lp_build_abs( &bld->base, res ); - res = LLVMBuildNeg( bld->base.builder, res, "" ); - break; - + /* fall through */ case TGSI_UTIL_SIGN_TOGGLE: - res = LLVMBuildNeg( bld->base.builder, res, "" ); + res = lp_build_negate( &bld->base, res ); break; case TGSI_UTIL_SIGN_KEEP: @@ -773,7 +771,9 @@ emit_store( addr = LLVMBuildExtractElement(bld->base.builder, addr, LLVMConstInt(LLVMInt32Type(), 0, 0), ""); - addr = lp_build_mul(&bld->base, addr, LLVMConstInt(LLVMInt32Type(), 4, 0)); + addr = LLVMBuildMul(bld->base.builder, + addr, LLVMConstInt(LLVMInt32Type(), 4, 0), + ""); } switch( reg->Register.File ) { diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 5275faa5e22..298f3d0a8bb 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -557,6 +557,23 @@ print_temp(const struct tgsi_exec_machine *mach, uint index) #endif +void +tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach, + unsigned num_bufs, + const void **bufs, + const unsigned *buf_sizes) +{ + unsigned i; + + for (i = 0; i < num_bufs; i++) { + mach->Consts[i] = bufs[i]; + mach->ConstsSize[i] = buf_sizes[i]; + } +} + + + + /** * Check if there's a potential src/dst register data dependency when * using SOA execution. @@ -632,6 +649,10 @@ tgsi_exec_machine_bind_shader( util_init_math(); + if (numSamplers) { + assert(samplers); + } + mach->Tokens = tokens; mach->Samplers = samplers; @@ -1040,6 +1061,8 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, { uint i; + assert(swizzle < 4); + switch (file) { case TGSI_FILE_CONSTANT: for (i = 0; i < QUAD_SIZE; i++) { @@ -1049,9 +1072,23 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, if (index->i[i] < 0) { chan->u[i] = 0; } else { - const uint *p = (const uint *)mach->Consts[index2D->i[i]]; - - chan->u[i] = p[index->i[i] * 4 + swizzle]; + /* NOTE: copying the const value as a uint instead of float */ + const uint constbuf = index2D->i[i]; + const uint *buf = (const uint *)mach->Consts[constbuf]; + const int pos = index->i[i] * 4 + swizzle; + /* const buffer bounds check */ + if (pos < 0 || pos >= mach->ConstsSize[constbuf]) { + if (0) { + /* Debug: print warning */ + static int count = 0; + if (count++ < 100) + debug_printf("TGSI Exec: const buffer index %d" + " out of bounds\n", pos); + } + chan->u[i] = 0; + } + else + chan->u[i] = buf[pos]; } } break; @@ -1065,9 +1102,10 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i], index2D->i[i], index->i[i]); }*/ - chan->u[i] = mach->Inputs[index2D->i[i] * - TGSI_EXEC_MAX_INPUT_ATTRIBS + - index->i[i]].xyzw[swizzle].u[i]; + int pos = index2D->i[i] * TGSI_EXEC_MAX_INPUT_ATTRIBS + index->i[i]; + assert(pos >= 0); + assert(pos < Elements(mach->Inputs)); + chan->u[i] = mach->Inputs[pos].xyzw[swizzle].u[i]; } break; @@ -1187,7 +1225,7 @@ fetch_source(const struct tgsi_exec_machine *mach, index2.i[1] = index2.i[2] = index2.i[3] = reg->Indirect.Index; - + assert(reg->Indirect.File == TGSI_FILE_ADDRESS); /* get current value of address register[swizzle] */ swizzle = tgsi_util_get_src_register_swizzle( ®->Indirect, CHAN_X ); fetch_src_file_channel(mach, diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index ccf80ca6fd9..6dee362d589 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -253,7 +253,10 @@ struct tgsi_exec_machine struct tgsi_sampler **Samplers; unsigned ImmLimit; + const void *Consts[PIPE_MAX_CONSTANT_BUFFERS]; + unsigned ConstsSize[PIPE_MAX_CONSTANT_BUFFERS]; + const struct tgsi_token *Tokens; /**< Declarations, instructions */ unsigned Processor; /**< TGSI_PROCESSOR_x */ @@ -367,6 +370,13 @@ tgsi_set_exec_mask(struct tgsi_exec_machine *mach, } +extern void +tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach, + unsigned num_bufs, + const void **bufs, + const unsigned *buf_sizes); + + #if defined __cplusplus } /* extern "C" */ #endif diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c index 97148dbe233..acbff103efe 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c @@ -33,6 +33,10 @@ #include "tgsi_info.h" #include "tgsi_iterate.h" + +DEBUG_GET_ONCE_BOOL_OPTION(print_sanity, "TGSI_PRINT_SANITY", FALSE) + + typedef struct { uint file : 28; /* max 2 dimensions */ @@ -54,6 +58,8 @@ struct sanity_check_ctx uint errors; uint warnings; uint implied_array_size; + + boolean print; }; static INLINE unsigned @@ -148,6 +154,9 @@ report_error( { va_list args; + if (!ctx->print) + return; + debug_printf( "Error : " ); va_start( args, format ); _debug_vprintf( format, args ); @@ -164,6 +173,9 @@ report_warning( { va_list args; + if (!ctx->print) + return; + debug_printf( "Warning: " ); va_start( args, format ); _debug_vprintf( format, args ); @@ -539,6 +551,7 @@ tgsi_sanity_check( ctx.errors = 0; ctx.warnings = 0; ctx.implied_array_size = 0; + ctx.print = debug_get_option_print_sanity(); if (!tgsi_iterate_shader( tokens, &ctx.iter )) return FALSE; diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.h b/src/gallium/auxiliary/tgsi/tgsi_sanity.h index 52263ff8832..73f0f414e3f 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sanity.h +++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.h @@ -35,7 +35,8 @@ extern "C" { #endif /* Check the given token stream for errors and common mistakes. - * Diagnostic messages are printed out to the debug output. + * Diagnostic messages are printed out to the debug output, and is + * controlled by the debug option TGSI_PRINT_SANITY (default false). * Returns TRUE if there are no errors, even though there could be some warnings. */ boolean diff --git a/src/gallium/auxiliary/translate/translate.c b/src/gallium/auxiliary/translate/translate.c index a9b7253bf44..fe638e211fa 100644 --- a/src/gallium/auxiliary/translate/translate.c +++ b/src/gallium/auxiliary/translate/translate.c @@ -48,3 +48,8 @@ struct translate *translate_create( const struct translate_key *key ) return translate_generic_create( key ); } + +boolean translate_is_output_format_supported(enum pipe_format format) +{ + return translate_generic_is_output_format_supported(format); +} diff --git a/src/gallium/auxiliary/translate/translate.h b/src/gallium/auxiliary/translate/translate.h index edd95e07882..eb6f2cc4862 100644 --- a/src/gallium/auxiliary/translate/translate.h +++ b/src/gallium/auxiliary/translate/translate.h @@ -105,6 +105,8 @@ struct translate *translate_lookup_or_create( struct translate_context *tctx, struct translate *translate_create( const struct translate_key *key ); +boolean translate_is_output_format_supported(enum pipe_format format); + static INLINE int translate_keysize( const struct translate_key *key ) { return 2 * sizeof(int) + key->nr_elements * sizeof(struct translate_element); @@ -138,5 +140,6 @@ struct translate *translate_sse2_create( const struct translate_key *key ); struct translate *translate_generic_create( const struct translate_key *key ); +boolean translate_generic_is_output_format_supported(enum pipe_format format); #endif diff --git a/src/gallium/auxiliary/translate/translate_generic.c b/src/gallium/auxiliary/translate/translate_generic.c index 0e43a512ee8..42cfd763e9c 100644 --- a/src/gallium/auxiliary/translate/translate_generic.c +++ b/src/gallium/auxiliary/translate/translate_generic.c @@ -187,9 +187,15 @@ ATTRIB( R8G8B8_SNORM, 3, char, TO_8_SNORM ) ATTRIB( R8G8_SNORM, 2, char, TO_8_SNORM ) ATTRIB( R8_SNORM, 1, char, TO_8_SNORM ) -ATTRIB( A8R8G8B8_UNORM, 4, ubyte, TO_8_UNORM ) -/*ATTRIB( R8G8B8A8_UNORM, 4, ubyte, TO_8_UNORM )*/ - +static void +emit_A8R8G8B8_UNORM( const float *attrib, void *ptr) +{ + ubyte *out = (ubyte *)ptr; + out[0] = TO_8_UNORM(attrib[3]); + out[1] = TO_8_UNORM(attrib[0]); + out[2] = TO_8_UNORM(attrib[1]); + out[3] = TO_8_UNORM(attrib[2]); +} static void emit_B8G8R8A8_UNORM( const float *attrib, void *ptr) @@ -368,23 +374,23 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate, /* loop over vertex attributes (vertex shader inputs) */ for (i = 0; i < count; i++) { - unsigned elt = *elts++; + const unsigned elt = *elts++; for (attr = 0; attr < nr_attrs; attr++) { float data[4]; - const uint8_t *src; - unsigned index; - - char *dst = (vert + - tg->attrib[attr].output_offset); + char *dst = vert + tg->attrib[attr].output_offset; if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) { + const uint8_t *src; + unsigned index; + if (tg->attrib[attr].instance_divisor) { index = instance_id / tg->attrib[attr].instance_divisor; } else { index = elt; } + /* clamp to void going out of bounds */ index = MIN2(index, tg->attrib[attr].max_index); src = tg->attrib[attr].input_ptr + @@ -392,11 +398,23 @@ static void PIPE_CDECL generic_run_elts( struct translate *translate, tg->attrib[attr].fetch( data, src, 0, 0 ); + if (0) + debug_printf("Fetch elt attr %d from %p stride %d div %u max %u index %d: " + " %f, %f, %f, %f \n", + attr, + tg->attrib[attr].input_ptr, + tg->attrib[attr].input_stride, + tg->attrib[attr].instance_divisor, + tg->attrib[attr].max_index, + index, + data[0], data[1],data[2], data[3]); } else { data[0] = (float)instance_id; } - if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n", - i, elt, attr, data[0], data[1], data[2], data[3]); + + if (0) + debug_printf("vert %d/%d attr %d: %f %f %f %f\n", + i, elt, attr, data[0], data[1], data[2], data[3]); tg->attrib[attr].emit( data, dst ); } @@ -425,29 +443,42 @@ static void PIPE_CDECL generic_run( struct translate *translate, for (attr = 0; attr < nr_attrs; attr++) { float data[4]; - - char *dst = (vert + - tg->attrib[attr].output_offset); + char *dst = vert + tg->attrib[attr].output_offset; if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) { const uint8_t *src; + unsigned index; if (tg->attrib[attr].instance_divisor) { - src = tg->attrib[attr].input_ptr + - tg->attrib[attr].input_stride * - (instance_id / tg->attrib[attr].instance_divisor); - } else { - src = tg->attrib[attr].input_ptr + - tg->attrib[attr].input_stride * elt; + index = instance_id / tg->attrib[attr].instance_divisor; } + else { + index = elt; + } + + /* clamp to void going out of bounds */ + index = MIN2(index, tg->attrib[attr].max_index); + + src = tg->attrib[attr].input_ptr + + tg->attrib[attr].input_stride * index; tg->attrib[attr].fetch( data, src, 0, 0 ); + + if (0) + debug_printf("Fetch linear attr %d from %p stride %d index %d: " + " %f, %f, %f, %f \n", + attr, + tg->attrib[attr].input_ptr, + tg->attrib[attr].input_stride, + index, + data[0], data[1],data[2], data[3]); } else { data[0] = (float)instance_id; } - if (0) debug_printf("vert %d attr %d: %f %f %f %f\n", - i, attr, data[0], data[1], data[2], data[3]); + if (0) + debug_printf("vert %d attr %d: %f %f %f %f\n", + i, attr, data[0], data[1], data[2], data[3]); tg->attrib[attr].emit( data, dst ); } @@ -523,3 +554,83 @@ struct translate *translate_generic_create( const struct translate_key *key ) return &tg->translate; } + +boolean translate_generic_is_output_format_supported(enum pipe_format format) +{ + switch(format) + { + case PIPE_FORMAT_R64G64B64A64_FLOAT: return TRUE; + case PIPE_FORMAT_R64G64B64_FLOAT: return TRUE; + case PIPE_FORMAT_R64G64_FLOAT: return TRUE; + case PIPE_FORMAT_R64_FLOAT: return TRUE; + + case PIPE_FORMAT_R32G32B32A32_FLOAT: return TRUE; + case PIPE_FORMAT_R32G32B32_FLOAT: return TRUE; + case PIPE_FORMAT_R32G32_FLOAT: return TRUE; + case PIPE_FORMAT_R32_FLOAT: return TRUE; + + case PIPE_FORMAT_R32G32B32A32_USCALED: return TRUE; + case PIPE_FORMAT_R32G32B32_USCALED: return TRUE; + case PIPE_FORMAT_R32G32_USCALED: return TRUE; + case PIPE_FORMAT_R32_USCALED: return TRUE; + + case PIPE_FORMAT_R32G32B32A32_SSCALED: return TRUE; + case PIPE_FORMAT_R32G32B32_SSCALED: return TRUE; + case PIPE_FORMAT_R32G32_SSCALED: return TRUE; + case PIPE_FORMAT_R32_SSCALED: return TRUE; + + case PIPE_FORMAT_R32G32B32A32_UNORM: return TRUE; + case PIPE_FORMAT_R32G32B32_UNORM: return TRUE; + case PIPE_FORMAT_R32G32_UNORM: return TRUE; + case PIPE_FORMAT_R32_UNORM: return TRUE; + + case PIPE_FORMAT_R32G32B32A32_SNORM: return TRUE; + case PIPE_FORMAT_R32G32B32_SNORM: return TRUE; + case PIPE_FORMAT_R32G32_SNORM: return TRUE; + case PIPE_FORMAT_R32_SNORM: return TRUE; + + case PIPE_FORMAT_R16G16B16A16_USCALED: return TRUE; + case PIPE_FORMAT_R16G16B16_USCALED: return TRUE; + case PIPE_FORMAT_R16G16_USCALED: return TRUE; + case PIPE_FORMAT_R16_USCALED: return TRUE; + + case PIPE_FORMAT_R16G16B16A16_SSCALED: return TRUE; + case PIPE_FORMAT_R16G16B16_SSCALED: return TRUE; + case PIPE_FORMAT_R16G16_SSCALED: return TRUE; + case PIPE_FORMAT_R16_SSCALED: return TRUE; + + case PIPE_FORMAT_R16G16B16A16_UNORM: return TRUE; + case PIPE_FORMAT_R16G16B16_UNORM: return TRUE; + case PIPE_FORMAT_R16G16_UNORM: return TRUE; + case PIPE_FORMAT_R16_UNORM: return TRUE; + + case PIPE_FORMAT_R16G16B16A16_SNORM: return TRUE; + case PIPE_FORMAT_R16G16B16_SNORM: return TRUE; + case PIPE_FORMAT_R16G16_SNORM: return TRUE; + case PIPE_FORMAT_R16_SNORM: return TRUE; + + case PIPE_FORMAT_R8G8B8A8_USCALED: return TRUE; + case PIPE_FORMAT_R8G8B8_USCALED: return TRUE; + case PIPE_FORMAT_R8G8_USCALED: return TRUE; + case PIPE_FORMAT_R8_USCALED: return TRUE; + + case PIPE_FORMAT_R8G8B8A8_SSCALED: return TRUE; + case PIPE_FORMAT_R8G8B8_SSCALED: return TRUE; + case PIPE_FORMAT_R8G8_SSCALED: return TRUE; + case PIPE_FORMAT_R8_SSCALED: return TRUE; + + case PIPE_FORMAT_R8G8B8A8_UNORM: return TRUE; + case PIPE_FORMAT_R8G8B8_UNORM: return TRUE; + case PIPE_FORMAT_R8G8_UNORM: return TRUE; + case PIPE_FORMAT_R8_UNORM: return TRUE; + + case PIPE_FORMAT_R8G8B8A8_SNORM: return TRUE; + case PIPE_FORMAT_R8G8B8_SNORM: return TRUE; + case PIPE_FORMAT_R8G8_SNORM: return TRUE; + case PIPE_FORMAT_R8_SNORM: return TRUE; + + case PIPE_FORMAT_A8R8G8B8_UNORM: return TRUE; + case PIPE_FORMAT_B8G8R8A8_UNORM: return TRUE; + default: return FALSE; + } +} diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 0d94aaae956..b5b86b72142 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -87,6 +87,7 @@ struct blitter_context_priv void *dsa_write_depth_keep_stencil; void *dsa_keep_depth_stencil; void *dsa_keep_depth_write_stencil; + void *dsa_flush_depth_stencil; void *velem_state; @@ -156,6 +157,10 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) ctx->dsa_keep_depth_stencil = pipe->create_depth_stencil_alpha_state(pipe, &dsa); + dsa.depth.writemask = 1; + ctx->dsa_flush_depth_stencil = + pipe->create_depth_stencil_alpha_state(pipe, &dsa); + dsa.depth.enabled = 1; dsa.depth.writemask = 1; dsa.depth.func = PIPE_FUNC_ALWAYS; @@ -940,3 +945,42 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter, UTIL_BLITTER_ATTRIB_NONE, NULL); blitter_restore_CSOs(ctx); } + +/* Clear a region of a depth stencil surface. */ +void util_blitter_flush_depth_stencil(struct blitter_context *blitter, + struct pipe_surface *dstsurf) +{ + struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; + struct pipe_context *pipe = ctx->base.pipe; + struct pipe_framebuffer_state fb_state; + + assert(dstsurf->texture); + if (!dstsurf->texture) + return; + + /* check the saved state */ + blitter_check_saved_CSOs(ctx); + assert(blitter->saved_fb_state.nr_cbufs != ~0); + + /* bind CSOs */ + pipe->bind_blend_state(pipe, ctx->blend_keep_color); + pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_flush_depth_stencil); + + pipe->bind_rasterizer_state(pipe, ctx->rs_state); + pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0)); + pipe->bind_vs_state(pipe, ctx->vs_col); + pipe->bind_vertex_elements_state(pipe, ctx->velem_state); + + /* set a framebuffer state */ + fb_state.width = dstsurf->width; + fb_state.height = dstsurf->height; + fb_state.nr_cbufs = 0; + fb_state.cbufs[0] = 0; + fb_state.zsbuf = dstsurf; + pipe->set_framebuffer_state(pipe, &fb_state); + + blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); + blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height, 0, + UTIL_BLITTER_ATTRIB_NONE, NULL); + blitter_restore_CSOs(ctx); +} diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index ba3f92eca85..f316587dea0 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -200,6 +200,8 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter, unsigned dstx, unsigned dsty, unsigned width, unsigned height); +void util_blitter_flush_depth_stencil(struct blitter_context *blitter, + struct pipe_surface *dstsurf); /* The functions below should be used to save currently bound constant state * objects inside a driver. The objects are automatically restored at the end * of the util_blitter_{clear, copy_region, fill_region} functions and then diff --git a/src/gallium/auxiliary/util/u_cpu_detect.c b/src/gallium/auxiliary/util/u_cpu_detect.c index a08241971ca..50563513072 100644 --- a/src/gallium/auxiliary/util/u_cpu_detect.c +++ b/src/gallium/auxiliary/util/u_cpu_detect.c @@ -38,7 +38,7 @@ #include "u_cpu_detect.h" #if defined(PIPE_ARCH_PPC) -#if defined(PIPE_OS_DARWIN) +#if defined(PIPE_OS_APPLE) #include <sys/sysctl.h> #else #include <signal.h> @@ -73,9 +73,15 @@ #endif +DEBUG_GET_ONCE_BOOL_OPTION(dump_cpu, "GALLIUM_DUMP_CPU", FALSE) + + struct util_cpu_caps util_cpu_caps; +#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) static int has_cpuid(void); +#endif + #if defined(PIPE_ARCH_X86) @@ -132,7 +138,7 @@ win32_sig_handler_sse(EXCEPTION_POINTERS* ep) #endif /* PIPE_ARCH_X86 */ -#if defined(PIPE_ARCH_PPC) && !defined(PIPE_OS_DARWIN) +#if defined(PIPE_ARCH_PPC) && !defined(PIPE_OS_APPLE) static jmp_buf __lv_powerpc_jmpbuf; static volatile sig_atomic_t __lv_powerpc_canjump = 0; @@ -153,7 +159,7 @@ sigill_handler(int sig) static void check_os_altivec_support(void) { -#if defined(PIPE_OS_DARWIN) +#if defined(PIPE_OS_APPLE) int sels[2] = {CTL_HW, HW_VECTORUNIT}; int has_vu = 0; int len = sizeof (has_vu); @@ -166,8 +172,8 @@ check_os_altivec_support(void) util_cpu_caps.has_altivec = 1; } } -#else /* !PIPE_OS_DARWIN */ - /* no Darwin, do it the brute-force way */ +#else /* !PIPE_OS_APPLE */ + /* not on Apple/Darwin, do it the brute-force way */ /* this is borrowed from the libmpeg2 library */ signal(SIGILL, sigill_handler); if (setjmp(__lv_powerpc_jmpbuf)) { @@ -184,7 +190,7 @@ check_os_altivec_support(void) signal(SIGILL, SIG_DFL); util_cpu_caps.has_altivec = 1; } -#endif /* PIPE_OS_DARWIN */ +#endif /* !PIPE_OS_APPLE */ } #endif /* PIPE_ARCH_PPC */ @@ -385,23 +391,6 @@ util_cpu_detect(void) memset(&util_cpu_caps, 0, sizeof util_cpu_caps); - /* Check for arch type */ -#if defined(PIPE_ARCH_MIPS) - util_cpu_caps.arch = UTIL_CPU_ARCH_MIPS; -#elif defined(PIPE_ARCH_ALPHA) - util_cpu_caps.arch = UTIL_CPU_ARCH_ALPHA; -#elif defined(PIPE_ARCH_SPARC) - util_cpu_caps.arch = UTIL_CPU_ARCH_SPARC; -#elif defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) - util_cpu_caps.arch = UTIL_CPU_ARCH_X86; - util_cpu_caps.little_endian = 1; -#elif defined(PIPE_ARCH_PPC) - util_cpu_caps.arch = UTIL_CPU_ARCH_POWERPC; - util_cpu_caps.little_endian = 0; -#else - util_cpu_caps.arch = UTIL_CPU_ARCH_UNKNOWN; -#endif - /* Count the number of CPUs in system */ #if defined(PIPE_OS_WINDOWS) { @@ -497,23 +486,24 @@ util_cpu_detect(void) #endif /* PIPE_ARCH_PPC */ #ifdef DEBUG - debug_printf("util_cpu_caps.arch = %i\n", util_cpu_caps.arch); - debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus); - - debug_printf("util_cpu_caps.x86_cpu_type = %u\n", util_cpu_caps.x86_cpu_type); - debug_printf("util_cpu_caps.cacheline = %u\n", util_cpu_caps.cacheline); - - debug_printf("util_cpu_caps.has_tsc = %u\n", util_cpu_caps.has_tsc); - debug_printf("util_cpu_caps.has_mmx = %u\n", util_cpu_caps.has_mmx); - debug_printf("util_cpu_caps.has_mmx2 = %u\n", util_cpu_caps.has_mmx2); - debug_printf("util_cpu_caps.has_sse = %u\n", util_cpu_caps.has_sse); - debug_printf("util_cpu_caps.has_sse2 = %u\n", util_cpu_caps.has_sse2); - debug_printf("util_cpu_caps.has_sse3 = %u\n", util_cpu_caps.has_sse3); - debug_printf("util_cpu_caps.has_ssse3 = %u\n", util_cpu_caps.has_ssse3); - debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1); - debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow); - debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext); - debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec); + if (debug_get_option_dump_cpu()) { + debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus); + + debug_printf("util_cpu_caps.x86_cpu_type = %u\n", util_cpu_caps.x86_cpu_type); + debug_printf("util_cpu_caps.cacheline = %u\n", util_cpu_caps.cacheline); + + debug_printf("util_cpu_caps.has_tsc = %u\n", util_cpu_caps.has_tsc); + debug_printf("util_cpu_caps.has_mmx = %u\n", util_cpu_caps.has_mmx); + debug_printf("util_cpu_caps.has_mmx2 = %u\n", util_cpu_caps.has_mmx2); + debug_printf("util_cpu_caps.has_sse = %u\n", util_cpu_caps.has_sse); + debug_printf("util_cpu_caps.has_sse2 = %u\n", util_cpu_caps.has_sse2); + debug_printf("util_cpu_caps.has_sse3 = %u\n", util_cpu_caps.has_sse3); + debug_printf("util_cpu_caps.has_ssse3 = %u\n", util_cpu_caps.has_ssse3); + debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1); + debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow); + debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext); + debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec); + } #endif util_cpu_detect_initialized = TRUE; diff --git a/src/gallium/auxiliary/util/u_cpu_detect.h b/src/gallium/auxiliary/util/u_cpu_detect.h index 4b3dc39c342..f3bef0993c7 100644 --- a/src/gallium/auxiliary/util/u_cpu_detect.h +++ b/src/gallium/auxiliary/util/u_cpu_detect.h @@ -36,26 +36,15 @@ #define _UTIL_CPU_DETECT_H #include "pipe/p_compiler.h" - -enum util_cpu_arch { - UTIL_CPU_ARCH_UNKNOWN = 0, - UTIL_CPU_ARCH_MIPS, - UTIL_CPU_ARCH_ALPHA, - UTIL_CPU_ARCH_SPARC, - UTIL_CPU_ARCH_X86, - UTIL_CPU_ARCH_POWERPC -}; +#include "pipe/p_config.h" struct util_cpu_caps { - enum util_cpu_arch arch; unsigned nr_cpus; /* Feature flags */ int x86_cpu_type; unsigned cacheline; - unsigned little_endian:1; - unsigned has_tsc:1; unsigned has_mmx:1; unsigned has_mmx2:1; diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index ad162558bc1..504e6d2a18f 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -88,7 +88,7 @@ debug_get_option_should_print(void) * but its cool since we set first to false */ first = FALSE; - value = debug_get_bool_option("GALLIUM_PRINT_OPTIONS", TRUE); + value = debug_get_bool_option("GALLIUM_PRINT_OPTIONS", FALSE); /* XXX should we print this option? Currently it wont */ return value; } diff --git a/src/gallium/auxiliary/util/u_draw.h b/src/gallium/auxiliary/util/u_draw.h new file mode 100644 index 00000000000..2a91ea0f9ae --- /dev/null +++ b/src/gallium/auxiliary/util/u_draw.h @@ -0,0 +1,138 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef U_DRAW_H +#define U_DRAW_H + + +#include "pipe/p_compiler.h" +#include "pipe/p_context.h" + + +static INLINE void +util_draw_init_info(struct pipe_draw_info *info) +{ + memset(info, 0, sizeof(*info)); + info->instance_count = 1; + info->max_index = 0xffffffff; +} + + +static INLINE void +util_draw_arrays(struct pipe_context *pipe, uint mode, uint start, uint count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.mode = mode; + info.start = start; + info.count = count; + info.min_index = start; + info.max_index = start + count - 1; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_elements(struct pipe_context *pipe, int index_bias, + uint mode, uint start, uint count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.indexed = TRUE; + info.mode = mode; + info.start = start; + info.count = count; + info.index_bias = index_bias; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_arrays_instanced(struct pipe_context *pipe, + uint mode, uint start, uint count, + uint start_instance, + uint instance_count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.mode = mode; + info.start = start; + info.count = count; + info.start_instance = start_instance; + info.instance_count = instance_count; + info.min_index = start; + info.max_index = start + count - 1; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_elements_instanced(struct pipe_context *pipe, + int index_bias, + uint mode, uint start, uint count, + uint start_instance, + uint instance_count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.indexed = TRUE; + info.mode = mode; + info.start = start; + info.count = count; + info.index_bias = index_bias; + info.start_instance = start_instance; + info.instance_count = instance_count; + + pipe->draw_vbo(pipe, &info); +} + +static INLINE void +util_draw_range_elements(struct pipe_context *pipe, + int index_bias, + uint min_index, + uint max_index, + uint mode, uint start, uint count) +{ + struct pipe_draw_info info; + + util_draw_init_info(&info); + info.indexed = TRUE; + info.mode = mode; + info.start = start; + info.count = count; + info.index_bias = index_bias; + info.min_index = min_index; + info.max_index = max_index; + + pipe->draw_vbo(pipe, &info); +} + +#endif diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index b37b48b5aef..0b6dc5880f3 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -60,7 +60,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe, /* note: vertex elements already set by caller */ /* draw */ - pipe->draw_arrays(pipe, prim_type, 0, num_verts); + util_draw_arrays(pipe, prim_type, 0, num_verts); } diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h index 42eb1844289..52994fe05c3 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.h +++ b/src/gallium/auxiliary/util/u_draw_quad.h @@ -29,12 +29,18 @@ #define U_DRAWQUAD_H +#include "pipe/p_compiler.h" +#include "pipe/p_context.h" + + #ifdef __cplusplus extern "C" { #endif struct pipe_resource; +#include "util/u_draw.h" + extern void util_draw_vertex_buffer(struct pipe_context *pipe, struct pipe_resource *vbuf, uint offset, diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index 38254b1096d..8e786a390a0 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -631,6 +631,44 @@ util_format_has_alpha(enum pipe_format format) } /** + * Return the matching SRGB format, or PIPE_FORMAT_NONE if none. + */ +static INLINE enum pipe_format +util_format_srgb(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_L8_UNORM: + return PIPE_FORMAT_L8_SRGB; + case PIPE_FORMAT_L8A8_UNORM: + return PIPE_FORMAT_L8A8_SRGB; + case PIPE_FORMAT_R8G8B8_UNORM: + return PIPE_FORMAT_R8G8B8_SRGB; + case PIPE_FORMAT_A8B8G8R8_UNORM: + return PIPE_FORMAT_A8B8G8R8_SRGB; + case PIPE_FORMAT_X8B8G8R8_UNORM: + return PIPE_FORMAT_X8B8G8R8_SRGB; + case PIPE_FORMAT_B8G8R8A8_UNORM: + return PIPE_FORMAT_B8G8R8A8_SRGB; + case PIPE_FORMAT_B8G8R8X8_UNORM: + return PIPE_FORMAT_B8G8R8X8_SRGB; + case PIPE_FORMAT_A8R8G8B8_UNORM: + return PIPE_FORMAT_A8R8G8B8_SRGB; + case PIPE_FORMAT_X8R8G8B8_UNORM: + return PIPE_FORMAT_X8R8G8B8_SRGB; + case PIPE_FORMAT_DXT1_RGB: + return PIPE_FORMAT_DXT1_SRGB; + case PIPE_FORMAT_DXT1_RGBA: + return PIPE_FORMAT_DXT1_SRGBA; + case PIPE_FORMAT_DXT3_RGBA: + return PIPE_FORMAT_DXT3_SRGBA; + case PIPE_FORMAT_DXT5_RGBA: + return PIPE_FORMAT_DXT5_SRGBA; + default: + return PIPE_FORMAT_NONE; + } +} + +/** * Return the number of components stored. * Formats with block size != 1x1 will always have 1 component (the block). */ diff --git a/src/gallium/auxiliary/util/u_format_other.c b/src/gallium/auxiliary/util/u_format_other.c index 723fa8c3bf9..fa42ec37138 100644 --- a/src/gallium/auxiliary/util/u_format_other.c +++ b/src/gallium/auxiliary/util/u_format_other.c @@ -121,6 +121,15 @@ util_format_r1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, * A.k.a. D3DFMT_CxV8U8 */ +static uint8_t +r8g8bx_derive(int16_t r, int16_t g) +{ + /* Derive blue from red and green components. + * Apparently, we must always use integers to perform calculations, + * otherwise the results won't match D3D's CxV8U8 definition. + */ + return (uint8_t)sqrtf(0x7f * 0x7f - r * r - g * g) * 0xff / 0x7f; +} void util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, @@ -145,7 +154,7 @@ util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, dst[0] = (float)(r * (1.0f/0x7f)); /* r */ dst[1] = (float)(g * (1.0f/0x7f)); /* g */ - dst[2] = sqrtf(1.0f - dst[0] * dst[0] - dst[1] * dst[1]); /* b */ + dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ dst[3] = 1.0f; /* a */ dst += 4; } @@ -177,7 +186,7 @@ util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_strid dst[0] = (uint8_t)(((uint16_t)MAX2(r, 0)) * 0xff / 0x7f); /* r */ dst[1] = (uint8_t)(((uint16_t)MAX2(g, 0)) * 0xff / 0x7f); /* g */ - dst[2] = (uint8_t)sqrtf(0x7f*0x7f - r * r - g * g) * 0xff / 0x7f; /* b */ + dst[2] = r8g8bx_derive(r, g); /* b */ dst[3] = 255; /* a */ dst += 4; } @@ -262,6 +271,6 @@ util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src, dst[0] = r * (1.0f/0x7f); /* r */ dst[1] = g * (1.0f/0x7f); /* g */ - dst[2] = sqrtf(1.0f - dst[0] * dst[0] - dst[1] * dst[1]); /* b */ + dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ dst[3] = 1.0f; /* a */ } diff --git a/src/gallium/auxiliary/util/u_framebuffer.c b/src/gallium/auxiliary/util/u_framebuffer.c index 768ae9ceb5d..7803ec6a8b5 100644 --- a/src/gallium/auxiliary/util/u_framebuffer.c +++ b/src/gallium/auxiliary/util/u_framebuffer.c @@ -85,9 +85,11 @@ util_copy_framebuffer_state(struct pipe_framebuffer_state *dst, dst->width = src->width; dst->height = src->height; - for (i = 0; i < Elements(src->cbufs); i++) { + for (i = 0; i < src->nr_cbufs; i++) pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]); - } + + for (i = src->nr_cbufs; i < dst->nr_cbufs; i++) + pipe_surface_reference(&dst->cbufs[i], NULL); dst->nr_cbufs = src->nr_cbufs; diff --git a/src/gallium/auxiliary/util/u_mempool.c b/src/gallium/auxiliary/util/u_mempool.c index 84e2a34acc6..1f336b39a1a 100644 --- a/src/gallium/auxiliary/util/u_mempool.c +++ b/src/gallium/auxiliary/util/u_mempool.c @@ -126,7 +126,6 @@ void util_mempool_set_thread_safety(struct util_mempool *pool, pool->threading = threading; if (threading) { - pipe_mutex_init(pool->mutex); pool->malloc = util_mempool_malloc_mt; pool->free = util_mempool_free_mt; } else { @@ -152,6 +151,8 @@ void util_mempool_create(struct util_mempool *pool, make_empty_list(&pool->list); + pipe_mutex_init(pool->mutex); + util_mempool_set_thread_safety(pool, threading); } @@ -164,6 +165,5 @@ void util_mempool_destroy(struct util_mempool *pool) FREE(page); } - if (pool->threading) - pipe_mutex_destroy(pool->mutex); + pipe_mutex_destroy(pool->mutex); } diff --git a/src/gallium/auxiliary/util/u_network.c b/src/gallium/auxiliary/util/u_network.c index 87ee0e47685..77f2c5fc7de 100644 --- a/src/gallium/auxiliary/util/u_network.c +++ b/src/gallium/auxiliary/util/u_network.c @@ -6,7 +6,7 @@ #if defined(PIPE_SUBSYSTEM_WINDOWS_USER) # include <winsock2.h> # include <windows.h> -#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE) +#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_CYGWIN) # include <sys/socket.h> # include <netinet/in.h> # include <unistd.h> diff --git a/src/gallium/auxiliary/util/u_pack_color.h b/src/gallium/auxiliary/util/u_pack_color.h index 3ebef9fb749..5f113f742b1 100644 --- a/src/gallium/auxiliary/util/u_pack_color.h +++ b/src/gallium/auxiliary/util/u_pack_color.h @@ -425,6 +425,53 @@ util_pack_color(const float rgba[4], enum pipe_format format, union util_color * } } +/* Integer versions of util_pack_z and util_pack_z_stencil - useful for + * constructing clear masks. + */ +static INLINE uint +util_pack_uint_z(enum pipe_format format, unsigned z) +{ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + return z & 0xffff; + case PIPE_FORMAT_Z32_UNORM: + case PIPE_FORMAT_Z32_FLOAT: + return z; + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + case PIPE_FORMAT_Z24X8_UNORM: + return z & 0xffffff; + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + return (z & 0xffffff) << 8; + case PIPE_FORMAT_S8_USCALED: + return 0; + default: + debug_print_format("gallium: unhandled format in util_pack_z()", format); + assert(0); + return 0; + } +} + +static INLINE uint +util_pack_uint_z_stencil(enum pipe_format format, double z, uint s) +{ + unsigned packed = util_pack_uint_z(format, z); + + s &= 0xff; + + switch (format) { + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + return packed | (s << 24); + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + return packed | s; + case PIPE_FORMAT_S8_USCALED: + return packed | s; + default: + return packed; + } +} + + /** * Note: it's assumed that z is in [0,1] diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h index 606b9b5c6b9..3c851f73401 100644 --- a/src/gallium/auxiliary/util/u_prim.h +++ b/src/gallium/auxiliary/util/u_prim.h @@ -108,6 +108,20 @@ static INLINE boolean u_trim_pipe_prim( unsigned pipe_prim, unsigned *nr ) ok = (*nr >= 4); *nr -= (*nr % 2); break; + case PIPE_PRIM_LINES_ADJACENCY: + ok = (*nr >= 4); + *nr -= (*nr % 4); + break; + case PIPE_PRIM_LINE_STRIP_ADJACENCY: + ok = (*nr >= 4); + break; + case PIPE_PRIM_TRIANGLES_ADJACENCY: + ok = (*nr >= 6); + *nr -= (*nr % 5); + break; + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: + ok = (*nr >= 4); + break; default: ok = 0; break; diff --git a/src/gallium/auxiliary/util/u_split_prim.h b/src/gallium/auxiliary/util/u_split_prim.h new file mode 100644 index 00000000000..206e1ec3118 --- /dev/null +++ b/src/gallium/auxiliary/util/u_split_prim.h @@ -0,0 +1,105 @@ +/* Originally written by Ben Skeggs for the nv50 driver*/ +#include <pipe/p_defines.h> + +struct util_split_prim { + void *priv; + void (*emit)(void *priv, unsigned start, unsigned count); + void (*edge)(void *priv, boolean enabled); + + unsigned mode; + unsigned start; + unsigned p_start; + unsigned p_end; + + uint repeat_first:1; + uint close_first:1; + uint edgeflag_off:1; +}; + +static INLINE void +util_split_prim_init(struct util_split_prim *s, + unsigned mode, unsigned start, unsigned count) +{ + if (mode == PIPE_PRIM_LINE_LOOP) { + s->mode = PIPE_PRIM_LINE_STRIP; + s->close_first = 1; + } else { + s->mode = mode; + s->close_first = 0; + } + s->start = start; + s->p_start = start; + s->p_end = start + count; + s->edgeflag_off = 0; + s->repeat_first = 0; +} + +static INLINE boolean +util_split_prim_next(struct util_split_prim *s, unsigned max_verts) +{ + int repeat = 0; + + if (s->repeat_first) { + s->emit(s->priv, s->start, 1); + max_verts--; + if (s->edgeflag_off) { + s->edge(s->priv, TRUE); + s->edgeflag_off = FALSE; + } + } + + if (s->p_start + s->close_first + max_verts >= s->p_end) { + s->emit(s->priv, s->p_start, s->p_end - s->p_start); + if (s->close_first) + s->emit(s->priv, s->start, 1); + return TRUE; + } + + switch (s->mode) { + case PIPE_PRIM_LINES: + max_verts &= ~1; + break; + case PIPE_PRIM_LINE_STRIP: + repeat = 1; + break; + case PIPE_PRIM_POLYGON: + max_verts--; + s->emit(s->priv, s->p_start, max_verts); + s->edge(s->priv, FALSE); + s->emit(s->priv, s->p_start + max_verts, 1); + s->p_start += max_verts; + s->repeat_first = TRUE; + s->edgeflag_off = TRUE; + return FALSE; + case PIPE_PRIM_TRIANGLES: + max_verts = max_verts - (max_verts % 3); + break; + case PIPE_PRIM_TRIANGLE_STRIP: + /* to ensure winding stays correct, always split + * on an even number of generated triangles + */ + max_verts = max_verts & ~1; + repeat = 2; + break; + case PIPE_PRIM_TRIANGLE_FAN: + s->repeat_first = TRUE; + repeat = 1; + break; + case PIPE_PRIM_QUADS: + max_verts &= ~3; + break; + case PIPE_PRIM_QUAD_STRIP: + max_verts &= ~1; + repeat = 2; + break; + case PIPE_PRIM_POINTS: + break; + default: + /* TODO: implement adjacency primitives */ + assert(0); + } + + s->emit (s->priv, s->p_start, max_verts); + s->p_start += (max_verts - repeat); + return FALSE; +} diff --git a/src/gallium/auxiliary/util/u_sse.h b/src/gallium/auxiliary/util/u_sse.h index e2a8491e62c..87959ab0aab 100644 --- a/src/gallium/auxiliary/util/u_sse.h +++ b/src/gallium/auxiliary/util/u_sse.h @@ -41,7 +41,6 @@ #if defined(PIPE_ARCH_SSE) -#include <xmmintrin.h> #include <emmintrin.h> @@ -72,6 +71,35 @@ _mm_castps_si128(__m128 a) #endif /* defined(_MSC_VER) && _MSC_VER < 1500 */ + +#if defined(PIPE_ARCH_SSSE3) + +#include <tmmintrin.h> + +#else /* !PIPE_ARCH_SSSE3 */ + +#include <emmintrin.h> + +/** + * Describe _mm_shuffle_epi8() with gcc extended inline assembly, for cases + * where -mssse3 is not supported/enabled. + * + * MSVC will never get in here as its intrinsics support do not rely on + * compiler command line options. + */ +static __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_shuffle_epi8(__m128i a, __m128i mask) +{ + __m128i result; + __asm__("pshufb %1, %0" + : "=x" (result) + : "xm" (mask), "0" (a)); + return result; +} + +#endif /* !PIPE_ARCH_SSSE3 */ + + #endif /* PIPE_ARCH_X86 || PIPE_ARCH_X86_64 */ #endif /* U_SSE_H_ */ diff --git a/src/gallium/auxiliary/util/u_staging.c b/src/gallium/auxiliary/util/u_staging.c new file mode 100644 index 00000000000..607c31f5ee7 --- /dev/null +++ b/src/gallium/auxiliary/util/u_staging.c @@ -0,0 +1,95 @@ +#include "util/u_staging.h" +#include "pipe/p_context.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" + +static void +util_staging_resource_template(struct pipe_resource *pt, unsigned width, unsigned height, unsigned depth, struct pipe_resource *template) +{ + memset(template, 0, sizeof(struct pipe_resource)); + if(pt->target != PIPE_BUFFER && depth <= 1) + template->target = PIPE_TEXTURE_2D; + else + template->target = pt->target; + template->format = pt->format; + template->width0 = width; + template->height0 = height; + template->depth0 = depth; + template->last_level = 0; + template->nr_samples = pt->nr_samples; + template->bind = 0; + template->usage = PIPE_USAGE_STAGING; + template->flags = 0; +} + +struct util_staging_transfer * +util_staging_transfer_new(struct pipe_context *pipe, + struct pipe_resource *pt, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box, + bool direct) +{ + struct pipe_screen *pscreen = pipe->screen; + struct util_staging_transfer *tx; + struct pipe_resource staging_resource_template; + + tx = CALLOC_STRUCT(util_staging_transfer); + if (!tx) + return NULL; + + pipe_resource_reference(&tx->base.resource, pt); + tx->base.sr = sr; + tx->base.usage = usage; + tx->base.box = *box; + + if (direct) + { + tx->staging_resource = pt; + return tx; + } + + util_staging_resource_template(pt, box->width, box->height, box->depth, &staging_resource_template); + tx->staging_resource = pscreen->resource_create(pscreen, &staging_resource_template); + if (!tx->staging_resource) + { + pipe_resource_reference(&tx->base.resource, NULL); + FREE(tx); + return NULL; + } + + if (usage & PIPE_TRANSFER_READ) + { + struct pipe_subresource dstsr; + unsigned zi; + dstsr.face = 0; + dstsr.level = 0; + for(zi = 0; zi < box->depth; ++zi) + pipe->resource_copy_region(pipe, tx->staging_resource, dstsr, 0, 0, 0, tx->base.resource, sr, box->x, box->y, box->z + zi, box->width, box->height); + } + + return tx; +} + +void +util_staging_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *ptx) +{ + struct util_staging_transfer *tx = (struct util_staging_transfer *)ptx; + + if (tx->staging_resource != tx->base.resource) + { + if(tx->base.usage & PIPE_TRANSFER_WRITE) { + struct pipe_subresource srcsr; + unsigned zi; + srcsr.face = 0; + srcsr.level = 0; + for(zi = 0; zi < tx->base.box.depth; ++zi) + pipe->resource_copy_region(pipe, tx->base.resource, tx->base.sr, tx->base.box.x, tx->base.box.y, tx->base.box.z + zi, tx->staging_resource, srcsr, 0, 0, 0, tx->base.box.width, tx->base.box.height); + } + + pipe_resource_reference(&tx->staging_resource, NULL); + } + + pipe_resource_reference(&ptx->resource, NULL); + FREE(ptx); +} diff --git a/src/gallium/auxiliary/util/u_staging.h b/src/gallium/auxiliary/util/u_staging.h new file mode 100644 index 00000000000..602faa2971d --- /dev/null +++ b/src/gallium/auxiliary/util/u_staging.h @@ -0,0 +1,37 @@ +/* Direct3D 10/11 has no concept of transfers. Applications instead + * create resources with a STAGING or DYNAMIC usage, copy between them + * and the real resource and use Map to map the STAGING/DYNAMIC resource. + * + * This util module allows to implement Gallium drivers as a Direct3D + * driver would be implemented: transfers allocate a resource with + * PIPE_USAGE_STAGING, and copy the data between it and the real resource + * with resource_copy_region. + */ + +#ifndef U_STAGING_H +#define U_STAGING_H + +#include "pipe/p_state.h" + +struct util_staging_transfer { + struct pipe_transfer base; + + /* if direct, same as base.resource, otherwise the temporary staging resource */ + struct pipe_resource *staging_resource; +}; + +/* user must be stride, slice_stride and offset */ +/* pt->usage == PIPE_USAGE_DYNAMIC should be a good value to pass for direct */ +/* staging resource is currently created with PIPE_USAGE_DYNAMIC */ +struct util_staging_transfer * +util_staging_transfer_new(struct pipe_context *pipe, + struct pipe_resource *pt, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box, + bool direct); + +void +util_staging_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *ptx); + +#endif diff --git a/src/gallium/auxiliary/util/u_surfaces.c b/src/gallium/auxiliary/util/u_surfaces.c index b5d21570d57..7733ad24d0d 100644 --- a/src/gallium/auxiliary/util/u_surfaces.c +++ b/src/gallium/auxiliary/util/u_surfaces.c @@ -3,40 +3,22 @@ #include "util/u_inlines.h" #include "util/u_memory.h" -/* TODO: ouch, util_hash_table should do these by default when passed a null function pointer - * this indirect function call is quite bad - */ -static unsigned -hash(void *key) -{ - return (unsigned)(uintptr_t)key; -} - -static int -compare(void *key1, void *key2) -{ - return (unsigned)(uintptr_t)key1 - (unsigned)(uintptr_t)key2; -} - struct pipe_surface * util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, struct pipe_screen *pscreen, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice, unsigned flags) { struct pipe_surface *ps; - void *key = NULL; if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE) - { /* or 2D array */ - if(!us->u.table) - us->u.table = util_hash_table_create(hash, compare); - key = (void *)(uintptr_t)(((zslice + face) << 8) | level); - /* TODO: ouch, should have a get-reference function... - * also, shouldn't allocate a two-pointer structure for each item... */ - ps = util_hash_table_get(us->u.table, key); + { /* or 2D array */ + if(!us->u.hash) + us->u.hash = cso_hash_create(); + + ps = cso_hash_iter_data(cso_hash_find(us->u.hash, ((zslice + face) << 8) | level)); } else { if(!us->u.array) - us->u.array = CALLOC(pt->last_level + 1, sizeof(struct pipe_surface *)); + us->u.array = CALLOC(pt->last_level + 1, sizeof(struct pipe_surface *)); ps = us->u.array[level]; } @@ -54,7 +36,7 @@ util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, str ps->offset = ~0; if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE) - util_hash_table_set(us->u.table, key, ps); + cso_hash_insert(us->u.hash, ((zslice + face) << 8) | level, ps); else us->u.array[level] = ps; @@ -66,47 +48,44 @@ util_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps) { struct pipe_resource *pt = ps->texture; if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE) - { /* or 2D array */ - void* key = (void*)(uintptr_t)(((ps->zslice + ps->face) << 8) | ps->level); - util_hash_table_remove(us->u.table, key); + { /* or 2D array */ + cso_hash_erase(us->u.hash, cso_hash_find(us->u.hash, ((ps->zslice + ps->face) << 8) | ps->level)); } else us->u.array[ps->level] = 0; } -static enum pipe_error -util_surfaces_destroy_callback(void *key, void *value, void *data) -{ - void (*destroy_surface) (struct pipe_surface * ps) = data; - destroy_surface((struct pipe_surface *)value); - return PIPE_OK; -} - void util_surfaces_destroy(struct util_surfaces *us, struct pipe_resource *pt, void (*destroy_surface) (struct pipe_surface *)) { if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE) - { /* or 2D array */ - if(us->u.table) + { /* or 2D array */ + if(us->u.hash) { - util_hash_table_foreach(us->u.table, util_surfaces_destroy_callback, destroy_surface); - util_hash_table_destroy(us->u.table); - us->u.table = NULL; + struct cso_hash_iter iter; + iter = cso_hash_first_node(us->u.hash); + while (!cso_hash_iter_is_null(iter)) { + destroy_surface(cso_hash_iter_data(iter)); + iter = cso_hash_iter_next(iter); + } + + cso_hash_delete(us->u.hash); + us->u.hash = NULL; } } else { if(us->u.array) { - unsigned i; - for(i = 0; i < pt->last_level; ++i) - { - struct pipe_surface *ps = us->u.array[i]; - if(ps) - destroy_surface(ps); - } - FREE(us->u.array); - us->u.array = NULL; + unsigned i; + for(i = 0; i <= pt->last_level; ++i) + { + struct pipe_surface *ps = us->u.array[i]; + if(ps) + destroy_surface(ps); + } + FREE(us->u.array); + us->u.array = NULL; } } } diff --git a/src/gallium/auxiliary/util/u_surfaces.h b/src/gallium/auxiliary/util/u_surfaces.h index 0195bf5afba..af978c70579 100644 --- a/src/gallium/auxiliary/util/u_surfaces.h +++ b/src/gallium/auxiliary/util/u_surfaces.h @@ -4,15 +4,15 @@ #include "pipe/p_compiler.h" #include "pipe/p_state.h" #include "util/u_atomic.h" - -struct util_hash_table; +#include "cso_cache/cso_hash.h" struct util_surfaces { union { - struct util_hash_table *table; + struct cso_hash *hash; struct pipe_surface **array; + void* pv; } u; }; @@ -35,6 +35,18 @@ util_surfaces_get(struct util_surfaces *us, unsigned surface_struct_size, struct return util_surfaces_do_get(us, surface_struct_size, pscreen, pt, face, level, zslice, flags); } +static INLINE struct pipe_surface * +util_surfaces_peek(struct util_surfaces *us, struct pipe_resource *pt, unsigned face, unsigned level, unsigned zslice) +{ + if(!us->u.pv) + return 0; + + if(unlikely(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)) + return cso_hash_iter_data(cso_hash_find(us->u.hash, ((zslice + face) << 8) | level)); + else + return us->u.array[level]; +} + void util_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps); static INLINE void diff --git a/src/gallium/docs/d3d11ddi.txt b/src/gallium/docs/d3d11ddi.txt index 0954c2926df..f8155c828b1 100644 --- a/src/gallium/docs/d3d11ddi.txt +++ b/src/gallium/docs/d3d11ddi.txt @@ -66,9 +66,6 @@ Unordered access view: view supporting random read/write access (usually from co clear + Gallium supports clearing both render targets and depth/stencil with a single call -draw_range_elements - + Gallium supports indexed draw with explicit range - fence_signalled fence_finish + D3D10/D3D11 don't appear to support explicit fencing; queries can often substitute though, and flushing is supported @@ -271,31 +268,27 @@ Dispatch (D3D11 only) DispatchIndirect (D3D11 only) - Gallium does not support compute shaders -Draw -> draw_arrays +Draw -> draw_vbo ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better DrawAuto -> draw_auto -DrawIndexed -> draw_elements +DrawIndexed -> draw_vbo ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better - * may want to add a separate set_index_buffer - - Gallium lacks base vertex for indexed draw calls - + D3D11 lacks draw_range_elements functionality, which is required for OpenGL + + D3D11 lacks explicit range, which is required for OpenGL -DrawIndexedInstanced -> draw_elements_instanced +DrawIndexedInstanced -> draw_vbo ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better - * may want to add a separate set_index_buffer - - Gallium lacks base vertex for indexed draw calls -DrawIndexedInstancedIndirect (D3D11 only) -> call draw_elements_instanced multiple times in software - # this allows to use an hardware buffer to specify the parameters for multiple draw_elements_instanced calls +DrawIndexedInstancedIndirect (D3D11 only) + # this allows to use an hardware buffer to specify the parameters for multiple draw_vbo calls - Gallium does not support draw call parameter buffers and indirect draw -DrawInstanced -> draw_arrays_instanced +DrawInstanced -> draw_vbo ! D3D11 sets primitive modes separately with IaSetTopology: it's not obvious which is better -DrawInstancedIndirect (D3D11 only) -> call draw_arrays_instanced multiple times in software - # this allows to use an hardware buffer to specify the parameters for multiple draw_arrays_instanced calls +DrawInstancedIndirect (D3D11 only) + # this allows to use an hardware buffer to specify the parameters for multiple draw_vbo calls - Gallium does not support draw call parameter buffers and indirect draws DsSetConstantBuffers (D3D11 only) @@ -332,10 +325,9 @@ HsSetShaderResources (D3D11 only) HsSetShaderWithIfaces (D3D11 only) - Gallium does not support hull shaders -IaSetIndexBuffer - ! Gallium passes this to the draw_elements or draw_elements_instanced calls +IaSetIndexBuffer -> set_index_buffer + Gallium supports 8-bit indices - ! the D3D11 interface allows index-size-unaligned byte offsets into index buffers; it's not clear whether they actually work + # the D3D11 interface allows index-size-unaligned byte offsets into the index buffer; most drivers will abort with an assertion IaSetInputLayout -> bind_vertex_elements_state diff --git a/src/gallium/docs/source/conf.py b/src/gallium/docs/source/conf.py index ccc84405c41..0846e7d0ece 100644 --- a/src/gallium/docs/source/conf.py +++ b/src/gallium/docs/source/conf.py @@ -22,7 +22,7 @@ sys.path.append(os.path.abspath('exts')) # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.pngmath', 'tgsi'] +extensions = ['sphinx.ext.pngmath', 'formatting'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -38,7 +38,7 @@ master_doc = 'index' # General information about the project. project = u'Gallium' -copyright = u'2009, VMWare, X.org, Nouveau' +copyright = u'2009, VMware, X.org, Nouveau' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -176,7 +176,7 @@ htmlhelp_basename = 'Galliumdoc' # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'Gallium.tex', u'Gallium Documentation', - u'VMWare, X.org, Nouveau', 'manual'), + u'VMware, X.org, Nouveau', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index 4e35a4c4082..f241411a002 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -45,6 +45,7 @@ buffers, surfaces) are bound to the driver. * ``set_vertex_buffers`` +* ``set_index_buffer`` Non-CSO State ^^^^^^^^^^^^^ @@ -132,50 +133,26 @@ this surface need not be bound to the framebuffer. Drawing ^^^^^^^ -``draw_arrays`` draws a specified primitive. +``draw_vbo`` draws a specified primitive. The primitive mode and other +properties are described by ``pipe_draw_info``. -This command is equivalent to calling ``draw_arrays_instanced`` -with ``startInstance`` set to 0 and ``instanceCount`` set to 1. +The ``mode``, ``start``, and ``count`` fields of ``pipe_draw_info`` specify the +the mode of the primitive and the vertices to be fetched, in the range between +``start`` to ``start``+``count``-1, inclusive. -``draw_elements`` draws a specified primitive using an optional -index buffer. +Every instance with instanceID in the range between ``start_instance`` and +``start_instance``+``instance_count``-1, inclusive, will be drawn. -This command is equivalent to calling ``draw_elements_instanced`` -with ``startInstance`` set to 0 and ``instanceCount`` set to 1. +All vertex indices must fall inside the range given by ``min_index`` and +``max_index``. In case non-indexed draw, ``min_index`` should be set to +``start`` and ``max_index`` should be set to ``start``+``count``-1. -``draw_range_elements`` +``index_bias`` is a value added to every vertex index before fetching vertex +attributes. It does not affect ``min_index`` and ``max_index``. -XXX: this is (probably) a temporary entrypoint, as the range -information should be available from the vertex_buffer state. -Using this to quickly evaluate a specialized path in the draw -module. - -``draw_arrays_instanced`` draws multiple instances of the same primitive. - -This command is equivalent to calling ``draw_elements_instanced`` -with ``indexBuffer`` set to NULL and ``indexSize`` set to 0. - -``draw_elements_instanced`` draws multiple instances of the same primitive -using an optional index buffer. - -For instanceID in the range between ``startInstance`` -and ``startInstance``+``instanceCount``-1, inclusive, draw a primitive -specified by ``mode`` and sequential numbers in the range between ``start`` -and ``start``+``count``-1, inclusive. - -If ``indexBuffer`` is not NULL, it specifies an index buffer with index -byte size of ``indexSize``. The sequential numbers are used to lookup -the index buffer and the resulting indices in turn are used to fetch -vertex attributes. - -If ``indexBuffer`` is NULL, the sequential numbers are used directly -as indices to fetch vertex attributes. - -``indexBias`` is a value which is added to every index read from the index -buffer before fetching vertex attributes. - -``minIndex`` and ``maxIndex`` describe minimum and maximum index contained in -the index buffer. +If there is an index buffer bound, and ``indexed`` field is true, all vertex +indices will be looked up in the index buffer. ``min_index``, ``max_index``, +and ``index_bias`` apply after index lookup. If a given vertex element has ``instance_divisor`` set to 0, it is said it contains per-vertex data and effective vertex attribute address needs diff --git a/src/gallium/docs/source/cso/rasterizer.rst b/src/gallium/docs/source/cso/rasterizer.rst index ad1612f93e3..ee3419ccfca 100644 --- a/src/gallium/docs/source/cso/rasterizer.rst +++ b/src/gallium/docs/source/cso/rasterizer.rst @@ -126,11 +126,15 @@ sprite_coord_enable Specifies if a texture unit has its texture coordinates replaced or not. This is a packed bitfield containing the enable for all texcoords -- if all bits -are zero, point sprites are effectively disabled. If any bit is set, then -point_smooth and point_quad_rasterization are ignored; point smoothing is -disabled and points are always rasterized as quads. If enabled, the four -vertices of the resulting quad will be assigned texture coordinates, -according to sprite_coord_mode. +are zero, point sprites are effectively disabled. + +If any bit is set, then point_smooth MUST be disabled (there are no +round sprites) and point_quad_rasterization MUST be true (sprites are +always rasterized as quads). Any mismatch between these states should +be considered a bug in the state-tracker. + +If enabled, the four vertices of the resulting quad will be assigned +texture coordinates, according to sprite_coord_mode. sprite_coord_mode ^^^^^^^^^^^^^^^^^ @@ -141,20 +145,23 @@ have coordinates (0,0,0,1). For PIPE_SPRITE_COORD_UPPER_LEFT, the upper-left vertex will have coordinates (0,0,0,1). This state is used by :ref:`Draw` to generate texcoords. -.. note:: - - When geometry shaders are available, a special geometry shader could be - used instead of this functionality, to convert incoming points into quads - with the proper texture coordinates. - point_quad_rasterization ^^^^^^^^^^^^^^^^^^^^^^^^ -Determines if points should be rasterized as quads or points. Certain APIs, -like Direct3D, always use quad rasterization for points, regardless of -whether point sprites are enabled or not. If this state is enabled, point -smoothing and antialiasing are disabled. If it is disabled, point sprite -coordinates are not generated. +Determines if points should be rasterized according to quad or point +rasterization rules. + +OpenGL actually has quite different rasterization rules for points and +point sprites - hence this indicates if points should be rasterized as +points or according to point sprite (which decomposes them into quads, +basically) rules. + +Additionally Direct3D will always use quad rasterization rules for +points, regardless of whether point sprites are enabled or not. + +If this state is enabled, point smoothing and antialiasing are +disabled. If it is disabled, point sprite coordinates are not +generated. .. note:: diff --git a/src/gallium/docs/source/debugging.rst b/src/gallium/docs/source/debugging.rst new file mode 100644 index 00000000000..42bda5aee93 --- /dev/null +++ b/src/gallium/docs/source/debugging.rst @@ -0,0 +1,101 @@ +Debugging +========= + +Debugging utilities in gallium. + +Debug Variables +^^^^^^^^^^^^^^^ + +All drivers respond to a set of common debug environment variables, as well as +some driver-specific variables. Set them as normal environment variables for +the platform or operating system you are running. For example, for Linux this +can be done by typing "export var=value" into a console and then running the +program from that console. + +Common +"""""" + +.. envvar:: GALLIUM_PRINT_OPTIONS <bool> (false) + +This option controls if the debug variables should be printed to stderr. This +is probably the most useful variable, since it allows you to find which +variables a driver uses. + +.. envvar:: GALLIUM_RBUG <bool> (false) + +Controls if the :ref:`rbug` should be used. + +.. envvar:: GALLIUM_TRACE <string> ("") + +If set, this variable will cause the :ref:`Trace` output to be written to the +specified file. Paths may be relative or absolute; relative paths are relative +to the working directory. For example, setting it to "trace.xml" will cause +the trace to be written to a file of the same name in the working directory. + +.. envvar:: GALLIUM_DUMP_CPU <bool> (false) + +Dump information about the current CPU that the driver is running on. + +.. envvar:: TGSI_PRINT_SANITY <bool> (false) + +Gallium has a built-in shader sanity checker. This option controls whether +the shader sanity checker prints its warnings and errors to stderr. + +.. envvar:: DRAW_USE_LLVM <bool> (false) + +Whether the :ref:`Draw` module will attempt to use LLVM for vertex and geometry shaders. + + +State tracker-specific +"""""""""""""""""""""" + +.. envvar:: ST_DEBUG <flags> (0x0) + +Debug :ref:`flags` for the GL state tracker. + + +Driver-specific +""""""""""""""" + +.. envvar:: I915_DEBUG <flags> (0x0) + +Debug :ref:`flags` for the i915 driver. + +.. envvar:: I915_NO_HW <bool> (false) + +Stop the i915 driver from submitting commands to the hardware. + +.. envvar:: I915_DUMP_CMD <bool> (false) + +Dump all commands going to the hardware. + +.. envvar:: LP_DEBUG <flags> (0x0) + +Debug :ref:`flags` for the llvmpipe driver. + +.. envvar:: LP_NUM_THREADS <int> (number of CPUs) + +Number of threads that the llvmpipe driver should use. + + +.. _flags: + +Flags +""""" + +The variables of type "flags" all take a string with comma-separated flags to +enable different debugging for different parts of the drivers or state +tracker. If set to "help", the driver will print a list of flags which the +variable accepts. Order does not matter. + + +.. _rbug: + +Remote Debugger +^^^^^^^^^^^^^^^ + +The remote debugger, commonly known as rbug, allows for runtime inspections of +:ref:`Context`, :ref:`Screen`, :ref:`Resource` and :ref:`Shader` objects; and +pausing and stepping of :ref:`Draw` calls. Is used with rbug-gui which is +hosted outside of the main mesa repository. rbug is can be used over a network +connection, so the debugger does not need to be on the same machine. diff --git a/src/gallium/docs/source/distro.rst b/src/gallium/docs/source/distro.rst index 6ba5a056f45..70d75b51e65 100644 --- a/src/gallium/docs/source/distro.rst +++ b/src/gallium/docs/source/distro.rst @@ -51,10 +51,10 @@ nVidia nv50 Driver for the nVidia nv50 family of GPUs. -VMWare SVGA +VMware SVGA ^^^^^^^^^^^ -Driver for VMWare virtualized guest operating system graphics processing. +Driver for VMware virtualized guest operating system graphics processing. ATI r300 ^^^^^^^^ @@ -74,6 +74,11 @@ Trace Wrapper driver. Trace dumps an XML record of the calls made to the :ref:`Context` and :ref:`Screen` objects that it wraps. +Rbug +^^^^ + +Wrapper driver. :ref:`rbug` driver used with stand alone rbug-gui. + State Trackers -------------- diff --git a/src/gallium/docs/source/exts/formatting.py b/src/gallium/docs/source/exts/formatting.py new file mode 100644 index 00000000000..14865f36033 --- /dev/null +++ b/src/gallium/docs/source/exts/formatting.py @@ -0,0 +1,31 @@ +# formatting.py +# Sphinx extension providing formatting for Gallium-specific data +# (c) Corbin Simpson 2010 +# Public domain to the extent permitted; contact author for special licensing + +import docutils.nodes +import sphinx.addnodes + +def parse_envvar(env, sig, signode): + envvar, t, default = sig.split(" ", 2) + envvar = envvar.strip().upper() + t = " Type: %s" % t.strip(" <>").lower() + default = " Default: %s" % default.strip(" ()") + signode += sphinx.addnodes.desc_name(envvar, envvar) + signode += sphinx.addnodes.desc_type(t, t) + signode += sphinx.addnodes.desc_annotation(default, default) + return envvar + +def parse_opcode(env, sig, signode): + opcode, desc = sig.split("-", 1) + opcode = opcode.strip().upper() + desc = " (%s)" % desc.strip() + signode += sphinx.addnodes.desc_name(opcode, opcode) + signode += sphinx.addnodes.desc_annotation(desc, desc) + return opcode + +def setup(app): + app.add_description_unit("envvar", "envvar", "%s (environment variable)", + parse_envvar) + app.add_description_unit("opcode", "opcode", "%s (TGSI opcode)", + parse_opcode) diff --git a/src/gallium/docs/source/exts/tgsi.py b/src/gallium/docs/source/exts/tgsi.py deleted file mode 100644 index e92cd5c4d1b..00000000000 --- a/src/gallium/docs/source/exts/tgsi.py +++ /dev/null @@ -1,17 +0,0 @@ -# tgsi.py -# Sphinx extension providing formatting for TGSI opcodes -# (c) Corbin Simpson 2010 - -import docutils.nodes -import sphinx.addnodes - -def parse_opcode(env, sig, signode): - opcode, desc = sig.split("-", 1) - opcode = opcode.strip().upper() - desc = " (%s)" % desc.strip() - signode += sphinx.addnodes.desc_name(opcode, opcode) - signode += sphinx.addnodes.desc_annotation(desc, desc) - return opcode - -def setup(app): - app.add_description_unit("opcode", "opcode", "%s (TGSI opcode)", parse_opcode) diff --git a/src/gallium/docs/source/index.rst b/src/gallium/docs/source/index.rst index 54bc883fced..6c19842dac4 100644 --- a/src/gallium/docs/source/index.rst +++ b/src/gallium/docs/source/index.rst @@ -12,6 +12,7 @@ Contents: :maxdepth: 2 intro + debugging tgsi screen context diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index bbb112fd336..a8cdde34aa7 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -230,7 +230,7 @@ struct cell_command_rasterizer { opcode_t opcode; /**< CELL_CMD_STATE_RASTERIZER */ struct pipe_rasterizer_state rasterizer; - uint32_t pad[1]; + /*uint32_t pad[1];*/ }; diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 07b6eebc69c..d1aee62ba1e 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -132,6 +132,7 @@ struct cell_context struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; uint num_vertex_buffers; + struct pipe_index_buffer index_buffer; ubyte *cbuf_map[PIPE_MAX_COLOR_BUFS]; ubyte *zsbuf_map; @@ -154,7 +155,7 @@ struct cell_context struct vertex_info vertex_info; /** Mapped constant buffers */ - void *mapped_constants[PIPE_SHADER_TYPES]; + const void *mapped_constants[PIPE_SHADER_TYPES]; PIPE_ALIGN_VAR(16) struct cell_spu_function_info spu_functions; diff --git a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c index 6a1e4d8a646..4adef5b8c07 100644 --- a/src/gallium/drivers/cell/ppu/cell_draw_arrays.c +++ b/src/gallium/drivers/cell/ppu/cell_draw_arrays.c @@ -56,16 +56,11 @@ * XXX should the element buffer be specified/bound with a separate function? */ static void -cell_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned min_index, - unsigned max_index, - unsigned mode, unsigned start, unsigned count) +cell_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct cell_context *cell = cell_context(pipe); struct draw_context *draw = cell->draw; + void *mapped_indices = NULL; unsigned i; if (cell->dirty) @@ -83,18 +78,20 @@ cell_draw_range_elements(struct pipe_context *pipe, draw_set_mapped_vertex_buffer(draw, i, buf); } /* Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes = cell_resource(indexBuffer)->data; - draw_set_mapped_element_buffer(draw, indexSize, indexBias, mapped_indexes); - } - else { - /* no index/element buffer */ - draw_set_mapped_element_buffer(draw, 0, 0, NULL); + if (info->indexed && cell->index_buffer.buffer) { + mapped_indices = cell_resource(cell->index_buffer.buffer)->data; + mapped_indices += cell->index_buffer.offset; } + draw_set_mapped_element_buffer_range(draw, (mapped_indices) ? + lp->index_buffer.index_size : 0, + info->index_bias, + info->min_index, + info->max_index, + mapped_indices); /* draw! */ - draw_arrays(draw, mode, start, count); + draw_arrays(draw, info->mode, info->start, info->count); /* * unmap vertex/index buffers - will cause draw module to flush @@ -102,7 +99,7 @@ cell_draw_range_elements(struct pipe_context *pipe, for (i = 0; i < cell->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); } - if (indexBuffer) { + if (mapped_indices) { draw_set_mapped_element_buffer(draw, 0, 0, NULL); } @@ -115,32 +112,9 @@ cell_draw_range_elements(struct pipe_context *pipe, } -static void -cell_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count) -{ - cell_draw_range_elements( pipe, indexBuffer, - indexSize, indexBias, - 0, 0xffffffff, - mode, start, count ); -} - - -static void -cell_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count) -{ - cell_draw_elements(pipe, NULL, 0, 0, mode, start, count); -} - - void cell_init_draw_functions(struct cell_context *cell) { - cell->pipe.draw_arrays = cell_draw_arrays; - cell->pipe.draw_elements = cell_draw_elements; - cell->pipe.draw_range_elements = cell_draw_range_elements; + cell->pipe.draw_vbo = cell_draw_vbo; } diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c index 34ca864155b..e7c9fc46d9f 100644 --- a/src/gallium/drivers/cell/ppu/cell_fence.c +++ b/src/gallium/drivers/cell/ppu/cell_fence.c @@ -87,6 +87,7 @@ struct cell_buffer_node }; +#if 0 static void cell_add_buffer_to_list(struct cell_context *cell, struct cell_buffer_list *list, @@ -100,6 +101,7 @@ cell_add_buffer_to_list(struct cell_context *cell, list->head = node; } } +#endif /** @@ -113,7 +115,7 @@ cell_free_fenced_buffers(struct cell_context *cell, struct cell_buffer_list *list) { if (list->head) { - struct pipe_screen *ps = cell->pipe.screen; + /*struct pipe_screen *ps = cell->pipe.screen;*/ struct cell_buffer_node *node; cell_fence_finish(cell, &list->fence); @@ -146,7 +148,7 @@ cell_free_fenced_buffers(struct cell_context *cell, void cell_add_fenced_textures(struct cell_context *cell) { - struct cell_buffer_list *list = &cell->fenced_buffers[cell->cur_batch]; + /*struct cell_buffer_list *list = &cell->fenced_buffers[cell->cur_batch];*/ uint i; for (i = 0; i < cell->num_textures; i++) { diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 03f84d295b5..223adda48f0 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -281,7 +281,7 @@ cell_set_fragment_sampler_views(struct pipe_context *pipe, struct pipe_resource *new_tex = new_view ? new_view->texture : NULL; pipe_sampler_view_reference(&cell->fragment_sampler_views[i], - views[i]); + new_view); pipe_resource_reference((struct pipe_resource **) &cell->texture[i], (struct pipe_resource *) new_tex); diff --git a/src/gallium/drivers/cell/ppu/cell_state_vertex.c b/src/gallium/drivers/cell/ppu/cell_state_vertex.c index 9510ea9ac2b..4e3701cd0ac 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_vertex.c +++ b/src/gallium/drivers/cell/ppu/cell_state_vertex.c @@ -36,7 +36,7 @@ #include "draw/draw_context.h" -void * +static void * cell_create_vertex_elements_state(struct pipe_context *pipe, unsigned count, const struct pipe_vertex_element *attribs) @@ -51,7 +51,7 @@ cell_create_vertex_elements_state(struct pipe_context *pipe, return velems; } -void +static void cell_bind_vertex_elements_state(struct pipe_context *pipe, void *velems) { @@ -66,7 +66,7 @@ cell_bind_vertex_elements_state(struct pipe_context *pipe, draw_set_vertex_elements(cell->draw, cell_velems->count, cell_velems->velem); } -void +static void cell_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) { FREE( velems ); @@ -91,10 +91,26 @@ cell_set_vertex_buffers(struct pipe_context *pipe, } +static void +cell_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct cell_context *cell = cell_context(pipe); + + if (ib) + memcpy(&cell->index_buffer, ib, sizeof(cell->index_buffer)); + else + memset(&cell->index_buffer, 0, sizeof(cell->index_buffer)); + + /* TODO make this more like a state */ +} + + void cell_init_vertex_functions(struct cell_context *cell) { cell->pipe.set_vertex_buffers = cell_set_vertex_buffers; + cell->pipe.set_index_buffer = cell_set_index_buffer; cell->pipe.create_vertex_elements_state = cell_create_vertex_elements_state; cell->pipe.bind_vertex_elements_state = cell_bind_vertex_elements_state; cell->pipe.delete_vertex_elements_state = cell_delete_vertex_elements_state; diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index 9c9c1bdc452..761a0fce721 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -50,13 +50,8 @@ void failover_fail_over( struct failover_context *failover ) } -static void failover_draw_elements( struct pipe_context *pipe, - struct pipe_resource *indexResource, - unsigned indexSize, - int indexBias, - unsigned prim, - unsigned start, - unsigned count) +static void failover_draw_vbo( struct pipe_context *pipe, + const struct pipe_draw_info *info) { struct failover_context *failover = failover_context( pipe ); @@ -70,13 +65,7 @@ static void failover_draw_elements( struct pipe_context *pipe, /* Try hardware: */ if (failover->mode == FO_HW) { - failover->hw->draw_elements( failover->hw, - indexResource, - indexSize, - indexBias, - prim, - start, - count ); + failover->hw->draw_vbo( failover->hw, info ); } /* Possibly try software: @@ -88,13 +77,7 @@ static void failover_draw_elements( struct pipe_context *pipe, failover_state_emit( failover ); } - failover->sw->draw_elements( failover->sw, - indexResource, - indexSize, - indexBias, - prim, - start, - count ); + failover->sw->draw_vbo( failover->sw, info ); /* Be ready to switch back to hardware rendering without an * intervening flush. Unlikely to be much performance impact to @@ -104,13 +87,6 @@ static void failover_draw_elements( struct pipe_context *pipe, } } - -static void failover_draw_arrays( struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - failover_draw_elements(pipe, NULL, 0, 0, prim, start, count); -} - static unsigned int failover_is_resource_referenced( struct pipe_context *_pipe, struct pipe_resource *resource, @@ -143,8 +119,7 @@ struct pipe_context *failover_create( struct pipe_context *hw, failover->pipe.get_paramf = hw->get_paramf; #endif - failover->pipe.draw_arrays = failover_draw_arrays; - failover->pipe.draw_elements = failover_draw_elements; + failover->pipe.draw_vbo = failover_draw_vbo; failover->pipe.clear = hw->clear; failover->pipe.clear_render_target = hw->clear_render_target; failover->pipe.clear_depth_stencil = hw->clear_depth_stencil; diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 9d3e0d0dba0..1afa6c9ceed 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -56,6 +56,7 @@ #define FO_NEW_VERTEX_BUFFER 0x40000 #define FO_NEW_VERTEX_ELEMENT 0x80000 #define FO_NEW_SAMPLE_MASK 0x100000 +#define FO_NEW_INDEX_BUFFER 0x200000 @@ -97,6 +98,7 @@ struct failover_context { struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; + struct pipe_index_buffer index_buffer; uint num_vertex_buffers; diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index 12e42379f98..c265f381b67 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -583,6 +583,23 @@ failover_set_vertex_buffers(struct pipe_context *pipe, } +static void +failover_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct failover_context *failover = failover_context(pipe); + + if (ib) + memcpy(&failover->index_buffer, ib, sizeof(failover->index_buffer)); + else + memset(&failover->index_buffer, 0, sizeof(failover->index_buffer)); + + failover->dirty |= FO_NEW_INDEX_BUFFER; + failover->sw->set_index_buffer( failover->sw, ib ); + failover->hw->set_index_buffer( failover->hw, ib ); +} + + void failover_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, @@ -635,6 +652,7 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.set_vertex_sampler_views = failover_set_vertex_sampler_views; failover->pipe.set_viewport_state = failover_set_viewport_state; failover->pipe.set_vertex_buffers = failover_set_vertex_buffers; + failover->pipe.set_index_buffer = failover_set_index_buffer; failover->pipe.set_constant_buffer = failover_set_constant_buffer; failover->pipe.create_sampler_view = failover_create_sampler_view; failover->pipe.sampler_view_destroy = failover_sampler_view_destroy; diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index 147f23269ca..7f434ff9d68 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -135,5 +135,10 @@ failover_state_emit( struct failover_context *failover ) failover->vertex_buffers ); } + if (failover->dirty & FO_NEW_INDEX_BUFFER) { + failover->sw->set_index_buffer( failover->sw, + &failover->index_buffer ); + } + failover->dirty = 0; } diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c index ab6f17b3ab8..fe14a287efb 100644 --- a/src/gallium/drivers/galahad/glhd_context.c +++ b/src/gallium/drivers/galahad/glhd_context.c @@ -48,68 +48,13 @@ galahad_destroy(struct pipe_context *_pipe) } static void -galahad_draw_arrays(struct pipe_context *_pipe, - unsigned prim, - unsigned start, - unsigned count) +galahad_draw_vbo(struct pipe_context *_pipe, + const struct pipe_draw_info *info) { struct galahad_context *glhd_pipe = galahad_context(_pipe); struct pipe_context *pipe = glhd_pipe->pipe; - pipe->draw_arrays(pipe, - prim, - start, - count); -} - -static void -galahad_draw_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned prim, - unsigned start, - unsigned count) -{ - struct galahad_context *glhd_pipe = galahad_context(_pipe); - struct galahad_resource *glhd_resource = galahad_resource(_indexResource); - struct pipe_context *pipe = glhd_pipe->pipe; - struct pipe_resource *indexResource = glhd_resource->resource; - - pipe->draw_elements(pipe, - indexResource, - indexSize, - indexBias, - prim, - start, - count); -} - -static void -galahad_draw_range_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) -{ - struct galahad_context *glhd_pipe = galahad_context(_pipe); - struct galahad_resource *glhd_resource = galahad_resource(_indexResource); - struct pipe_context *pipe = glhd_pipe->pipe; - struct pipe_resource *indexResource = glhd_resource->resource; - - pipe->draw_range_elements(pipe, - indexResource, - indexSize, - indexBias, - minIndex, - maxIndex, - mode, - start, - count); + pipe->draw_vbo(pipe, info); } static struct pipe_query * @@ -650,6 +595,41 @@ galahad_set_vertex_buffers(struct pipe_context *_pipe, num_buffers, buffers); } + +static void +galahad_set_index_buffer(struct pipe_context *_pipe, + const struct pipe_index_buffer *_ib) +{ + struct galahad_context *glhd_pipe = galahad_context(_pipe); + struct pipe_context *pipe = glhd_pipe->pipe; + struct pipe_index_buffer unwrapped_ib, *ib = NULL; + + if (_ib->buffer) { + switch (_ib->index_size) { + case 1: + case 2: + case 4: + break; + default: + glhd_warn("index buffer %p has unrecognized index size %d", + _ib->buffer, _ib->index_size); + break; + } + } + else if (_ib->offset || _ib->index_size) { + glhd_warn("non-indexed state with index offset %d and index size %d", + _ib->offset, _ib->index_size); + } + + if (_ib) { + unwrapped_ib = *_ib; + unwrapped_ib.buffer = galahad_resource_unwrap(_ib->buffer); + ib = &unwrapped_ib; + } + + pipe->set_index_buffer(pipe, ib); +} + static void galahad_resource_copy_region(struct pipe_context *_pipe, struct pipe_resource *_dst, @@ -934,9 +914,7 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) glhd_pipe->base.draw = NULL; glhd_pipe->base.destroy = galahad_destroy; - glhd_pipe->base.draw_arrays = galahad_draw_arrays; - glhd_pipe->base.draw_elements = galahad_draw_elements; - glhd_pipe->base.draw_range_elements = galahad_draw_range_elements; + glhd_pipe->base.draw_vbo = galahad_draw_vbo; glhd_pipe->base.create_query = galahad_create_query; glhd_pipe->base.destroy_query = galahad_destroy_query; glhd_pipe->base.begin_query = galahad_begin_query; @@ -976,6 +954,7 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) glhd_pipe->base.set_fragment_sampler_views = galahad_set_fragment_sampler_views; glhd_pipe->base.set_vertex_sampler_views = galahad_set_vertex_sampler_views; glhd_pipe->base.set_vertex_buffers = galahad_set_vertex_buffers; + glhd_pipe->base.set_index_buffer = galahad_set_index_buffer; glhd_pipe->base.resource_copy_region = galahad_resource_copy_region; glhd_pipe->base.clear = galahad_clear; glhd_pipe->base.clear_render_target = galahad_clear_render_target; diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index 2af9bdac956..2beb9e3091f 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -45,16 +45,11 @@ static void -i915_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned min_index, - unsigned max_index, - unsigned prim, unsigned start, unsigned count) +i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct i915_context *i915 = i915_context(pipe); struct draw_context *draw = i915->draw; + void *mapped_indices = NULL; unsigned i; if (i915->dirty) @@ -71,16 +66,18 @@ i915_draw_range_elements(struct pipe_context *pipe, /* * Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes = i915_buffer(indexBuffer)->data; - draw_set_mapped_element_buffer_range(draw, indexSize, indexBias, - min_index, - max_index, - mapped_indexes); - } else { - draw_set_mapped_element_buffer(draw, 0, 0, NULL); + if (info->indexed && i915->index_buffer.buffer) { + char *indices = (char *) i915_buffer(i915->index_buffer.buffer)->data; + mapped_indices = (void *) (indices + i915->index_buffer.offset); } + draw_set_mapped_element_buffer_range(draw, (mapped_indices) ? + i915->index_buffer.index_size : 0, + info->index_bias, + info->min_index, + info->max_index, + mapped_indices); + draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, i915->current.constants[PIPE_SHADER_VERTEX], @@ -90,7 +87,7 @@ i915_draw_range_elements(struct pipe_context *pipe, /* * Do the drawing */ - draw_arrays(i915->draw, prim, start, count); + draw_arrays(i915->draw, info->mode, info->start, info->count); /* * unmap vertex/index buffers @@ -99,32 +96,11 @@ i915_draw_range_elements(struct pipe_context *pipe, draw_set_mapped_vertex_buffer(draw, i, NULL); } - if (indexBuffer) { + if (mapped_indices) { draw_set_mapped_element_buffer(draw, 0, 0, NULL); } } -static void -i915_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned prim, unsigned start, unsigned count) -{ - i915_draw_range_elements(pipe, indexBuffer, - indexSize, indexBias, - 0, 0xffffffff, - prim, start, count); -} - -static void -i915_draw_arrays(struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - i915_draw_elements(pipe, NULL, 0, 0, prim, start, count); -} - - - /* * Generic context functions @@ -168,9 +144,7 @@ i915_create_context(struct pipe_screen *screen, void *priv) i915->base.clear = i915_clear; - i915->base.draw_arrays = i915_draw_arrays; - i915->base.draw_elements = i915_draw_elements; - i915->base.draw_range_elements = i915_draw_range_elements; + i915->base.draw_vbo = i915_draw_vbo; /* * Create drawing context and plug our rendering stage into it. diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index b210cb130d0..3ae61d0ea70 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -221,6 +221,7 @@ struct i915_context struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_index_buffer index_buffer; unsigned dirty; diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index e767aa9f8f0..385c3b2d2d3 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -812,6 +812,19 @@ i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) FREE( velems ); } +static void i915_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct i915_context *i915 = i915_context(pipe); + + if (ib) + memcpy(&i915->index_buffer, ib, sizeof(i915->index_buffer)); + else + memset(&i915->index_buffer, 0, sizeof(i915->index_buffer)); + + /* TODO make this more like a state */ +} + static void i915_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) @@ -860,4 +873,5 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.sampler_view_destroy = i915_sampler_view_destroy; i915->base.set_viewport_state = i915_set_viewport_state; i915->base.set_vertex_buffers = i915_set_vertex_buffers; + i915->base.set_index_buffer = i915_set_index_buffer; } diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index 94c9c443f05..56d351f97d1 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -576,6 +576,7 @@ struct brw_context */ struct pipe_resource *index_buffer; unsigned index_size; + unsigned index_offset; /* Updates are signalled by PIPE_NEW_INDEX_RANGE: */ diff --git a/src/gallium/drivers/i965/brw_draw.c b/src/gallium/drivers/i965/brw_draw.c index 4625c2048f9..3ab9024c31e 100644 --- a/src/gallium/drivers/i965/brw_draw.c +++ b/src/gallium/drivers/i965/brw_draw.c @@ -142,7 +142,7 @@ static int brw_emit_prim(struct brw_context *brw, */ static int try_draw_range_elements(struct brw_context *brw, - struct pipe_resource *index_buffer, + boolean indexed, unsigned hw_prim, unsigned start, unsigned count) { @@ -165,7 +165,7 @@ try_draw_range_elements(struct brw_context *brw, if (ret) return ret; - ret = brw_emit_prim(brw, start, count, index_buffer != NULL, hw_prim); + ret = brw_emit_prim(brw, start, count, indexed, hw_prim); if (ret) return ret; @@ -177,91 +177,54 @@ try_draw_range_elements(struct brw_context *brw, static void -brw_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, - unsigned min_index, - unsigned max_index, - unsigned mode, unsigned start, unsigned count) +brw_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct brw_context *brw = brw_context(pipe); int ret; uint32_t hw_prim; - hw_prim = brw_set_prim(brw, mode); + hw_prim = brw_set_prim(brw, info->mode); if (BRW_DEBUG & DEBUG_PRIMS) debug_printf("PRIM: %s start %d count %d index_buffer %p\n", - u_prim_name(mode), start, count, (void *)index_buffer); + u_prim_name(info->mode), info->start, info->count, + (void *) brw->curr.index_buffer); - assert(index_bias == 0); + assert(info->index_bias == 0); - /* Potentially trigger upload of new index buffer. - * - * XXX: do we need to go through state validation to achieve this? - * Could just call upload code directly. + /* Potentially trigger upload of new index buffer range. + * XXX: do we really care? */ - if (brw->curr.index_buffer != index_buffer || - brw->curr.index_size != index_size) { - pipe_resource_reference( &brw->curr.index_buffer, index_buffer ); - brw->curr.index_size = index_size; - brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER; - } - - /* XXX: do we really care? - */ - if (brw->curr.min_index != min_index || - brw->curr.max_index != max_index) + if (brw->curr.min_index != info->min_index || + brw->curr.max_index != info->max_index) { - brw->curr.min_index = min_index; - brw->curr.max_index = max_index; + brw->curr.min_index = info->min_index; + brw->curr.max_index = info->max_index; brw->state.dirty.mesa |= PIPE_NEW_INDEX_RANGE; } /* Make a first attempt at drawing: */ - ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count ); + ret = try_draw_range_elements(brw, info->indexed, + hw_prim, info->start, info->count); /* Otherwise, flush and retry: */ if (ret != 0) { brw_context_flush( brw ); - ret = try_draw_range_elements(brw, index_buffer, hw_prim, start, count ); + ret = try_draw_range_elements(brw, info->indexed, + hw_prim, info->start, info->count); assert(ret == 0); } } -static void -brw_draw_elements(struct pipe_context *pipe, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, - unsigned mode, - unsigned start, unsigned count) -{ - brw_draw_range_elements( pipe, index_buffer, - index_size, index_bias, - 0, 0xffffffff, - mode, - start, count ); -} - -static void -brw_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count) -{ - brw_draw_elements(pipe, NULL, 0, 0, mode, start, count); -} - - boolean brw_draw_init( struct brw_context *brw ) { /* Register our drawing function: */ - brw->base.draw_arrays = brw_draw_arrays; - brw->base.draw_elements = brw_draw_elements; - brw->base.draw_range_elements = brw_draw_range_elements; + brw->base.draw_vbo = brw_draw_vbo; /* Create helpers for uploading data in user buffers: */ diff --git a/src/gallium/drivers/i965/brw_draw_upload.c b/src/gallium/drivers/i965/brw_draw_upload.c index 337eee8cd9c..ebeb1e146aa 100644 --- a/src/gallium/drivers/i965/brw_draw_upload.c +++ b/src/gallium/drivers/i965/brw_draw_upload.c @@ -231,7 +231,7 @@ static int brw_prepare_indices(struct brw_context *brw) struct pipe_resource *upload_buf = NULL; struct brw_winsys_buffer *bo = NULL; GLuint offset; - GLuint index_size; + GLuint index_size, index_offset; GLuint ib_size; int ret; @@ -246,13 +246,14 @@ static int brw_prepare_indices(struct brw_context *brw) ib_size = index_buffer->width0; index_size = brw->curr.index_size; + index_offset = brw->curr.index_offset; /* Turn userbuffer into a proper hardware buffer? */ if (brw_buffer_is_user_buffer(index_buffer)) { ret = u_upload_buffer( brw->vb.upload_index, - 0, + index_offset, ib_size, index_buffer, &offset, @@ -269,7 +270,7 @@ static int brw_prepare_indices(struct brw_context *brw) else { bo = brw_buffer(index_buffer)->bo; ib_size = bo->size; - offset = 0; + offset = index_offset; } /* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading the diff --git a/src/gallium/drivers/i965/brw_pipe_vertex.c b/src/gallium/drivers/i965/brw_pipe_vertex.c index 4a120a51dad..007239efc40 100644 --- a/src/gallium/drivers/i965/brw_pipe_vertex.c +++ b/src/gallium/drivers/i965/brw_pipe_vertex.c @@ -274,10 +274,41 @@ static void brw_set_vertex_buffers(struct pipe_context *pipe, } +static void brw_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct brw_context *brw = brw_context(pipe); + + if (ib) { + if (brw->curr.index_buffer == ib->buffer && + brw->curr.index_offset == ib->offset && + brw->curr.index_size == ib->index_size) + return; + + pipe_resource_reference(&brw->curr.index_buffer, ib->buffer); + brw->curr.index_offset = ib->offset; + brw->curr.index_size = ib->index_size; + } + else { + if (!brw->curr.index_buffer && + !brw->curr.index_offset && + !brw->curr.index_size) + return; + + pipe_resource_reference(&brw->curr.index_buffer, NULL); + brw->curr.index_offset = 0; + brw->curr.index_size = 0; + } + + brw->state.dirty.mesa |= PIPE_NEW_INDEX_BUFFER; +} + + void brw_pipe_vertex_init( struct brw_context *brw ) { brw->base.set_vertex_buffers = brw_set_vertex_buffers; + brw->base.set_index_buffer = brw_set_index_buffer; brw->base.create_vertex_elements_state = brw_create_vertex_elements_state; brw->base.bind_vertex_elements_state = brw_bind_vertex_elements_state; brw->base.delete_vertex_elements_state = brw_delete_vertex_elements_state; diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index 67be895b385..de83c249057 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -46,68 +46,13 @@ identity_destroy(struct pipe_context *_pipe) } static void -identity_draw_arrays(struct pipe_context *_pipe, - unsigned prim, - unsigned start, - unsigned count) +identity_draw_vbo(struct pipe_context *_pipe, + const struct pipe_draw_info *info) { struct identity_context *id_pipe = identity_context(_pipe); struct pipe_context *pipe = id_pipe->pipe; - pipe->draw_arrays(pipe, - prim, - start, - count); -} - -static void -identity_draw_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned prim, - unsigned start, - unsigned count) -{ - struct identity_context *id_pipe = identity_context(_pipe); - struct identity_resource *id_resource = identity_resource(_indexResource); - struct pipe_context *pipe = id_pipe->pipe; - struct pipe_resource *indexResource = id_resource->resource; - - pipe->draw_elements(pipe, - indexResource, - indexSize, - indexBias, - prim, - start, - count); -} - -static void -identity_draw_range_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) -{ - struct identity_context *id_pipe = identity_context(_pipe); - struct identity_resource *id_resource = identity_resource(_indexResource); - struct pipe_context *pipe = id_pipe->pipe; - struct pipe_resource *indexResource = id_resource->resource; - - pipe->draw_range_elements(pipe, - indexResource, - indexSize, - indexBias, - minIndex, - maxIndex, - mode, - start, - count); + pipe->draw_vbo(pipe, info); } static struct pipe_query * @@ -611,6 +556,24 @@ identity_set_vertex_buffers(struct pipe_context *_pipe, num_buffers, buffers); } + +static void +identity_set_index_buffer(struct pipe_context *_pipe, + const struct pipe_index_buffer *_ib) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + struct pipe_index_buffer unwrapped_ib, *ib = NULL; + + if (_ib) { + unwrapped_ib = *_ib; + unwrapped_ib.buffer = identity_resource_unwrap(_ib->buffer); + ib = &unwrapped_ib; + } + + pipe->set_index_buffer(pipe, ib); +} + static void identity_resource_copy_region(struct pipe_context *_pipe, struct pipe_resource *_dst, @@ -889,9 +852,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.draw = NULL; id_pipe->base.destroy = identity_destroy; - id_pipe->base.draw_arrays = identity_draw_arrays; - id_pipe->base.draw_elements = identity_draw_elements; - id_pipe->base.draw_range_elements = identity_draw_range_elements; + id_pipe->base.draw_vbo = identity_draw_vbo; id_pipe->base.create_query = identity_create_query; id_pipe->base.destroy_query = identity_destroy_query; id_pipe->base.begin_query = identity_begin_query; @@ -931,6 +892,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.set_fragment_sampler_views = identity_set_fragment_sampler_views; id_pipe->base.set_vertex_sampler_views = identity_set_vertex_sampler_views; id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers; + id_pipe->base.set_index_buffer = identity_set_index_buffer; id_pipe->base.resource_copy_region = identity_resource_copy_region; id_pipe->base.clear = identity_clear; id_pipe->base.clear_render_target = identity_clear_render_target; diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index fd6ba1561ea..5583fca38e6 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -1,3 +1,4 @@ +from sys import executable as python_cmd import distutils.version Import('*') @@ -16,7 +17,7 @@ env.CodeGenerate( target = 'lp_tile_soa.c', script = 'lp_tile_soa.py', source = ['#src/gallium/auxiliary/util/u_format.csv'], - command = 'python $SCRIPT $SOURCE > $TARGET' + command = python_cmd + ' $SCRIPT $SOURCE > $TARGET' ) # XXX: Our dependency scanner only finds depended modules in relative dirs. diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c index e05bbe5011a..99a768afd80 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c @@ -258,16 +258,16 @@ lp_build_stencil_op_single(struct lp_build_context *bld, } if (stencil->writemask != stencilMax) { - /* compute res = (res & mask) | (stencilVals & ~mask) */ - LLVMValueRef mask = lp_build_const_int_vec(type, stencil->writemask); - LLVMValueRef cmask = LLVMBuildNot(bld->builder, mask, "notWritemask"); - LLVMValueRef t1 = LLVMBuildAnd(bld->builder, res, mask, "t1"); - LLVMValueRef t2 = LLVMBuildAnd(bld->builder, stencilVals, cmask, "t2"); - res = LLVMBuildOr(bld->builder, t1, t2, "t1_or_t2"); + /* mask &= stencil->writemask */ + LLVMValueRef writemask = lp_build_const_int_vec(type, stencil->writemask); + mask = LLVMBuildAnd(bld->builder, mask, writemask, ""); + /* res = (res & mask) | (stencilVals & ~mask) */ + res = lp_build_select_bitwise(bld, writemask, res, stencilVals); + } + else { + /* res = mask ? res : stencilVals */ + res = lp_build_select(bld, mask, res, stencilVals); } - - /* only the update the vector elements enabled by 'mask' */ - res = lp_build_select(bld, mask, res, stencilVals); return res; } @@ -662,9 +662,9 @@ lp_build_depth_stencil_test(LLVMBuilderRef builder, } /* Mix the old and new Z buffer values. - * z_dst[i] = zselectmask[i] ? z_src[i] : z_dst[i] + * z_dst[i] = (zselectmask[i] & z_src[i]) | (~zselectmask[i] & z_dst[i]) */ - z_dst = lp_build_select(&bld, zselectmask, z_src, z_dst); + z_dst = lp_build_select_bitwise(&bld, zselectmask, z_src, z_dst); } if (stencil[0].enabled) { diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c index 78744da500b..2cf6f38c4b8 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c @@ -141,7 +141,7 @@ coeffs_init(struct lp_build_interp_soa_context *bld, else { dadx = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dadx_ptr, &index, 1, ""), ""); dady = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dady_ptr, &index, 1, ""), ""); - dadxy = LLVMBuildAdd(builder, dadx, dady, ""); + dadxy = LLVMBuildFAdd(builder, dadx, dady, ""); attrib_name(dadx, attrib, chan, ".dadx"); attrib_name(dady, attrib, chan, ".dady"); attrib_name(dadxy, attrib, chan, ".dadxy"); @@ -177,7 +177,7 @@ coeffs_init(struct lp_build_interp_soa_context *bld, * dadq2 = 2 * dq */ - dadq2 = LLVMBuildAdd(builder, dadq, dadq, ""); + dadq2 = LLVMBuildFAdd(builder, dadq, dadq, ""); /* * a = a0 + x * dadx + y * dady @@ -193,12 +193,11 @@ coeffs_init(struct lp_build_interp_soa_context *bld, a = a0; if (interp != LP_INTERP_CONSTANT && interp != LP_INTERP_FACING) { - a = LLVMBuildAdd(builder, a, - LLVMBuildMul(builder, bld->x, dadx, ""), - ""); - a = LLVMBuildAdd(builder, a, - LLVMBuildMul(builder, bld->y, dady, ""), - ""); + LLVMValueRef tmp; + tmp = LLVMBuildFMul(builder, bld->x, dadx, ""); + a = LLVMBuildFAdd(builder, a, tmp, ""); + tmp = LLVMBuildFMul(builder, bld->y, dady, ""); + a = LLVMBuildFAdd(builder, a, tmp, ""); } } @@ -212,7 +211,7 @@ coeffs_init(struct lp_build_interp_soa_context *bld, * Compute the attrib values on the upper-left corner of each quad. */ - a = LLVMBuildAdd(builder, a, dadq2, ""); + a = LLVMBuildFAdd(builder, a, dadq2, ""); /* * a *= 1 / w diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 3db4f12ebb6..7543bd7b2b0 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -46,6 +46,10 @@ #include "lp_query.h" #include "lp_setup.h" + +DEBUG_GET_ONCE_BOOL_OPTION(lp_no_rast, "LP_NO_RAST", FALSE) + + static void llvmpipe_destroy( struct pipe_context *pipe ) { struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); @@ -130,7 +134,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv ) /* FIXME: devise alternative to draw_texture_samplers */ - if (debug_get_bool_option( "LP_NO_RAST", FALSE )) + if (debug_get_option_lp_no_rast()) llvmpipe->no_rast = TRUE; llvmpipe->setup = lp_setup_create( &llvmpipe->pipe, diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index b2643ab33cd..50f9091c3ca 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -77,6 +77,7 @@ struct llvmpipe_context { struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_VERTEX_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_index_buffer index_buffer; struct { struct llvmpipe_resource *buffer[PIPE_MAX_SO_BUFFERS]; int offset[PIPE_MAX_SO_BUFFERS]; diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 625d0c8a8c9..e73b431cb4d 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -49,20 +49,11 @@ * the drawing to the 'draw' module. */ static void -llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) +llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct llvmpipe_context *lp = llvmpipe_context(pipe); struct draw_context *draw = lp->draw; + void *mapped_indices = NULL; unsigned i; if (lp->dirty) @@ -77,27 +68,25 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe, } /* Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes = llvmpipe_resource_data(indexBuffer); - draw_set_mapped_element_buffer_range(draw, - indexSize, - indexBias, - minIndex, - maxIndex, - mapped_indexes); - } - else { - /* no index/element buffer */ - draw_set_mapped_element_buffer_range(draw, 0, 0, start, - start + count - 1, NULL); + if (info->indexed && lp->index_buffer.buffer) { + char *indices = (char *) llvmpipe_resource_data(lp->index_buffer.buffer); + mapped_indices = (void *) (indices + lp->index_buffer.offset); } + + draw_set_mapped_element_buffer_range(draw, (mapped_indices) ? + lp->index_buffer.index_size : 0, + info->index_bias, + info->min_index, + info->max_index, + mapped_indices); + llvmpipe_prepare_vertex_sampling(lp, lp->num_vertex_sampler_views, lp->vertex_sampler_views); /* draw! */ - draw_arrays_instanced(draw, mode, start, count, - startInstance, instanceCount); + draw_arrays_instanced(draw, info->mode, info->start, info->count, + info->start_instance, info->instance_count); /* * unmap vertex/index buffers @@ -105,7 +94,7 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe, for (i = 0; i < lp->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); } - if (indexBuffer) { + if (mapped_indices) { draw_set_mapped_element_buffer(draw, 0, 0, NULL); } llvmpipe_cleanup_vertex_sampling(lp); @@ -119,112 +108,8 @@ llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe, } -static void -llvmpipe_draw_arrays_instanced(struct pipe_context *pipe, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) -{ - llvmpipe_draw_range_elements_instanced(pipe, - NULL, /* no indexBuffer */ - 0, 0, /* indexSize, indexBias */ - 0, ~0, /* minIndex, maxIndex */ - mode, - start, - count, - startInstance, - instanceCount); -} - - -static void -llvmpipe_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) -{ - llvmpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, indexBias, - 0, ~0, /* minIndex, maxIndex */ - mode, - start, - count, - startInstance, - instanceCount); -} - - -static void -llvmpipe_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, - unsigned start, - unsigned count) -{ - llvmpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, indexBias, - 0, 0xffffffff, /* min, maxIndex */ - mode, start, count, - 0, /* startInstance */ - 1); /* instanceCount */ -} - - -static void -llvmpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned min_index, - unsigned max_index, - unsigned mode, - unsigned start, - unsigned count) -{ - llvmpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, indexBias, - min_index, max_index, - mode, start, count, - 0, /* startInstance */ - 1); /* instanceCount */ -} - - -static void -llvmpipe_draw_arrays(struct pipe_context *pipe, - unsigned mode, - unsigned start, - unsigned count) -{ - llvmpipe_draw_range_elements_instanced(pipe, - NULL, /* indexBuffer */ - 0, /* indexSize */ - 0, /* indexBias */ - 0, ~0, /* min, maxIndex */ - mode, start, count, - 0, /* startInstance */ - 1); /* instanceCount */ -} - - void llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe) { - llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays; - llvmpipe->pipe.draw_elements = llvmpipe_draw_elements; - llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements; - llvmpipe->pipe.draw_arrays_instanced = llvmpipe_draw_arrays_instanced; - llvmpipe->pipe.draw_elements_instanced = llvmpipe_draw_elements_instanced; + llvmpipe->pipe.draw_vbo = llvmpipe_draw_vbo; } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index 654f4ea48eb..3215d0f6525 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -43,6 +43,12 @@ #include "lp_scene.h" +#ifdef DEBUG +int jit_line = 0; +const struct lp_rast_state *jit_state = NULL; +#endif + + /** * Begin rasterizing a scene. * Called once per scene by one thread. @@ -368,14 +374,15 @@ lp_rast_store_linear_color( struct lp_rasterizer_task *task, for (buf = 0; buf < rast->state.nr_cbufs; buf++) { struct pipe_surface *cbuf = scene->fb.cbufs[buf]; - const unsigned face = cbuf->face, level = cbuf->level; + const unsigned face_slice = cbuf->face + cbuf->zslice; + const unsigned level = cbuf->level; struct llvmpipe_resource *lpt = llvmpipe_resource(cbuf->texture); if (!task->color_tiles[buf]) continue; llvmpipe_unswizzle_cbuf_tile(lpt, - face, + face_slice, level, task->x, task->y, task->color_tiles[buf]); @@ -418,6 +425,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task, depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y); /* run shader on 4x4 block */ + BEGIN_JIT_CALL(state); variant->jit_function[RAST_WHOLE]( &state->jit_context, tile_x + x, tile_y + y, inputs->facing, @@ -428,6 +436,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task, depth, 0xffff, &task->vis_counter); + END_JIT_CALL(); } } } @@ -497,6 +506,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, assert(lp_check_alignment(state->jit_context.blend_color, 16)); /* run shader on 4x4 block */ + BEGIN_JIT_CALL(state); variant->jit_function[RAST_EDGE_TEST](&state->jit_context, x, y, inputs->facing, @@ -507,6 +517,7 @@ lp_rast_shade_quads_mask(struct lp_rasterizer_task *task, depth, mask, &task->vis_counter); + END_JIT_CALL(); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h index eaf2a6f3345..44319a0ad6f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.h +++ b/src/gallium/drivers/llvmpipe/lp_rast.h @@ -104,9 +104,6 @@ struct lp_rast_plane { int dcdx; int dcdy; - - /* edge/step info for 3 edges and 4x4 block of pixels */ - const int *step; }; /** @@ -119,8 +116,6 @@ struct lp_rast_triangle { /* inputs for the shader */ struct lp_rast_shader_inputs inputs; - int step[3][16]; - #ifdef DEBUG float v[3][2]; #endif diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h index b4a48cfd024..fae7f6d3dc2 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h @@ -40,6 +40,34 @@ #include "lp_limits.h" +/* If we crash in a jitted function, we can examine jit_line and jit_state + * to get some info. This is not thread-safe, however. + */ +#ifdef DEBUG + +extern int jit_line; +extern const struct lp_rast_state *jit_state; + +#define BEGIN_JIT_CALL(state) \ + do { \ + jit_line = __LINE__; \ + jit_state = state; \ + } while (0) + +#define END_JIT_CALL() \ + do { \ + jit_line = 0; \ + jit_state = NULL; \ + } while (0) + +#else + +#define BEGIN_JIT_CALL(X) +#define END_JIT_CALL() + +#endif + + struct lp_rasterizer; @@ -249,6 +277,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task, depth = lp_rast_get_depth_block_pointer(task, x, y); /* run shader on 4x4 block */ + BEGIN_JIT_CALL(state); variant->jit_function[RAST_WHOLE]( &state->jit_context, x, y, inputs->facing, @@ -259,6 +288,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task, depth, 0xffff, &task->vis_counter ); + END_JIT_CALL(); } diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index ebe9a8e92b4..980c18c0240 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -37,52 +37,6 @@ #include "lp_tile_soa.h" -/** - * Map an index in [0,15] to an x,y position, multiplied by 4. - * This is used to get the position of each subtile in a 4x4 - * grid of edge step values. - * Note: we can use some bit twiddling to compute these values instead - * of using a look-up table, but there's no measurable performance - * difference. - */ -static const int pos_table4[16][2] = { - { 0, 0 }, - { 4, 0 }, - { 0, 4 }, - { 4, 4 }, - { 8, 0 }, - { 12, 0 }, - { 8, 4 }, - { 12, 4 }, - { 0, 8 }, - { 4, 8 }, - { 0, 12 }, - { 4, 12 }, - { 8, 8 }, - { 12, 8 }, - { 8, 12 }, - { 12, 12 } -}; - - -static const int pos_table16[16][2] = { - { 0, 0 }, - { 16, 0 }, - { 0, 16 }, - { 16, 16 }, - { 32, 0 }, - { 48, 0 }, - { 32, 16 }, - { 48, 16 }, - { 0, 32 }, - { 16, 32 }, - { 0, 48 }, - { 16, 48 }, - { 32, 32 }, - { 48, 32 }, - { 32, 48 }, - { 48, 48 } -}; /** @@ -113,6 +67,68 @@ block_full_16(struct lp_rasterizer_task *task, block_full_4(task, tri, x + ix, y + iy); } + +static INLINE unsigned +build_mask(int c, int dcdx, int dcdy) +{ + int mask = 0; + + int c0 = c; + int c1 = c0 + dcdx; + int c2 = c1 + dcdx; + int c3 = c2 + dcdx; + + mask |= ((c0 + 0 * dcdy) >> 31) & (1 << 0); + mask |= ((c0 + 1 * dcdy) >> 31) & (1 << 2); + mask |= ((c0 + 2 * dcdy) >> 31) & (1 << 8); + mask |= ((c0 + 3 * dcdy) >> 31) & (1 << 10); + mask |= ((c1 + 0 * dcdy) >> 31) & (1 << 1); + mask |= ((c1 + 1 * dcdy) >> 31) & (1 << 3); + mask |= ((c1 + 2 * dcdy) >> 31) & (1 << 9); + mask |= ((c1 + 3 * dcdy) >> 31) & (1 << 11); + mask |= ((c2 + 0 * dcdy) >> 31) & (1 << 4); + mask |= ((c2 + 1 * dcdy) >> 31) & (1 << 6); + mask |= ((c2 + 2 * dcdy) >> 31) & (1 << 12); + mask |= ((c2 + 3 * dcdy) >> 31) & (1 << 14); + mask |= ((c3 + 0 * dcdy) >> 31) & (1 << 5); + mask |= ((c3 + 1 * dcdy) >> 31) & (1 << 7); + mask |= ((c3 + 2 * dcdy) >> 31) & (1 << 13); + mask |= ((c3 + 3 * dcdy) >> 31) & (1 << 15); + + return mask; +} + +static INLINE unsigned +build_mask_linear(int c, int dcdx, int dcdy) +{ + int mask = 0; + + int c0 = c; + int c1 = c0 + dcdy; + int c2 = c1 + dcdy; + int c3 = c2 + dcdy; + + mask |= ((c0 + 0 * dcdx) >> 31) & (1 << 0); + mask |= ((c0 + 1 * dcdx) >> 31) & (1 << 1); + mask |= ((c0 + 2 * dcdx) >> 31) & (1 << 2); + mask |= ((c0 + 3 * dcdx) >> 31) & (1 << 3); + mask |= ((c1 + 0 * dcdx) >> 31) & (1 << 4); + mask |= ((c1 + 1 * dcdx) >> 31) & (1 << 5); + mask |= ((c1 + 2 * dcdx) >> 31) & (1 << 6); + mask |= ((c1 + 3 * dcdx) >> 31) & (1 << 7); + mask |= ((c2 + 0 * dcdx) >> 31) & (1 << 8); + mask |= ((c2 + 1 * dcdx) >> 31) & (1 << 9); + mask |= ((c2 + 2 * dcdx) >> 31) & (1 << 10); + mask |= ((c2 + 3 * dcdx) >> 31) & (1 << 11); + mask |= ((c3 + 0 * dcdx) >> 31) & (1 << 12); + mask |= ((c3 + 1 * dcdx) >> 31) & (1 << 13); + mask |= ((c3 + 2 * dcdx) >> 31) & (1 << 14); + mask |= ((c3 + 3 * dcdx) >> 31) & (1 << 15); + + return mask; +} + + #define TAG(x) x##_1 #define NR_PLANES 1 #include "lp_rast_tri_tmp.h" diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h b/src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h index a410c611a3f..43f72d8ca8f 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h @@ -46,19 +46,13 @@ TAG(do_block_4)(struct lp_rasterizer_task *task, int x, int y, const int *c) { - unsigned mask = 0; - int i; + unsigned mask = 0xffff; + int j; - for (i = 0; i < 16; i++) { - int any_negative = 0; - int j; - - for (j = 0; j < NR_PLANES; j++) - any_negative |= (c[j] - 1 + plane[j].step[i]); - - any_negative >>= 31; - - mask |= (~any_negative) & (1 << i); + for (j = 0; j < NR_PLANES; j++) { + mask &= ~build_mask(c[j] - 1, + -plane[j].dcdx, + plane[j].dcdy); } /* Now pass to the shader: @@ -79,24 +73,19 @@ TAG(do_block_16)(struct lp_rasterizer_task *task, const int *c) { unsigned outmask, inmask, partmask, partial_mask; - unsigned i, j; + unsigned j; outmask = 0; /* outside one or more trivial reject planes */ partmask = 0; /* outside one or more trivial accept planes */ for (j = 0; j < NR_PLANES; j++) { - const int *step = plane[j].step; - const int eo = plane[j].eo * 4; - const int ei = plane[j].ei * 4; - const int cox = c[j] + eo; - const int cio = ei - 1 - eo; - - for (i = 0; i < 16; i++) { - int out = cox + step[i] * 4; - int part = out + cio; - outmask |= (out >> 31) & (1 << i); - partmask |= (part >> 31) & (1 << i); - } + const int dcdx = -plane[j].dcdx * 4; + const int dcdy = plane[j].dcdy * 4; + const int cox = c[j] + plane[j].eo * 4; + const int cio = c[j] + plane[j].ei * 4 - 1; + + outmask |= build_mask_linear(cox, dcdx, dcdy); + partmask |= build_mask_linear(cio, dcdx, dcdy); } if (outmask == 0xffff) @@ -117,15 +106,19 @@ TAG(do_block_16)(struct lp_rasterizer_task *task, */ while (partial_mask) { int i = ffs(partial_mask) - 1; - int px = x + pos_table4[i][0]; - int py = y + pos_table4[i][1]; + int ix = (i & 3) * 4; + int iy = (i >> 2) * 4; + int px = x + ix; + int py = y + iy; int cx[NR_PLANES]; - for (j = 0; j < NR_PLANES; j++) - cx[j] = c[j] + plane[j].step[i] * 4; - partial_mask &= ~(1 << i); + for (j = 0; j < NR_PLANES; j++) + cx[j] = (c[j] + - plane[j].dcdx * ix + + plane[j].dcdy * iy); + TAG(do_block_4)(task, tri, plane, px, py, cx); } @@ -133,8 +126,10 @@ TAG(do_block_16)(struct lp_rasterizer_task *task, */ while (inmask) { int i = ffs(inmask) - 1; - int px = x + pos_table4[i][0]; - int py = y + pos_table4[i][1]; + int ix = (i & 3) * 4; + int iy = (i >> 2) * 4; + int px = x + ix; + int py = y + iy; inmask &= ~(1 << i); @@ -157,35 +152,28 @@ TAG(lp_rast_triangle)(struct lp_rasterizer_task *task, struct lp_rast_plane plane[NR_PLANES]; int c[NR_PLANES]; unsigned outmask, inmask, partmask, partial_mask; - unsigned i, j, nr_planes = 0; + unsigned j = 0; + + outmask = 0; /* outside one or more trivial reject planes */ + partmask = 0; /* outside one or more trivial accept planes */ while (plane_mask) { int i = ffs(plane_mask) - 1; - plane[nr_planes] = tri->plane[i]; + plane[j] = tri->plane[i]; plane_mask &= ~(1 << i); - nr_planes++; - }; - - assert(nr_planes == NR_PLANES); - outmask = 0; /* outside one or more trivial reject planes */ - partmask = 0; /* outside one or more trivial accept planes */ + c[j] = plane[j].c + plane[j].dcdy * y - plane[j].dcdx * x; - for (j = 0; j < NR_PLANES; j++) { - const int *step = plane[j].step; - const int eo = plane[j].eo * 16; - const int ei = plane[j].ei * 16; - int cox, cio; + { + const int dcdx = -plane[j].dcdx * 16; + const int dcdy = plane[j].dcdy * 16; + const int cox = c[j] + plane[j].eo * 16; + const int cio = c[j] + plane[j].ei * 16 - 1; - c[j] = plane[j].c + plane[j].dcdy * y - plane[j].dcdx * x; - cox = c[j] + eo; - cio = ei - 1 - eo; - - for (i = 0; i < 16; i++) { - int out = cox + step[i] * 16; - int part = out + cio; - outmask |= (out >> 31) & (1 << i); - partmask |= (part >> 31) & (1 << i); + outmask |= build_mask_linear(cox, dcdx, dcdy); + partmask |= build_mask_linear(cio, dcdx, dcdy); } + + j++; } if (outmask == 0xffff) @@ -206,12 +194,16 @@ TAG(lp_rast_triangle)(struct lp_rasterizer_task *task, */ while (partial_mask) { int i = ffs(partial_mask) - 1; - int px = x + pos_table16[i][0]; - int py = y + pos_table16[i][1]; + int ix = (i & 3) * 16; + int iy = (i >> 2) * 16; + int px = x + ix; + int py = y + iy; int cx[NR_PLANES]; for (j = 0; j < NR_PLANES; j++) - cx[j] = c[j] + plane[j].step[i] * 16; + cx[j] = (c[j] + - plane[j].dcdx * ix + + plane[j].dcdy * iy); partial_mask &= ~(1 << i); @@ -223,8 +215,10 @@ TAG(lp_rast_triangle)(struct lp_rasterizer_task *task, */ while (inmask) { int i = ffs(inmask) - 1; - int px = x + pos_table16[i][0]; - int py = y + pos_table16[i][1]; + int ix = (i & 3) * 16; + int iy = (i >> 2) * 16; + int px = x + ix; + int py = y + iy; inmask &= ~(1 << i); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 7e432503c12..393533ebee4 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -61,36 +61,6 @@ struct tri_info { -static const int step_scissor_minx[16] = { - 0, 1, 0, 1, - 2, 3, 2, 3, - 0, 1, 0, 1, - 2, 3, 2, 3 -}; - -static const int step_scissor_maxx[16] = { - 0, -1, 0, -1, - -2, -3, -2, -3, - 0, -1, 0, -1, - -2, -3, -2, -3 -}; - -static const int step_scissor_miny[16] = { - 0, 0, 1, 1, - 0, 0, 1, 1, - 2, 2, 3, 3, - 2, 2, 3, 3 -}; - -static const int step_scissor_maxy[16] = { - 0, 0, -1, -1, - 0, 0, -1, -1, - -2, -2, -3, -3, - -2, -2, -3, -3 -}; - - - static INLINE int subpixel_snap(float a) @@ -260,13 +230,13 @@ static void setup_tri_coefficients( struct lp_setup_context *setup, { unsigned fragcoord_usage_mask = TGSI_WRITEMASK_XYZ; unsigned slot; + unsigned i; /* setup interpolation for all the remaining attributes: */ for (slot = 0; slot < setup->fs.nr_inputs; slot++) { unsigned vert_attr = setup->fs.input[slot].src_index; unsigned usage_mask = setup->fs.input[slot].usage_mask; - unsigned i; switch (setup->fs.input[slot].interp) { case LP_INTERP_CONSTANT: @@ -316,6 +286,34 @@ static void setup_tri_coefficients( struct lp_setup_context *setup, /* The internal position input is in slot zero: */ setup_fragcoord_coef(tri, info, 0, fragcoord_usage_mask); + + if (0) { + for (i = 0; i < NUM_CHANNELS; i++) { + float a0 = tri->inputs.a0 [0][i]; + float dadx = tri->inputs.dadx[0][i]; + float dady = tri->inputs.dady[0][i]; + + debug_printf("POS.%c: a0 = %f, dadx = %f, dady = %f\n", + "xyzw"[i], + a0, dadx, dady); + } + + for (slot = 0; slot < setup->fs.nr_inputs; slot++) { + unsigned usage_mask = setup->fs.input[slot].usage_mask; + for (i = 0; i < NUM_CHANNELS; i++) { + if (usage_mask & (1 << i)) { + float a0 = tri->inputs.a0 [1 + slot][i]; + float dadx = tri->inputs.dadx[1 + slot][i]; + float dady = tri->inputs.dady[1 + slot][i]; + + debug_printf("IN[%u].%c: a0 = %f, dadx = %f, dady = %f\n", + slot, + "xyzw"[i], + a0, dadx, dady); + } + } + } + } } @@ -525,7 +523,7 @@ do_triangle_ccw(struct lp_setup_context *setup, info.dx20 = info.v2[0][0] - info.v0[0][0]; info.dy01 = info.v0[0][1] - info.v1[0][1]; info.dy20 = info.v2[0][1] - info.v0[0][1]; - info.oneoverarea = 1.0 / (info.dx01 * info.dy20 - info.dx20 * info.dy01); + info.oneoverarea = 1.0f / (info.dx01 * info.dy20 - info.dx20 * info.dy01); info.frontfacing = frontfacing; /* Setup parameter interpolants: @@ -590,35 +588,6 @@ do_triangle_ccw(struct lp_setup_context *setup, /* Calculate trivial accept offsets from the above. */ plane->ei = plane->dcdy - plane->dcdx - plane->eo; - - plane->step = tri->step[i]; - - /* Fill in the inputs.step[][] arrays. - * We've manually unrolled some loops here. - */ -#define SETUP_STEP(j, x, y) \ - tri->step[i][j] = y * plane->dcdy - x * plane->dcdx - - SETUP_STEP(0, 0, 0); - SETUP_STEP(1, 1, 0); - SETUP_STEP(2, 0, 1); - SETUP_STEP(3, 1, 1); - - SETUP_STEP(4, 2, 0); - SETUP_STEP(5, 3, 0); - SETUP_STEP(6, 2, 1); - SETUP_STEP(7, 3, 1); - - SETUP_STEP(8, 0, 2); - SETUP_STEP(9, 1, 2); - SETUP_STEP(10, 0, 3); - SETUP_STEP(11, 1, 3); - - SETUP_STEP(12, 2, 2); - SETUP_STEP(13, 3, 2); - SETUP_STEP(14, 2, 3); - SETUP_STEP(15, 3, 3); -#undef STEP } @@ -641,28 +610,24 @@ do_triangle_ccw(struct lp_setup_context *setup, * these planes elsewhere. */ if (nr_planes == 7) { - tri->plane[3].step = step_scissor_minx; tri->plane[3].dcdx = -1; tri->plane[3].dcdy = 0; tri->plane[3].c = 1-minx; tri->plane[3].ei = 0; tri->plane[3].eo = 1; - tri->plane[4].step = step_scissor_maxx; tri->plane[4].dcdx = 1; tri->plane[4].dcdy = 0; tri->plane[4].c = maxx; tri->plane[4].ei = -1; tri->plane[4].eo = 0; - tri->plane[5].step = step_scissor_miny; tri->plane[5].dcdx = 0; tri->plane[5].dcdy = 1; tri->plane[5].c = 1-miny; tri->plane[5].ei = 0; tri->plane[5].eo = 1; - tri->plane[6].step = step_scissor_maxy; tri->plane[6].dcdx = 0; tri->plane[6].dcdy = -1; tri->plane[6].c = maxy; diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 5953d690a41..dbca49a2efa 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -75,6 +75,7 @@ #include "gallivm/lp_bld_type.h" #include "gallivm/lp_bld_const.h" #include "gallivm/lp_bld_conv.h" +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_intr.h" #include "gallivm/lp_bld_logic.h" #include "gallivm/lp_bld_tgsi.h" @@ -676,6 +677,11 @@ generate_fragment(struct llvmpipe_context *lp, color_ptr); } +#ifdef PIPE_ARCH_X86 + /* Avoid corrupting the FPU stack on 32bit OSes. */ + lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); +#endif + LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); @@ -710,6 +716,7 @@ generate_fragment(struct llvmpipe_context *lp, if (gallivm_debug & GALLIVM_DEBUG_ASM) { lp_disassemble(f); } + lp_func_delete_body(function); } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c index 113f13db018..d86e66b4fb8 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_vertex.c +++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c @@ -89,6 +89,19 @@ llvmpipe_set_vertex_buffers(struct pipe_context *pipe, } +static void +llvmpipe_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + if (ib) + memcpy(&llvmpipe->index_buffer, ib, sizeof(llvmpipe->index_buffer)); + else + memset(&llvmpipe->index_buffer, 0, sizeof(llvmpipe->index_buffer)); + + /* TODO make this more like a state */ +} void llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe) @@ -98,4 +111,5 @@ llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe) llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state; llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers; + llvmpipe->pipe.set_index_buffer = llvmpipe_set_index_buffer; } diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c index 0c955556551..d0389f0cb0b 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c @@ -37,6 +37,7 @@ */ +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_type.h" #include "gallivm/lp_bld_debug.h" #include "lp_bld_blend.h" @@ -485,8 +486,7 @@ test_one(unsigned verbose, { LLVMModuleRef module = NULL; LLVMValueRef func = NULL; - LLVMExecutionEngineRef engine = NULL; - LLVMModuleProviderRef provider = NULL; + LLVMExecutionEngineRef engine = lp_build_engine; LLVMPassManagerRef pass = NULL; char *error = NULL; blend_test_ptr_t blend_test_ptr; @@ -510,15 +510,6 @@ test_one(unsigned verbose, } LLVMDisposeMessage(error); - provider = LLVMCreateModuleProviderForExistingModule(module); - if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { - if(verbose < 1) - dump_blend_type(stderr, blend, mode, type); - fprintf(stderr, "%s\n", error); - LLVMDisposeMessage(error); - abort(); - } - #if 0 pass = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); @@ -735,7 +726,6 @@ test_one(unsigned verbose, LLVMFreeMachineCodeForFunction(engine, func); - LLVMDisposeExecutionEngine(engine); if(pass) LLVMDisposePassManager(pass); diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c index cf41b40581f..3ba42bf11a6 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_conv.c +++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c @@ -35,6 +35,7 @@ #include "util/u_pointer.h" +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_type.h" #include "gallivm/lp_bld_const.h" #include "gallivm/lp_bld_conv.h" @@ -152,8 +153,7 @@ test_one(unsigned verbose, { LLVMModuleRef module = NULL; LLVMValueRef func = NULL; - LLVMExecutionEngineRef engine = NULL; - LLVMModuleProviderRef provider = NULL; + LLVMExecutionEngineRef engine = lp_build_engine; LLVMPassManagerRef pass = NULL; char *error = NULL; conv_test_ptr_t conv_test_ptr; @@ -203,15 +203,6 @@ test_one(unsigned verbose, } LLVMDisposeMessage(error); - provider = LLVMCreateModuleProviderForExistingModule(module); - if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { - if(verbose < 1) - dump_conv_types(stderr, src_type, dst_type); - fprintf(stderr, "%s\n", error); - LLVMDisposeMessage(error); - abort(); - } - #if 0 pass = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); @@ -351,7 +342,6 @@ test_one(unsigned verbose, LLVMFreeMachineCodeForFunction(engine, func); - LLVMDisposeExecutionEngine(engine); if(pass) LLVMDisposePassManager(pass); diff --git a/src/gallium/drivers/llvmpipe/lp_test_printf.c b/src/gallium/drivers/llvmpipe/lp_test_printf.c index 21df83f9d89..4653f30e39d 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_printf.c +++ b/src/gallium/drivers/llvmpipe/lp_test_printf.c @@ -31,6 +31,8 @@ #include "util/u_pointer.h" #include "gallivm/lp_bld.h" +#include "gallivm/lp_bld_init.h" +#include "gallivm/lp_bld_assert.h" #include "gallivm/lp_bld_printf.h" #include <llvm-c/Analysis.h> @@ -74,6 +76,10 @@ add_printf_test(LLVMModuleRef module) lp_build_printf(builder, "hello, world\n"); lp_build_printf(builder, "print 5 6: %d %d\n", LLVMConstInt(LLVMInt32Type(), 5, 0), LLVMConstInt(LLVMInt32Type(), 6, 0)); + + /* Also test lp_build_assert(). This should not fail. */ + lp_build_assert(builder, LLVMConstInt(LLVMInt32Type(), 1, 0), "assert(1)"); + LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); return func; @@ -107,11 +113,16 @@ test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase) LLVMDisposeMessage(error); provider = LLVMCreateModuleProviderForExistingModule(module); +#if 0 if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { fprintf(stderr, "%s\n", error); LLVMDisposeMessage(error); abort(); } +#else + (void) provider; + engine = lp_build_engine; +#endif #if 0 pass = LLVMCreatePassManager(); diff --git a/src/gallium/drivers/llvmpipe/lp_test_round.c b/src/gallium/drivers/llvmpipe/lp_test_round.c index f571a81a4a4..57b0ee57767 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_round.c +++ b/src/gallium/drivers/llvmpipe/lp_test_round.c @@ -31,7 +31,7 @@ #include "util/u_pointer.h" #include "gallivm/lp_bld.h" -#include "gallivm/lp_bld_printf.h" +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_arit.h" #include <llvm-c/Analysis.h> @@ -121,8 +121,7 @@ test_round(unsigned verbose, FILE *fp) { LLVMModuleRef module = NULL; LLVMValueRef test_round = NULL, test_trunc, test_floor, test_ceil; - LLVMExecutionEngineRef engine = NULL; - LLVMModuleProviderRef provider = NULL; + LLVMExecutionEngineRef engine = lp_build_engine; LLVMPassManagerRef pass = NULL; char *error = NULL; test_round_t round_func, trunc_func, floor_func, ceil_func; @@ -145,13 +144,6 @@ test_round(unsigned verbose, FILE *fp) } LLVMDisposeMessage(error); - provider = LLVMCreateModuleProviderForExistingModule(module); - if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { - fprintf(stderr, "%s\n", error); - LLVMDisposeMessage(error); - abort(); - } - #if 0 pass = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); diff --git a/src/gallium/drivers/llvmpipe/lp_test_sincos.c b/src/gallium/drivers/llvmpipe/lp_test_sincos.c index 1366ecddcbc..7ab357f162e 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_sincos.c +++ b/src/gallium/drivers/llvmpipe/lp_test_sincos.c @@ -30,8 +30,9 @@ #include <stdio.h> #include "gallivm/lp_bld.h" -#include "gallivm/lp_bld_printf.h" +#include "gallivm/lp_bld_init.h" #include "gallivm/lp_bld_arit.h" +#include "util/u_pointer.h" #include <llvm-c/Analysis.h> #include <llvm-c/ExecutionEngine.h> @@ -101,8 +102,7 @@ test_sincos(unsigned verbose, FILE *fp) { LLVMModuleRef module = NULL; LLVMValueRef test_sin = NULL, test_cos = NULL; - LLVMExecutionEngineRef engine = NULL; - LLVMModuleProviderRef provider = NULL; + LLVMExecutionEngineRef engine = lp_build_engine; LLVMPassManagerRef pass = NULL; char *error = NULL; test_sincos_t sin_func; @@ -122,13 +122,6 @@ test_sincos(unsigned verbose, FILE *fp) } LLVMDisposeMessage(error); - provider = LLVMCreateModuleProviderForExistingModule(module); - if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) { - fprintf(stderr, "%s\n", error); - LLVMDisposeMessage(error); - abort(); - } - #if 0 pass = LLVMCreatePassManager(); LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass); @@ -144,8 +137,8 @@ test_sincos(unsigned verbose, FILE *fp) (void)pass; #endif - sin_func = (test_sincos_t)LLVMGetPointerToGlobal(engine, test_sin); - cos_func = (test_sincos_t)LLVMGetPointerToGlobal(engine, test_cos); + sin_func = (test_sincos_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_sin)); + cos_func = (test_sincos_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_cos)); memset(unpacked, 0, sizeof unpacked); @@ -162,7 +155,6 @@ test_sincos(unsigned verbose, FILE *fp) LLVMFreeMachineCodeForFunction(engine, test_sin); LLVMFreeMachineCodeForFunction(engine, test_cos); - LLVMDisposeExecutionEngine(engine); if(pass) LLVMDisposePassManager(pass); diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.py b/src/gallium/drivers/llvmpipe/lp_tile_soa.py index c71ec8066c7..2ba39052aba 100644 --- a/src/gallium/drivers/llvmpipe/lp_tile_soa.py +++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.py @@ -293,34 +293,7 @@ def generate_ssse3(): print ''' #if defined(PIPE_ARCH_SSE) - -#if defined(PIPE_ARCH_SSSE3) - -#include <tmmintrin.h> - -#else - -#include <emmintrin.h> - -/** - * Describe _mm_shuffle_epi8() with gcc extended inline assembly, for cases - * where -mssse3 is not supported/enabled. - * - * MSVC will never get in here as its intrinsics support do not rely on - * compiler command line options. - */ -static __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__)) -_mm_shuffle_epi8(__m128i a, __m128i mask) -{ - __m128i result; - __asm__("pshufb %1, %0" - : "=x" (result) - : "xm" (mask), "0" (a)); - return result; -} - -#endif - +#include "util/u_sse.h" static void lp_tile_b8g8r8a8_unorm_swizzle_4ub_ssse3(uint8_t *dst, diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index f5c1c5ca2c3..e920cf9f3bc 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -151,9 +151,9 @@ so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr, if (so->start_alloc <= so->cur_start) { debug_printf("exceeding num_start size\n"); assert(0); - } else + } #endif /* DEBUG_NOUVEAU_STATEOBJ */ - start = so->start; + start = so->start; #ifdef DEBUG_NOUVEAU_STATEOBJ if (so->cur_start > 0 && start[so->cur_start - 1].size > so->cur) { @@ -162,7 +162,6 @@ so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr, } #endif /* DEBUG_NOUVEAU_STATEOBJ */ - so->start = start; start[so->cur_start].gr = gr; start[so->cur_start].mthd = mthd; start[so->cur_start].size = size; @@ -193,11 +192,10 @@ so_reloc(struct nouveau_stateobj *so, struct nouveau_bo *bo, if (so->reloc_alloc <= so->cur_reloc) { debug_printf("exceeding num_reloc size\n"); assert(0); - } else + } #endif /* DEBUG_NOUVEAU_STATEOBJ */ - r = so->reloc; + r = so->reloc; - so->reloc = r; r[so->cur_reloc].bo = NULL; nouveau_bo_ref(bo, &(r[so->cur_reloc].bo)); r[so->cur_reloc].gr = so->start[so->cur_start-1].gr; diff --git a/src/gallium/drivers/nouveau/nouveau_util.h b/src/gallium/drivers/nouveau/nouveau_util.h index a5e8537533e..b165f7a611a 100644 --- a/src/gallium/drivers/nouveau/nouveau_util.h +++ b/src/gallium/drivers/nouveau/nouveau_util.h @@ -88,104 +88,4 @@ static INLINE unsigned log2i(unsigned i) return r; } -struct u_split_prim { - void *priv; - void (*emit)(void *priv, unsigned start, unsigned count); - void (*edge)(void *priv, boolean enabled); - - unsigned mode; - unsigned start; - unsigned p_start; - unsigned p_end; - - uint repeat_first:1; - uint close_first:1; - uint edgeflag_off:1; -}; - -static INLINE void -u_split_prim_init(struct u_split_prim *s, - unsigned mode, unsigned start, unsigned count) -{ - if (mode == PIPE_PRIM_LINE_LOOP) { - s->mode = PIPE_PRIM_LINE_STRIP; - s->close_first = 1; - } else { - s->mode = mode; - s->close_first = 0; - } - s->start = start; - s->p_start = start; - s->p_end = start + count; - s->edgeflag_off = 0; - s->repeat_first = 0; -} - -static INLINE boolean -u_split_prim_next(struct u_split_prim *s, unsigned max_verts) -{ - int repeat = 0; - - if (s->repeat_first) { - s->emit(s->priv, s->start, 1); - max_verts--; - if (s->edgeflag_off) { - s->edge(s->priv, TRUE); - s->edgeflag_off = FALSE; - } - } - - if (s->p_start + s->close_first + max_verts >= s->p_end) { - s->emit(s->priv, s->p_start, s->p_end - s->p_start); - if (s->close_first) - s->emit(s->priv, s->start, 1); - return TRUE; - } - - switch (s->mode) { - case PIPE_PRIM_LINES: - max_verts &= ~1; - break; - case PIPE_PRIM_LINE_STRIP: - repeat = 1; - break; - case PIPE_PRIM_POLYGON: - max_verts--; - s->emit(s->priv, s->p_start, max_verts); - s->edge(s->priv, FALSE); - s->emit(s->priv, s->p_start + max_verts, 1); - s->p_start += max_verts; - s->repeat_first = TRUE; - s->edgeflag_off = TRUE; - return FALSE; - case PIPE_PRIM_TRIANGLES: - max_verts = max_verts - (max_verts % 3); - break; - case PIPE_PRIM_TRIANGLE_STRIP: - /* to ensure winding stays correct, always split - * on an even number of generated triangles - */ - max_verts = max_verts & ~1; - repeat = 2; - break; - case PIPE_PRIM_TRIANGLE_FAN: - s->repeat_first = TRUE; - repeat = 1; - break; - case PIPE_PRIM_QUADS: - max_verts &= ~3; - break; - case PIPE_PRIM_QUAD_STRIP: - max_verts &= ~1; - repeat = 2; - break; - default: - break; - } - - s->emit (s->priv, s->p_start, max_verts); - s->p_start += (max_verts - repeat); - return FALSE; -} - #endif diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h index df79ca89ca1..c6c93d40b8f 100644 --- a/src/gallium/drivers/nouveau/nouveau_winsys.h +++ b/src/gallium/drivers/nouveau/nouveau_winsys.h @@ -24,11 +24,10 @@ nouveau_screen_transfer_flags(unsigned pipe) flags |= NOUVEAU_BO_WR; if (pipe & PIPE_TRANSFER_DISCARD) flags |= NOUVEAU_BO_INVAL; - if (pipe & PIPE_TRANSFER_DONTBLOCK) - flags |= NOUVEAU_BO_NOWAIT; - else if (pipe & PIPE_TRANSFER_UNSYNCHRONIZED) flags |= NOUVEAU_BO_NOSYNC; + else if (pipe & PIPE_TRANSFER_DONTBLOCK) + flags |= NOUVEAU_BO_NOWAIT; return flags; } diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 915a9254025..0874cb5e4ea 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -82,10 +82,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv) nv50->pipe.destroy = nv50_destroy; - nv50->pipe.draw_arrays = nv50_draw_arrays; - nv50->pipe.draw_arrays_instanced = nv50_draw_arrays_instanced; - nv50->pipe.draw_elements = nv50_draw_elements; - nv50->pipe.draw_elements_instanced = nv50_draw_elements_instanced; + nv50->pipe.draw_vbo = nv50_draw_vbo; nv50->pipe.clear = nv50_clear; nv50->pipe.flush = nv50_flush; diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 12c4a93a9bd..d24d6c50ea8 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -148,6 +148,7 @@ struct nv50_context { struct pipe_resource *constbuf[PIPE_SHADER_TYPES]; struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned vtxbuf_nr; + struct pipe_index_buffer idxbuf; struct nv50_vtxelt_stateobj *vtxelt; struct nv50_sampler_stateobj *sampler[3][PIPE_MAX_SAMPLERS]; unsigned sampler_nr[3]; @@ -179,24 +180,8 @@ nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50); /* nv50_vbo.c */ -extern void nv50_draw_arrays(struct pipe_context *, unsigned mode, - unsigned start, unsigned count); -extern void nv50_draw_arrays_instanced(struct pipe_context *, unsigned mode, - unsigned start, unsigned count, - unsigned startInstance, - unsigned instanceCount); -extern void nv50_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, - unsigned count); -extern void nv50_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount); +extern void nv50_draw_vbo(struct pipe_context *pipe, + const struct pipe_draw_info *info); extern void nv50_vtxelt_construct(struct nv50_vtxelt_stateobj *cso); extern struct nouveau_stateobj *nv50_vbo_validate(struct nv50_context *nv50); diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c index 481182dd8df..0091927a982 100644 --- a/src/gallium/drivers/nv50/nv50_push.c +++ b/src/gallium/drivers/nv50/nv50_push.c @@ -2,8 +2,8 @@ #include "pipe/p_state.h" #include "util/u_inlines.h" #include "util/u_format.h" +#include "util/u_split_prim.h" -#include "nouveau/nouveau_util.h" #include "nv50_context.h" #include "nv50_resource.h" @@ -217,7 +217,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe, 4; /* potential edgeflag enable/disable */ const unsigned v_overhead = 1 + /* VERTEX_DATA packet header */ 2; /* potential edgeflag modification */ - struct u_split_prim s; + struct util_split_prim s; unsigned vtx_size; boolean nzi = FALSE; int i; @@ -335,7 +335,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe, ctx.attr[i].map = (uint8_t *)ctx.attr[i].map + ctx.attr[i].stride; } - u_split_prim_init(&s, mode, start, count); + util_split_prim_init(&s, mode, start, count); do { if (AVAIL_RING(chan) < p_overhead + (6 * vtx_size)) { FIRE_RING(chan); @@ -351,7 +351,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe, BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1 << 28) : 0)); - done = u_split_prim_next(&s, max_verts); + done = util_split_prim_next(&s, max_verts); BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); OUT_RING (chan, 0); } while (!done); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 88fee3630be..3afce06557a 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -786,6 +786,20 @@ nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count, nv50->dirty |= NV50_NEW_ARRAYS; } +static void +nv50_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + if (ib) + memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf)); + else + memset(&nv50->idxbuf, 0, sizeof(nv50->idxbuf)); + + /* TODO make this more like a state */ +} + static void * nv50_vtxelts_state_create(struct pipe_context *pipe, unsigned num_elements, @@ -871,5 +885,6 @@ nv50_init_state_functions(struct nv50_context *nv50) nv50->pipe.bind_vertex_elements_state = nv50_vtxelts_state_bind; nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers; + nv50->pipe.set_index_buffer = nv50_set_index_buffer; } diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 4fe0df5683d..d41a59d05db 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -24,8 +24,8 @@ #include "pipe/p_state.h" #include "util/u_inlines.h" #include "util/u_format.h" +#include "util/u_split_prim.h" -#include "nouveau/nouveau_util.h" #include "nv50_context.h" #include "nv50_resource.h" @@ -83,7 +83,7 @@ instance_step(struct nv50_context *nv50, struct instance *a) } } -void +static void nv50_draw_arrays_instanced(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count, unsigned startInstance, unsigned instanceCount) @@ -130,13 +130,6 @@ nv50_draw_arrays_instanced(struct pipe_context *pipe, } } -void -nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, - unsigned count) -{ - nv50_draw_arrays_instanced(pipe, mode, start, count, 0, 1); -} - struct inline_ctx { struct nv50_context *nv50; void *map; @@ -228,7 +221,7 @@ nv50_draw_elements_inline(struct pipe_context *pipe, struct pipe_transfer *transfer; struct instance a[16]; struct inline_ctx ctx; - struct u_split_prim s; + struct util_split_prim s; boolean nzi = FALSE; unsigned overhead; @@ -264,7 +257,7 @@ nv50_draw_elements_inline(struct pipe_context *pipe, unsigned max_verts; boolean done; - u_split_prim_init(&s, mode, start, count); + util_split_prim_init(&s, mode, start, count); do { if (AVAIL_RING(chan) < (overhead + 6)) { FIRE_RING(chan); @@ -283,7 +276,7 @@ nv50_draw_elements_inline(struct pipe_context *pipe, BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); OUT_RING (chan, nv50_prim(s.mode) | (nzi ? (1<<28) : 0)); - done = u_split_prim_next(&s, max_verts); + done = util_split_prim_next(&s, max_verts); BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); OUT_RING (chan, 0); } while (!done); @@ -294,7 +287,7 @@ nv50_draw_elements_inline(struct pipe_context *pipe, pipe_buffer_unmap(pipe, indexBuffer, transfer); } -void +static void nv50_draw_elements_instanced(struct pipe_context *pipe, struct pipe_resource *indexBuffer, unsigned indexSize, int indexBias, @@ -374,13 +367,34 @@ nv50_draw_elements_instanced(struct pipe_context *pipe, } void -nv50_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count) +nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { - nv50_draw_elements_instanced(pipe, indexBuffer, indexSize, indexBias, - mode, start, count, 0, 1); + struct nv50_context *nv50 = nv50_context(pipe); + + if (info->indexed && nv50->idxbuf.buffer) { + unsigned offset; + + assert(nv50->idxbuf.offset % nv50->idxbuf.index_size == 0); + offset = nv50->idxbuf.offset / nv50->idxbuf.index_size; + + nv50_draw_elements_instanced(pipe, + nv50->idxbuf.buffer, + nv50->idxbuf.index_size, + info->index_bias, + info->mode, + info->start + offset, + info->count, + info->start_instance, + info->instance_count); + } + else { + nv50_draw_arrays_instanced(pipe, + info->mode, + info->start, + info->count, + info->start_instance, + info->instance_count); + } } static INLINE boolean diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c index 6d2dc4d5bf6..7218abff22d 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.c +++ b/src/gallium/drivers/nvfx/nvfx_context.c @@ -55,8 +55,7 @@ nvfx_create(struct pipe_screen *pscreen, void *priv) nvfx->pipe.screen = pscreen; nvfx->pipe.priv = priv; nvfx->pipe.destroy = nvfx_destroy; - nvfx->pipe.draw_arrays = nvfx_draw_arrays; - nvfx->pipe.draw_elements = nvfx_draw_elements; + nvfx->pipe.draw_vbo = nvfx_draw_vbo; nvfx->pipe.clear = nvfx_clear; nvfx->pipe.flush = nvfx_flush; diff --git a/src/gallium/drivers/nvfx/nvfx_context.h b/src/gallium/drivers/nvfx/nvfx_context.h index e48f9f3aa88..89f94c10bd1 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.h +++ b/src/gallium/drivers/nvfx/nvfx_context.h @@ -121,7 +121,8 @@ struct nvfx_context { struct pipe_stencil_ref stencil_ref; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; - struct pipe_resource *idxbuf; + struct pipe_index_buffer idxbuf; + struct pipe_resource *idxbuf_buffer; unsigned idxbuf_format; struct nvfx_sampler_state *tex_sampler[PIPE_MAX_SAMPLERS]; struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; @@ -235,13 +236,8 @@ extern void nvfx_init_transfer_functions(struct nvfx_context *nvfx); /* nvfx_vbo.c */ extern boolean nvfx_vbo_validate(struct nvfx_context *nvfx); extern void nvfx_vbo_relocate(struct nvfx_context *nvfx); -extern void nvfx_draw_arrays(struct pipe_context *, unsigned mode, - unsigned start, unsigned count); -extern void nvfx_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, - unsigned count); +extern void nvfx_draw_vbo(struct pipe_context *pipe, + const struct pipe_draw_info *info); /* nvfx_vertprog.c */ extern boolean nvfx_vertprog_validate(struct nvfx_context *nvfx); diff --git a/src/gallium/drivers/nvfx/nvfx_fragprog.c b/src/gallium/drivers/nvfx/nvfx_fragprog.c index 6772d9bd516..ee41f03b9b8 100644 --- a/src/gallium/drivers/nvfx/nvfx_fragprog.c +++ b/src/gallium/drivers/nvfx/nvfx_fragprog.c @@ -842,7 +842,6 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx) struct nouveau_channel* chan = nvfx->screen->base.channel; struct nvfx_fragment_program *fp = nvfx->fragprog; int update = 0; - int i; if (!fp->translated) { @@ -895,6 +894,7 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx) { struct nvfx_fragment_program_bo* fpbo = os_malloc_aligned(sizeof(struct nvfx_fragment_program) + fp->prog_size * fp->progs_per_bo, 16); char *map, *buf; + int i; if(fp->fpbo) { @@ -910,7 +910,7 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx) map = fpbo->bo->map; buf = fpbo->insn; - for(int i = 0; i < fp->progs_per_bo; ++i) + for(i = 0; i < fp->progs_per_bo; ++i) { memcpy(buf, fp->insn, fp->insn_len * 4); nvfx_fp_memcpy(map, fp->insn, fp->insn_len * 4); @@ -931,6 +931,7 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx) uint32_t* map = pipe_buffer_map(&nvfx->pipe, constbuf, PIPE_TRANSFER_READ, &transfer); uint32_t* fpmap = (uint32_t*)((char*)fp->fpbo->bo->map + offset); uint32_t* buf = (uint32_t*)((char*)fp->fpbo->insn + offset); + int i; for (i = 0; i < fp->nr_consts; ++i) { unsigned off = fp->consts[i].offset; unsigned idx = fp->consts[i].index * 4; diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 80db28a07cb..f2525ccb38f 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -131,6 +131,8 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return screen->is_nv4x ? 1 : 0; case PIPE_CAP_GEOMETRY_SHADER4: return 0; + case PIPE_CAP_DEPTH_CLAMP: + return 0; // TODO: implement depth clamp default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/nvfx/nvfx_state.c b/src/gallium/drivers/nvfx/nvfx_state.c index 30322d46d93..cd58e439d71 100644 --- a/src/gallium/drivers/nvfx/nvfx_state.c +++ b/src/gallium/drivers/nvfx/nvfx_state.c @@ -555,6 +555,20 @@ nvfx_set_vertex_buffers(struct pipe_context *pipe, unsigned count, nvfx->draw_dirty |= NVFX_NEW_ARRAYS; } +static void +nvfx_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct nvfx_context *nvfx = nvfx_context(pipe); + + if (ib) + memcpy(&nvfx->idxbuf, ib, sizeof(nvfx->idxbuf)); + else + memset(&nvfx->idxbuf, 0, sizeof(nvfx->idxbuf)); + + /* TODO make this more like a state */ +} + static void * nvfx_vtxelts_state_create(struct pipe_context *pipe, unsigned num_elements, @@ -635,4 +649,5 @@ nvfx_init_state_functions(struct nvfx_context *nvfx) nvfx->pipe.bind_vertex_elements_state = nvfx_vtxelts_state_bind; nvfx->pipe.set_vertex_buffers = nvfx_set_vertex_buffers; + nvfx->pipe.set_index_buffer = nvfx_set_index_buffer; } diff --git a/src/gallium/drivers/nvfx/nvfx_vbo.c b/src/gallium/drivers/nvfx/nvfx_vbo.c index 520bae5aed2..4aa37938425 100644 --- a/src/gallium/drivers/nvfx/nvfx_vbo.c +++ b/src/gallium/drivers/nvfx/nvfx_vbo.c @@ -85,7 +85,7 @@ nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib, unsigned type; if (!ib) { - nvfx->idxbuf = NULL; + nvfx->idxbuf_buffer = NULL; nvfx->idxbuf_format = 0xdeadbeef; return FALSE; } @@ -104,10 +104,10 @@ nvfx_vbo_set_idxbuf(struct nvfx_context *nvfx, struct pipe_resource *ib, return FALSE; } - if (ib != nvfx->idxbuf || + if (ib != nvfx->idxbuf_buffer || type != nvfx->idxbuf_format) { nvfx->dirty |= NVFX_NEW_ARRAYS; - nvfx->idxbuf = ib; + nvfx->idxbuf_buffer = ib; nvfx->idxbuf_format = type; } @@ -158,7 +158,7 @@ nvfx_vbo_static_attrib(struct nvfx_context *nvfx, pipe_buffer_unmap(&nvfx->pipe, vb->buffer, transfer); } -void +static void nvfx_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start, unsigned count) { @@ -463,7 +463,7 @@ nvfx_draw_elements_vbo(struct pipe_context *pipe, } } -void +static void nvfx_draw_elements(struct pipe_context *pipe, struct pipe_resource *indexBuffer, unsigned indexSize, int indexBias, @@ -491,11 +491,38 @@ nvfx_draw_elements(struct pipe_context *pipe, pipe->flush(pipe, 0, NULL); } +void +nvfx_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) +{ + struct nvfx_context *nvfx = nvfx_context(pipe); + + if (info->indexed && nvfx->idxbuf.buffer) { + unsigned offset; + + assert(nvfx->idxbuf.offset % nvfx->idxbuf.index_size == 0); + offset = nvfx->idxbuf.offset / nvfx->idxbuf.index_size; + + nvfx_draw_elements(pipe, + nvfx->idxbuf.buffer, + nvfx->idxbuf.index_size, + info->index_bias, + info->mode, + info->start + offset, + info->count); + } + else { + nvfx_draw_arrays(pipe, + info->mode, + info->start, + info->count); + } +} + boolean nvfx_vbo_validate(struct nvfx_context *nvfx) { struct nouveau_channel* chan = nvfx->screen->base.channel; - struct pipe_resource *ib = nvfx->idxbuf; + struct pipe_resource *ib = nvfx->idxbuf_buffer; unsigned ib_format = nvfx->idxbuf_format; int i; int elements = MAX2(nvfx->vtxelt->num_elements, nvfx->hw_vtxelt_nr); @@ -610,10 +637,10 @@ nvfx_vbo_relocate(struct nvfx_context *nvfx) } } - if(nvfx->idxbuf) + if(nvfx->idxbuf_buffer) { unsigned ib_flags = nvfx->screen->index_buffer_reloc_flags | NOUVEAU_BO_RD | NOUVEAU_BO_DUMMY; - struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf)->bo; + struct nouveau_bo* bo = nvfx_resource(nvfx->idxbuf_buffer)->bo; assert(nvfx->screen->index_buffer_reloc_flags); diff --git a/src/gallium/drivers/nvfx/nvfx_vertprog.c b/src/gallium/drivers/nvfx/nvfx_vertprog.c index 80b98b62d34..24d9846310e 100644 --- a/src/gallium/drivers/nvfx/nvfx_vertprog.c +++ b/src/gallium/drivers/nvfx/nvfx_vertprog.c @@ -299,7 +299,13 @@ nvfx_vp_arith(struct nvfx_context* nvfx, struct nvfx_vpc *vpc, int slot, int op, (3 << NVFX_VP(INST_COND_SWZ_W_SHIFT))); if(!nvfx->is_nv4x) { - hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT); + if(slot == 0) + hw[1] |= (op << NV30_VP_INST_VEC_OPCODE_SHIFT); + else + { + hw[0] |= ((op >> 4) << NV30_VP_INST_SCA_OPCODEH_SHIFT); + hw[1] |= ((op & 0xf) << NV30_VP_INST_SCA_OPCODEL_SHIFT); + } // hw[3] |= NVFX_VP(INST_SCA_DEST_TEMP_MASK); // hw[3] |= (mask << NVFX_VP(INST_VEC_WRITEMASK_SHIFT)); diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile index 13152635a65..728bc40a5bb 100644 --- a/src/gallium/drivers/r300/Makefile +++ b/src/gallium/drivers/r300/Makefile @@ -24,6 +24,7 @@ C_SOURCES = \ r300_vs.c \ r300_vs_draw.c \ r300_texture.c \ + r300_texture_desc.c \ r300_tgsi_to_rc.c \ r300_transfer.c diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index 552ed4e5bef..bf023daaa56 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -34,6 +34,7 @@ r300 = env.ConvenienceLibrary( 'r300_vs.c', 'r300_vs_draw.c', 'r300_texture.c', + 'r300_texture_desc.c', 'r300_tgsi_to_rc.c', 'r300_transfer.c', ] + r300compiler) + r300compiler diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 895efaa1c4a..47ffc0cb3c6 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -21,7 +21,10 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "r300_context.h" +#include "r300_emit.h" +#include "r300_hyperz.h" #include "r300_texture.h" +#include "r300_winsys.h" #include "util/u_format.h" #include "util/u_pack_color.h" @@ -81,7 +84,7 @@ static void r300_blitter_end(struct r300_context *r300) } static uint32_t r300_depth_clear_cb_value(enum pipe_format format, - const float* rgba) + const float* rgba) { union util_color uc; util_pack_color(rgba, format, &uc); @@ -97,29 +100,29 @@ static boolean r300_cbzb_clear_allowed(struct r300_context *r300, { struct pipe_framebuffer_state *fb = (struct pipe_framebuffer_state*)r300->fb_state.state; - struct r300_surface *surf = r300_surface(fb->cbufs[0]); - unsigned bpp; /* Only color clear allowed, and only one colorbuffer. */ if (clear_buffers != PIPE_CLEAR_COLOR || fb->nr_cbufs != 1) return FALSE; - /* The colorbuffer must be point-sampled. */ - if (surf->base.texture->nr_samples > 1) - return FALSE; - - bpp = util_format_get_blocksizebits(surf->base.format); + return r300_surface(fb->cbufs[0])->cbzb_allowed; +} - /* ZB can only work with the two pixel sizes. */ - if (bpp != 16 && bpp != 32) - return FALSE; +static uint32_t r300_depth_clear_value(enum pipe_format format, + double depth, unsigned stencil) +{ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_X8Z24_UNORM: + return util_pack_z(format, depth); - /* If the midpoint ZB offset is not aligned to 2048, it returns garbage - * with certain texture sizes. Macrotiling ensures the alignment. */ - if (!r300_texture(surf->base.texture)->mip_macrotile[surf->base.level]) - return FALSE; + case PIPE_FORMAT_S8_USCALED_Z24_UNORM: + return util_pack_z_stencil(format, depth, stencil); - return TRUE; + default: + assert(0); + return 0; + } } /* Clear currently bound buffers. */ @@ -169,8 +172,27 @@ static void r300_clear(struct pipe_context* pipe, (struct pipe_framebuffer_state*)r300->fb_state.state; struct r300_hyperz_state *hyperz = (struct r300_hyperz_state*)r300->hyperz_state.state; + struct r300_texture *zstex = + fb->zsbuf ? r300_texture(fb->zsbuf->texture) : NULL; uint32_t width = fb->width; uint32_t height = fb->height; + boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + uint32_t hyperz_dcv = hyperz->zb_depthclearvalue; + + /* Enable fast Z clear. + * The zbuffer must be in micro-tiled mode, otherwise it locks up. */ + if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && has_hyperz) { + hyperz_dcv = hyperz->zb_depthclearvalue = + r300_depth_clear_value(fb->zsbuf->format, depth, stencil); + + r300_mark_fb_state_dirty(r300, R300_CHANGED_ZCLEAR_FLAG); + if (zstex->zmask_mem[fb->zsbuf->level]) { + r300->zmask_clear.dirty = TRUE; + buffers &= ~PIPE_CLEAR_DEPTHSTENCIL; + } + if (zstex->hiz_mem[fb->zsbuf->level]) + r300->hiz_clear.dirty = TRUE; + } /* Enable CBZB clear. */ if (r300_cbzb_clear_allowed(r300, buffers)) { @@ -187,20 +209,61 @@ static void r300_clear(struct pipe_context* pipe, } /* Clear. */ - r300_blitter_begin(r300, R300_CLEAR); - util_blitter_clear(r300->blitter, - width, - height, - fb->nr_cbufs, - buffers, rgba, depth, stencil); - r300_blitter_end(r300); + if (buffers) { + /* Clear using the blitter. */ + r300_blitter_begin(r300, R300_CLEAR); + util_blitter_clear(r300->blitter, + width, + height, + fb->nr_cbufs, + buffers, rgba, depth, stencil); + r300_blitter_end(r300); + } else if (r300->zmask_clear.dirty) { + /* Just clear zmask and hiz now, this does not use a standard draw + * procedure. */ + unsigned dwords; + + /* Calculate zmask_clear and hiz_clear atom sizes. */ + r300_update_hyperz_state(r300); + dwords = r300->zmask_clear.size + + (r300->hiz_clear.dirty ? r300->hiz_clear.size : 0) + + r300_get_num_cs_end_dwords(r300); + + /* Reserve CS space. */ + if (dwords > (r300->cs->ndw - r300->cs->cdw)) { + r300->context.flush(&r300->context, 0, NULL); + } + + /* Emit clear packets. */ + r300_emit_zmask_clear(r300, r300->zmask_clear.size, + r300->zmask_clear.state); + r300->zmask_clear.dirty = FALSE; + if (r300->hiz_clear.dirty) { + r300_emit_hiz_clear(r300, r300->hiz_clear.size, + r300->hiz_clear.state); + r300->hiz_clear.dirty = FALSE; + } + } else { + assert(0); + } /* Disable CBZB clear. */ if (r300->cbzb_clear) { r300->cbzb_clear = FALSE; + hyperz->zb_depthclearvalue = hyperz_dcv; r300_mark_fb_state_dirty(r300, R300_CHANGED_CBZB_FLAG); } + /* Enable fastfill and/or hiz. + * + * If we cleared zmask/hiz, it's in use now. The Hyper-Z state update + * looks if zmask/hiz is in use and enables fastfill accordingly. */ + if (zstex && + (zstex->zmask_in_use[fb->zsbuf->level] || + zstex->hiz_in_use[fb->zsbuf->level])) { + r300->hyperz_state.dirty = TRUE; + } + /* XXX this flush "fixes" a hardlock in the cubestorm xscreensaver */ if (r300->flush_counter == 0) pipe->flush(pipe, 0, NULL); @@ -238,6 +301,33 @@ static void r300_clear_depth_stencil(struct pipe_context *pipe, r300_blitter_end(r300); } +/* Flush a depth stencil buffer. */ +void r300_flush_depth_stencil(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned zslice) +{ + struct r300_context *r300 = r300_context(pipe); + struct pipe_surface *dstsurf; + struct r300_texture *tex = r300_texture(dst); + + if (!tex->zmask_mem[subdst.level]) + return; + if (!tex->zmask_in_use[subdst.level]) + return; + + dstsurf = pipe->screen->get_tex_surface(pipe->screen, dst, + subdst.face, subdst.level, zslice, + PIPE_BIND_DEPTH_STENCIL); + r300->z_decomp_rd = TRUE; + r300_blitter_begin(r300, R300_CLEAR_SURFACE); + util_blitter_flush_depth_stencil(r300->blitter, dstsurf); + r300_blitter_end(r300); + r300->z_decomp_rd = FALSE; + + tex->zmask_in_use[subdst.level] = FALSE; +} + /* Copy a block of pixels from one surface to another using HW. */ static void r300_hw_copy_region(struct pipe_context* pipe, struct pipe_resource *dst, @@ -269,7 +359,7 @@ static void r300_resource_copy_region(struct pipe_context *pipe, { enum pipe_format old_format = dst->format; enum pipe_format new_format = old_format; - + boolean is_depth; if (!pipe->screen->is_format_supported(pipe->screen, old_format, src->target, src->nr_samples, @@ -296,6 +386,10 @@ static void r300_resource_copy_region(struct pipe_context *pipe, } } + is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; + if (is_depth) { + r300_flush_depth_stencil(pipe, src, subsrc, srcz); + } if (old_format != new_format) { dst->format = new_format; src->format = new_format; diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c index 21f3b9d2610..48c24092114 100644 --- a/src/gallium/drivers/r300/r300_chipset.c +++ b/src/gallium/drivers/r300/r300_chipset.c @@ -36,7 +36,7 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->num_vert_fpus = 2; caps->num_tex_units = 16; caps->has_tcl = debug_get_bool_option("RADEON_NO_TCL", FALSE) ? FALSE : TRUE; - caps->has_hiz = TRUE; + caps->hiz_ram = 0; caps->is_r400 = FALSE; caps->is_r500 = FALSE; caps->high_second_pipe = FALSE; @@ -49,6 +49,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R300; caps->high_second_pipe = TRUE; caps->num_vert_fpus = 4; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x4145: @@ -61,6 +63,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R300; caps->high_second_pipe = TRUE; caps->num_vert_fpus = 4; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x4150: @@ -77,8 +81,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x4E54: case 0x4E56: caps->family = CHIP_FAMILY_RV350; - caps->has_hiz = FALSE; caps->high_second_pipe = TRUE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x4148: @@ -91,12 +95,16 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R350; caps->high_second_pipe = TRUE; caps->num_vert_fpus = 4; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x4E4A: caps->family = CHIP_FAMILY_R360; caps->high_second_pipe = TRUE; caps->num_vert_fpus = 4; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x5460: @@ -108,8 +116,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x5B64: case 0x5B65: caps->family = CHIP_FAMILY_RV370; - caps->has_hiz = FALSE; caps->high_second_pipe = TRUE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x3150: @@ -120,6 +128,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) case 0x3E54: caps->family = CHIP_FAMILY_RV380; caps->high_second_pipe = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x4A48: @@ -135,6 +145,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R420; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x5548: @@ -149,6 +161,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R423; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x554C: @@ -161,6 +175,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R430; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x5D4C: @@ -172,6 +188,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R480; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x4B48: @@ -182,6 +200,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R481; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x5E4C: @@ -199,34 +219,36 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RV410; caps->num_vert_fpus = 6; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x5954: case 0x5955: caps->family = CHIP_FAMILY_RS480; - caps->has_hiz = FALSE; caps->has_tcl = FALSE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x5974: case 0x5975: caps->family = CHIP_FAMILY_RS482; - caps->has_hiz = FALSE; caps->has_tcl = FALSE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x5A41: case 0x5A42: caps->family = CHIP_FAMILY_RS400; - caps->has_hiz = FALSE; caps->has_tcl = FALSE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x5A61: case 0x5A62: caps->family = CHIP_FAMILY_RC410; - caps->has_hiz = FALSE; caps->has_tcl = FALSE; + caps->zmask_ram = RV3xx_ZMASK_SIZE; break; case 0x791E: @@ -234,6 +256,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RS690; caps->has_tcl = FALSE; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x793F: @@ -242,6 +266,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RS600; caps->has_tcl = FALSE; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x796C: @@ -251,6 +277,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RS740; caps->has_tcl = FALSE; caps->is_r400 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x7100: @@ -270,6 +298,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R520; caps->num_vert_fpus = 8; caps->is_r500 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x7140: @@ -313,6 +343,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RV515; caps->num_vert_fpus = 2; caps->is_r500 = TRUE; + caps->hiz_ram = R300_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x71C0: @@ -334,6 +366,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RV530; caps->num_vert_fpus = 5; caps->is_r500 = TRUE; + /*caps->hiz_ram = RV530_HIZ_LIMIT;*/ + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x7240: @@ -354,12 +388,16 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_R580; caps->num_vert_fpus = 8; caps->is_r500 = TRUE; + caps->hiz_ram = RV530_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x7280: caps->family = CHIP_FAMILY_RV570; caps->num_vert_fpus = 8; caps->is_r500 = TRUE; + caps->hiz_ram = RV530_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; case 0x7281: @@ -376,6 +414,8 @@ void r300_parse_chipset(struct r300_capabilities* caps) caps->family = CHIP_FAMILY_RV560; caps->num_vert_fpus = 8; caps->is_r500 = TRUE; + caps->hiz_ram = RV530_HIZ_LIMIT; + caps->zmask_ram = PIPE_ZMASK_SIZE; break; default: diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h index 65750f54e71..e7ca642b4f3 100644 --- a/src/gallium/drivers/r300/r300_chipset.h +++ b/src/gallium/drivers/r300/r300_chipset.h @@ -25,6 +25,14 @@ #include "pipe/p_compiler.h" +/* these are sizes in dwords */ +#define R300_HIZ_LIMIT 10240 +#define RV530_HIZ_LIMIT 15360 + +/* rv3xx have only one pipe */ +#define PIPE_ZMASK_SIZE 4096 +#define RV3xx_ZMASK_SIZE 5120 + /* Structure containing all the possible information about a specific Radeon * in the R3xx, R4xx, and R5xx families. */ struct r300_capabilities { @@ -42,8 +50,10 @@ struct r300_capabilities { unsigned num_tex_units; /* Whether or not TCL is physically present */ boolean has_tcl; - /* Some chipsets do not have HiZ RAM. */ - boolean has_hiz; + /* Some chipsets do not have HiZ RAM - other have varying amounts . */ + int hiz_ram; + /* some chipsets have zmask ram per pipe some don't */ + int zmask_ram; /* Whether or not this is RV350 or newer, including all r400 and r500 * chipsets. The differences compared to the oldest r300 chips are: * - Blend LTE/GTE thresholds diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index df903590583..e8b6c4f7af8 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -30,6 +30,7 @@ #include "r300_cb.h" #include "r300_context.h" #include "r300_emit.h" +#include "r300_hyperz.h" #include "r300_screen.h" #include "r300_screen_buffer.h" #include "r300_winsys.h" @@ -114,6 +115,10 @@ static void r300_destroy_context(struct pipe_context* context) u_upload_destroy(r300->upload_vb); u_upload_destroy(r300->upload_ib); + /* setup hyper-z mm */ + if (r300->rws->get_value(r300->rws, R300_CAN_HYPERZ)) + r300_hyperz_destroy_mm(r300); + translate_cache_destroy(r300->tran.translate_cache); r300_release_referenced_objects(r300); @@ -166,6 +171,9 @@ static void r300_setup_atoms(struct r300_context* r300) boolean is_r500 = r300->screen->caps.is_r500; boolean has_tcl = r300->screen->caps.has_tcl; boolean drm_2_3_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); + boolean drm_2_6_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_6_0); + boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean has_hiz_ram = r300->screen->caps.hiz_ram > 0; /* Create the actual atom list. * @@ -188,8 +196,8 @@ static void r300_setup_atoms(struct r300_context* r300) R300_INIT_ATOM(gpu_flush, 9); R300_INIT_ATOM(aa_state, 4); R300_INIT_ATOM(fb_state, 0); + R300_INIT_ATOM(hyperz_state, is_r500 || (is_rv350 && drm_2_6_0) ? 10 : 8); /* ZB (unpipelined), SC. */ - R300_INIT_ATOM(hyperz_state, 6); R300_INIT_ATOM(ztop_state, 2); /* ZB, FG. */ R300_INIT_ATOM(dsa_state, is_r500 ? 8 : 6); @@ -220,6 +228,13 @@ static void r300_setup_atoms(struct r300_context* r300) /* TX. */ R300_INIT_ATOM(texture_cache_inval, 2); R300_INIT_ATOM(textures_state, 0); + if (has_hyperz) { + /* HiZ Clear */ + if (has_hiz_ram) + R300_INIT_ATOM(hiz_clear, 0); + /* zmask clear */ + R300_INIT_ATOM(zmask_clear, 0); + } /* ZB (unpipelined), SU. */ R300_INIT_ATOM(query_start, 4); @@ -282,8 +297,7 @@ static void r300_init_states(struct pipe_context *pipe) (struct r300_vap_invariant_state*)r300->vap_invariant_state.state; struct r300_invariant_state *invariant = (struct r300_invariant_state*)r300->invariant_state.state; - struct r300_hyperz_state *hyperz = - (struct r300_hyperz_state*)r300->hyperz_state.state; + CB_LOCALS; pipe->set_blend_color(pipe, &bc); @@ -351,10 +365,20 @@ static void r300_init_states(struct pipe_context *pipe) /* Initialize the hyperz state. */ { - BEGIN_CB(&hyperz->cb_begin, r300->hyperz_state.size); + struct r300_hyperz_state *hyperz = + (struct r300_hyperz_state*)r300->hyperz_state.state; + BEGIN_CB(&hyperz->cb_flush_begin, r300->hyperz_state.size); + OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT, + R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE); OUT_CB_REG(R300_ZB_BW_CNTL, 0); OUT_CB_REG(R300_ZB_DEPTHCLEARVALUE, 0); OUT_CB_REG(R300_SC_HYPERZ, R300_SC_HYPERZ_ADJ_2); + + if (r300->screen->caps.is_r500 || + (r300->screen->caps.is_rv350 && + r300->rws->get_value(r300->rws, R300_VID_DRM_2_6_0))) { + OUT_CB_REG(R300_GB_Z_PEQ_CONFIG, 0); + } END_CB; } } @@ -415,6 +439,10 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, rws->cs_set_flush(r300->cs, r300_flush_cb, r300); + /* setup hyper-z mm */ + if (r300->rws->get_value(r300->rws, R300_CAN_HYPERZ)) + r300_hyperz_init_mm(r300); + r300->upload_ib = u_upload_create(&r300->context, 32 * 1024, 16, PIPE_BIND_INDEX_BUFFER); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index b9c96d5bdd8..6fa7f470f98 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -106,13 +106,19 @@ struct r300_dsa_state { }; struct r300_hyperz_state { + int current_func; /* -1 after a clear before first op */ + int flush; /* This is actually a command buffer with named dwords. */ + uint32_t cb_flush_begin; + uint32_t zb_zcache_ctlstat; /* R300_ZB_CACHE_CNTL */ uint32_t cb_begin; uint32_t zb_bw_cntl; /* R300_ZB_BW_CNTL */ uint32_t cb_reg1; uint32_t zb_depthclearvalue; /* R300_ZB_DEPTHCLEARVALUE */ uint32_t cb_reg2; uint32_t sc_hyperz; /* R300_SC_HYPERZ */ + uint32_t cb_reg3; + uint32_t gb_z_peq_config; /* R300_GB_Z_PEQ_CONFIG: 0x4028 */ }; struct r300_gpu_flush { @@ -318,29 +324,39 @@ struct r300_surface { uint32_t cbzb_midpoint_offset; /* DEPTHOFFSET. */ uint32_t cbzb_pitch; /* DEPTHPITCH. */ uint32_t cbzb_format; /* ZB_FORMAT. */ + + /* Whether the CBZB clear is allowed on the surface. */ + boolean cbzb_allowed; + }; -struct r300_texture { - /* Parent class */ +struct r300_texture_desc { + /* Parent class. */ struct u_resource b; - enum r300_buffer_domain domain; + /* Buffer tiling. + * Macrotiling is specified per-level because small mipmaps cannot + * be macrotiled. */ + enum r300_buffer_tiling microtile; + enum r300_buffer_tiling macrotile[R300_MAX_TEXTURE_LEVELS]; /* Offsets into the buffer. */ - unsigned offset[R300_MAX_TEXTURE_LEVELS]; + unsigned offset_in_bytes[R300_MAX_TEXTURE_LEVELS]; - /* A pitch for each mip-level */ - unsigned pitch[R300_MAX_TEXTURE_LEVELS]; + /* Strides for each mip-level. */ + unsigned stride_in_pixels[R300_MAX_TEXTURE_LEVELS]; + unsigned stride_in_bytes[R300_MAX_TEXTURE_LEVELS]; - /* A pitch multiplied by blockwidth as hardware wants - * the number of pixels instead of the number of blocks. */ - unsigned hwpitch[R300_MAX_TEXTURE_LEVELS]; + /* Size of one zslice or face or 2D image based on the texture target. */ + unsigned layer_size_in_bytes[R300_MAX_TEXTURE_LEVELS]; - /* Size of one zslice or face based on the texture target */ - unsigned layer_size[R300_MAX_TEXTURE_LEVELS]; + /* Total size of this texture, in bytes, + * derived from the texture properties. */ + unsigned size_in_bytes; - /* Whether the mipmap level is macrotiled. */ - enum r300_buffer_tiling mip_macrotile[R300_MAX_TEXTURE_LEVELS]; + /* Total size of the buffer backing this texture, in bytes. + * It must be >= size. */ + unsigned buffer_size_in_bytes; /** * If non-zero, override the natural texture layout with @@ -350,16 +366,24 @@ struct r300_texture { * * \sa r300_texture_get_stride */ - unsigned stride_override; + unsigned stride_in_bytes_override; - /* Total size of this texture, in bytes. */ - unsigned size; + /* Whether this texture has non-power-of-two dimensions. + * It can be either a regular texture or a rectangle one. */ + boolean is_npot; - /* Whether this texture has non-power-of-two dimensions - * or a user-specified pitch. - * It can be either a regular texture or a rectangle one. - */ - boolean uses_pitch; + /* This flag says that hardware must use the stride for addressing + * instead of the width. */ + boolean uses_stride_addressing; + + /* Whether CBZB fast color clear is allowed on the miplevel. */ + boolean cbzb_allowed[R300_MAX_TEXTURE_LEVELS]; +}; + +struct r300_texture { + struct r300_texture_desc desc; + + enum r300_buffer_domain domain; /* Pipe buffer backing this texture. */ struct r300_winsys_buffer *buffer; @@ -370,8 +394,11 @@ struct r300_texture { /* All bits should be filled in. */ struct r300_texture_fb_state fb_state; - /* Buffer tiling */ - enum r300_buffer_tiling microtile, macrotile; + /* hyper-z memory allocs */ + struct mem_block *hiz_mem[R300_MAX_TEXTURE_LEVELS]; + struct mem_block *zmask_mem[R300_MAX_TEXTURE_LEVELS]; + boolean zmask_in_use[R300_MAX_TEXTURE_LEVELS]; + boolean hiz_in_use[R300_MAX_TEXTURE_LEVELS]; /* This is the level tiling flags were last time set for. * It's used to prevent redundant tiling-flags changes from happening.*/ @@ -498,6 +525,10 @@ struct r300_context { struct r300_atom texture_cache_inval; /* GPU flush. */ struct r300_atom gpu_flush; + /* HiZ clear */ + struct r300_atom hiz_clear; + /* zmask clear */ + struct r300_atom zmask_clear; /* Invariant state. This must be emitted to get the engine started. */ struct r300_atom invariant_state; @@ -510,6 +541,8 @@ struct r300_context { struct r300_vertex_element_state *velems; bool any_user_vbs; + struct pipe_index_buffer index_buffer; + /* Vertex info for Draw. */ struct vertex_info vertex_info; @@ -533,8 +566,16 @@ struct r300_context { boolean two_sided_color; /* Incompatible vertex buffer layout? (misaligned stride or buffer_offset) */ boolean incompatible_vb_layout; - +#define R300_Z_COMPRESS_44 1 +#define RV350_Z_COMPRESS_88 2 + int z_compression; boolean cbzb_clear; + boolean z_decomp_rd; + + /* two mem block managers for hiz/zmask ram space */ + struct mem_block *hiz_mm; + struct mem_block *zmask_mm; + /* upload managers */ struct u_upload_mgr *upload_vb; struct u_upload_mgr *upload_ib; @@ -586,6 +627,12 @@ void r300_init_render_functions(struct r300_context *r300); void r300_init_state_functions(struct r300_context* r300); void r300_init_resource_functions(struct r300_context* r300); +/* r300_blit.c */ +void r300_flush_depth_stencil(struct pipe_context *pipe, + struct pipe_resource *dst, + struct pipe_subresource subdst, + unsigned zslice); + /* r300_query.c */ void r300_resume_query(struct r300_context *r300, struct r300_query *query); @@ -605,7 +652,8 @@ void r300_plug_in_stencil_ref_fallback(struct r300_context *r300); /* r300_state.c */ enum r300_fb_state_change { R300_CHANGED_FB_STATE = 0, - R300_CHANGED_CBZB_FLAG + R300_CHANGED_CBZB_FLAG, + R300_CHANGED_ZCLEAR_FLAG }; void r300_mark_fb_state_dirty(struct r300_context *r300, diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h index 3beb625d430..c194d6a1b08 100644 --- a/src/gallium/drivers/r300/r300_cs.h +++ b/src/gallium/drivers/r300/r300_cs.h @@ -136,8 +136,8 @@ #define WRITE_CS_TABLE(values, count) do { \ CS_DEBUG(assert(cs_count == 0);) \ - memcpy(cs_copy->ptr + cs_copy->cdw, values, count * 4); \ - cs_copy->cdw += count; \ + memcpy(cs_copy->ptr + cs_copy->cdw, (values), (count) * 4); \ + cs_copy->cdw += (count); \ } while (0) #endif /* R300_CS_H */ diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index 31d4e14681b..c3e157e99af 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -38,11 +38,13 @@ static const struct debug_named_value debug_options[] = { { "fall", DBG_FALL, "Fallbacks (for debugging)" }, { "rs", DBG_RS, "Rasterizer (for debugging)" }, { "fb", DBG_FB, "Framebuffer (for debugging)" }, + { "cbzb", DBG_CBZB, "Fast color clear info (for debugging)" }, { "fakeocc", DBG_FAKE_OCC, "Use fake occlusion queries (for debugging)" }, { "anisohq", DBG_ANISOHQ, "High quality anisotropic filtering (for benchmarking)" }, { "notiling", DBG_NO_TILING, "Disable tiling (for benchmarking)" }, { "noimmd", DBG_NO_IMMD, "Disable immediate mode (for benchmarking)" }, { "stats", DBG_STATS, "Gather statistics" }, + { "hyperz", DBG_HYPERZ, "HyperZ (for debugging)" }, /* must be last */ DEBUG_NAMED_VALUE_END diff --git a/src/gallium/drivers/r300/r300_defines.h b/src/gallium/drivers/r300/r300_defines.h index d510d80a7bb..896aeef395d 100644 --- a/src/gallium/drivers/r300/r300_defines.h +++ b/src/gallium/drivers/r300/r300_defines.h @@ -36,7 +36,10 @@ enum r300_buffer_tiling { R300_BUFFER_LINEAR = 0, R300_BUFFER_TILED, - R300_BUFFER_SQUARETILED + R300_BUFFER_SQUARETILED, + + R300_BUFFER_UNKNOWN, + R300_BUFFER_SELECT_LAYOUT = R300_BUFFER_UNKNOWN }; enum r300_buffer_domain { /* bitfield */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 36a26a78717..d0fd45349e3 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -25,6 +25,7 @@ #include "util/u_format.h" #include "util/u_math.h" +#include "util/u_mm.h" #include "util/u_simple_list.h" #include "r300_context.h" @@ -329,6 +330,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; struct r300_surface* surf; unsigned i; + boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); CS_LOCALS(r300); BEGIN_CS(size); @@ -364,6 +366,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); OUT_CS_RELOC(surf->buffer, surf->cbzb_pitch, 0, surf->domain); + + DBG(r300, DBG_CBZB, + "CBZB clearing cbuf %08x %08x\n", surf->cbzb_format, + surf->cbzb_pitch); } /* Set up a zbuffer. */ else if (fb->zsbuf) { @@ -377,15 +383,32 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain); - /* HiZ RAM. */ - if (r300->screen->caps.has_hiz) { - OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0); - OUT_CS_REG(R300_ZB_HIZ_PITCH, 0); + if (has_hyperz) { + uint32_t surf_pitch; + struct r300_texture *tex; + int level = surf->base.level; + tex = r300_texture(surf->base.texture); + + surf_pitch = surf->pitch & R300_DEPTHPITCH_MASK; + /* HiZ RAM. */ + if (r300->screen->caps.hiz_ram) { + if (tex->hiz_mem[level]) { + OUT_CS_REG(R300_ZB_HIZ_OFFSET, tex->hiz_mem[level]->ofs << 2); + OUT_CS_REG(R300_ZB_HIZ_PITCH, surf_pitch); + } else { + OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0); + OUT_CS_REG(R300_ZB_HIZ_PITCH, 0); + } + } + /* Z Mask RAM. (compressed zbuffer) */ + if (tex->zmask_mem[level]) { + OUT_CS_REG(R300_ZB_ZMASK_OFFSET, tex->zmask_mem[level]->ofs << 2); + OUT_CS_REG(R300_ZB_ZMASK_PITCH, surf_pitch); + } else { + OUT_CS_REG(R300_ZB_ZMASK_OFFSET, 0); + OUT_CS_REG(R300_ZB_ZMASK_PITCH, 0); + } } - - /* Z Mask RAM. (compressed zbuffer) */ - OUT_CS_REG(R300_ZB_ZMASK_OFFSET, 0); - OUT_CS_REG(R300_ZB_ZMASK_PITCH, 0); } END_CS; @@ -394,8 +417,12 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) void r300_emit_hyperz_state(struct r300_context *r300, unsigned size, void *state) { + struct r300_hyperz_state *z = state; CS_LOCALS(r300); - WRITE_CS_TABLE(state, size); + if (z->flush) + WRITE_CS_TABLE(&z->cb_flush_begin, size); + else + WRITE_CS_TABLE(&z->cb_begin, size - 2); } void r300_emit_hyperz_end(struct r300_context *r300) @@ -403,9 +430,11 @@ void r300_emit_hyperz_end(struct r300_context *r300) struct r300_hyperz_state z = *(struct r300_hyperz_state*)r300->hyperz_state.state; + z.flush = 1; z.zb_bw_cntl = 0; z.zb_depthclearvalue = 0; z.sc_hyperz = R300_SC_HYPERZ_ADJ_2; + z.gb_z_peq_config = 0; r300_emit_hyperz_state(r300, r300->hyperz_state.size, &z); } @@ -907,6 +936,22 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_TABLE(data, 4); } } + + /* Emit flow control instructions. */ + if (code->num_fc_ops) { + + OUT_CS_REG(R300_VAP_PVS_FLOW_CNTL_OPC, code->fc_ops); + if (r300screen->caps.is_r500) { + OUT_CS_REG_SEQ(R500_VAP_PVS_FLOW_CNTL_ADDRS_LW_0, code->num_fc_ops * 2); + OUT_CS_TABLE(code->fc_op_addrs.r500, code->num_fc_ops * 2); + } else { + OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_ADDRS_0, code->num_fc_ops); + OUT_CS_TABLE(code->fc_op_addrs.r300, code->num_fc_ops); + } + OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_LOOP_INDEX_0, code->num_fc_ops); + OUT_CS_TABLE(code->fc_loop_index, code->num_fc_ops); + } + END_CS; } @@ -943,6 +988,111 @@ void r300_emit_viewport_state(struct r300_context* r300, END_CS; } +static void r300_emit_hiz_line_clear(struct r300_context *r300, int start, uint16_t count, uint32_t val) +{ + CS_LOCALS(r300); + BEGIN_CS(4); + OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_HIZ, 2); + OUT_CS(start); + OUT_CS(count); + OUT_CS(val); + END_CS; +} + +static void r300_emit_zmask_line_clear(struct r300_context *r300, int start, uint16_t count, uint32_t val) +{ + CS_LOCALS(r300); + BEGIN_CS(4); + OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_ZMASK, 2); + OUT_CS(start); + OUT_CS(count); + OUT_CS(val); + END_CS; +} + +#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y)) + +void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state) +{ + struct pipe_framebuffer_state *fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; + struct r300_hyperz_state *z = + (struct r300_hyperz_state*)r300->hyperz_state.state; + struct r300_screen* r300screen = r300->screen; + uint32_t stride, offset = 0, height, offset_shift; + struct r300_texture* tex; + int i; + + tex = r300_texture(fb->zsbuf->texture); + + offset = tex->hiz_mem[fb->zsbuf->level]->ofs; + stride = tex->desc.stride_in_pixels[fb->zsbuf->level]; + + /* convert from pixels to 4x4 blocks */ + stride = ALIGN_DIVUP(stride, 4); + + stride = ALIGN_DIVUP(stride, r300screen->caps.num_frag_pipes); + /* there are 4 blocks per dwords */ + stride = ALIGN_DIVUP(stride, 4); + + height = ALIGN_DIVUP(fb->zsbuf->height, 4); + + offset_shift = 2; + offset_shift += (r300screen->caps.num_frag_pipes / 2); + + for (i = 0; i < height; i++) { + offset = i * stride; + offset <<= offset_shift; + r300_emit_hiz_line_clear(r300, offset, stride, 0xffffffff); + } + z->current_func = -1; + + /* Mark the current zbuffer's hiz ram as in use. */ + tex->hiz_in_use[fb->zsbuf->level] = TRUE; +} + +void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state) +{ + struct pipe_framebuffer_state *fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; + struct r300_screen* r300screen = r300->screen; + uint32_t stride, offset = 0; + struct r300_texture* tex; + uint32_t i, height; + int mult, offset_shift; + + tex = r300_texture(fb->zsbuf->texture); + stride = tex->desc.stride_in_pixels[fb->zsbuf->level]; + + offset = tex->zmask_mem[fb->zsbuf->level]->ofs; + + if (r300->z_compression == RV350_Z_COMPRESS_88) + mult = 8; + else + mult = 4; + + height = ALIGN_DIVUP(fb->zsbuf->height, mult); + + offset_shift = 4; + offset_shift += (r300screen->caps.num_frag_pipes / 2); + stride = ALIGN_DIVUP(stride, r300screen->caps.num_frag_pipes); + + /* okay have width in pixels - divide by block width */ + stride = ALIGN_DIVUP(stride, mult); + /* have width in blocks - divide by number of fragment pipes screen width */ + /* 16 blocks per dword */ + stride = ALIGN_DIVUP(stride, 16); + + for (i = 0; i < height; i++) { + offset = i * stride; + offset <<= offset_shift; + r300_emit_zmask_line_clear(r300, offset, stride, 0x0);//0xffffffff); + } + + /* Mark the current zbuffer's zmask as in use. */ + tex->zmask_in_use[fb->zsbuf->level] = TRUE; +} + void r300_emit_ztop_state(struct r300_context* r300, unsigned size, void* state) { @@ -1062,6 +1212,17 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300) return dwords; } +unsigned r300_get_num_cs_end_dwords(struct r300_context *r300) +{ + unsigned dwords = 0; + + /* Emitted in flush. */ + dwords += 26; /* emit_query_end */ + dwords += r300->hyperz_state.size + 2; /* emit_hyperz_end + zcache flush */ + + return dwords; +} + /* Emit all dirty state. */ void r300_emit_dirty_state(struct r300_context* r300) { diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 5d05039669f..bae25256346 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -112,7 +112,11 @@ void r300_emit_texture_cache_inval(struct r300_context* r300, unsigned size, voi void r300_emit_invariant_state(struct r300_context *r300, unsigned size, void *state); +void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state); +void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state); + unsigned r300_get_num_dirty_dwords(struct r300_context *r300); +unsigned r300_get_num_cs_end_dwords(struct r300_context *r300); /* Emit all dirty state. */ void r300_emit_dirty_state(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index ae7b5759e78..fe182b6615b 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -43,14 +43,6 @@ static void r300_flush(struct pipe_context* pipe, u_upload_flush(r300->upload_vb); u_upload_flush(r300->upload_ib); - /* We probably need to flush Draw, but we may have been called from - * within Draw. This feels kludgy, but it might be the best thing. - * - * Of course, the best thing is to kill Draw with fire. :3 */ - if (r300->draw && !r300->draw->flushing) { - draw_flush(r300->draw); - } - if (r300->dirty_hw) { r300_emit_hyperz_end(r300); r300_emit_query_end(r300); diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index b145ded6399..2a0c30620ad 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -72,6 +72,11 @@ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info, fs_inputs->wpos = i; break; + case TGSI_SEMANTIC_FACE: + assert(index == 0); + fs_inputs->face = i; + break; + default: fprintf(stderr, "r300: FP: Unknown input semantic: %i\n", info->input_semantic_name[i]); @@ -120,6 +125,9 @@ static void allocate_hardware_inputs( allocate(mydata, inputs->color[i], reg++); } } + if (inputs->face != ATTR_UNUSED) { + allocate(mydata, inputs->face, reg++); + } for (i = 0; i < ATTR_GENERIC_COUNT; i++) { if (inputs->generic[i] != ATTR_UNUSED) { allocate(mydata, inputs->generic[i], reg++); @@ -173,7 +181,7 @@ static void get_external_state( t = (struct r300_texture*)texstate->sampler_views[i]->base.texture; /* XXX this should probably take into account STR, not just S. */ - if (t->uses_pitch) { + if (t->desc.is_npot) { switch (s->state.wrap_s) { case PIPE_TEX_WRAP_REPEAT: state->unit[i].wrap_mode = RC_WRAP_REPEAT; @@ -248,13 +256,18 @@ static void r300_emit_fs_code_to_buffer( shader->cb_code_size = 19 + ((code->inst_end + 1) * 6) + - imm_count * 7; + imm_count * 7 + + code->int_constant_count * 2; NEW_CB(shader->cb_code, shader->cb_code_size); OUT_CB_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); OUT_CB_REG(R500_US_PIXSIZE, code->max_temp_idx); OUT_CB_REG(R500_US_FC_CTRL, code->us_fc_ctrl); - OUT_CB_REG(R500_US_CODE_RANGE, + for(i = 0; i < code->int_constant_count; i++){ + OUT_CB_REG(R500_US_FC_INT_CONST_0 + (i * 4), + code->int_constants[i]); + } + OUT_CB_REG(R500_US_CODE_RANGE, R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end)); OUT_CB_REG(R500_US_CODE_OFFSET, 0); OUT_CB_REG(R500_US_CODE_ADDR, @@ -355,13 +368,14 @@ static void r300_translate_fragment_shader( { struct r300_fragment_program_compiler compiler; struct tgsi_to_rc ttr; - int wpos; + int wpos, face; unsigned i; tgsi_scan_shader(tokens, &shader->info); r300_shader_read_fs_inputs(&shader->info, &shader->inputs); wpos = shader->inputs.wpos; + face = shader->inputs.face; /* Setup the compiler. */ memset(&compiler, 0, sizeof(compiler)); @@ -378,7 +392,7 @@ static void r300_translate_fragment_shader( find_output_registers(&compiler, shader); if (compiler.Base.Debug) { - debug_printf("r300: Initial fragment program\n"); + DBG(r300, DBG_FP, "r300: Initial fragment program\n"); tgsi_dump(tokens, 0); } @@ -401,6 +415,10 @@ static void r300_translate_fragment_shader( rc_transform_fragment_wpos(&compiler.Base, wpos, wpos, TRUE); } + if (face != ATTR_UNUSED) { + rc_transform_fragment_face(&compiler.Base, face); + } + /* Invoke the compiler */ r3xx_compile_fragment_program(&compiler); @@ -413,7 +431,7 @@ static void r300_translate_fragment_shader( } if (compiler.Base.Error) { - fprintf(stderr, "r300 FP: Compiler Error:\n%sUsing a dummy shader" + DBG(r300, DBG_FP, "r300 FP: Compiler Error:\n%sUsing a dummy shader" " instead.\nIf there's an 'unknown opcode' message, please" " file a bug report and attach this log.\n", compiler.Base.ErrorMsg); diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c index e9528956019..811b5646e16 100644 --- a/src/gallium/drivers/r300/r300_hyperz.c +++ b/src/gallium/drivers/r300/r300_hyperz.c @@ -25,21 +25,170 @@ #include "r300_hyperz.h" #include "r300_reg.h" #include "r300_fs.h" +#include "r300_winsys.h" +#include "util/u_format.h" +#include "util/u_mm.h" + +/* + HiZ rules - taken from various docs + 1. HiZ only works on depth values + 2. Cannot HiZ if stencil fail or zfail is !KEEP + 3. on R300/400, HiZ is disabled if depth test is EQUAL + 4. comparison changes without clears usually mean disabling HiZ +*/ /*****************************************************************************/ /* The HyperZ setup */ /*****************************************************************************/ +static bool r300_get_sc_hz_max(struct r300_context *r300) +{ + struct r300_dsa_state *dsa_state = r300->dsa_state.state; + int func = dsa_state->z_stencil_control & 0x7; + int ret = R300_SC_HYPERZ_MIN; + + if (func >= 4 && func <= 7) + ret = R300_SC_HYPERZ_MAX; + return ret; +} + +static bool r300_zfunc_same_direction(int func1, int func2) +{ + /* func1 is less/lessthan */ + if (func1 == 1 || func1 == 2) + if (func2 == 3 || func2 == 4 || func2 == 5) + return FALSE; + + if (func2 == 1 || func2 == 2) + if (func1 == 4 || func1 == 5) + return FALSE; + return TRUE; +} + +static int r300_get_hiz_min(struct r300_context *r300) +{ + struct r300_dsa_state *dsa_state = r300->dsa_state.state; + int func = dsa_state->z_stencil_control & 0x7; + int ret = R300_HIZ_MIN; + + if (func == 1 || func == 2) + ret = R300_HIZ_MAX; + return ret; +} + +static boolean r300_dsa_stencil_op_not_keep(struct pipe_stencil_state *s) +{ + if (s->enabled && (s->fail_op != PIPE_STENCIL_OP_KEEP || + s->zfail_op != PIPE_STENCIL_OP_KEEP)) + return TRUE; + return FALSE; +} + +static boolean r300_can_hiz(struct r300_context *r300) +{ + struct r300_dsa_state *dsa_state = r300->dsa_state.state; + struct pipe_depth_stencil_alpha_state *dsa = &dsa_state->dsa; + struct r300_screen* r300screen = r300->screen; + struct r300_hyperz_state *z = r300->hyperz_state.state; + + /* shader writes depth - no HiZ */ + if (r300_fragment_shader_writes_depth(r300_fs(r300))) /* (5) */ + return FALSE; + + if (r300->query_current) + return FALSE; + /* if stencil fail/zfail op is not KEEP */ + if (r300_dsa_stencil_op_not_keep(&dsa->stencil[0]) || + r300_dsa_stencil_op_not_keep(&dsa->stencil[1])) + return FALSE; + + if (dsa->depth.enabled) { + /* if depth func is EQUAL pre-r500 */ + if (dsa->depth.func == PIPE_FUNC_EQUAL && !r300screen->caps.is_r500) + return FALSE; + /* if depth func is NOTEQUAL */ + if (dsa->depth.func == PIPE_FUNC_NOTEQUAL) + return FALSE; + } + /* depth comparison function - if just cleared save and return okay */ + if (z->current_func == -1) { + int func = dsa_state->z_stencil_control & 0x7; + if (func != 0 && func != 7) + z->current_func = dsa_state->z_stencil_control & 0x7; + } else { + /* simple don't change */ + if (!r300_zfunc_same_direction(z->current_func, (dsa_state->z_stencil_control & 0x7))) { + DBG(r300, DBG_HYPERZ, "z func changed direction - disabling hyper-z %d -> %d\n", z->current_func, dsa_state->z_stencil_control); + return FALSE; + } + } + return TRUE; +} + static void r300_update_hyperz(struct r300_context* r300) { struct r300_hyperz_state *z = (struct r300_hyperz_state*)r300->hyperz_state.state; + struct pipe_framebuffer_state *fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; + struct r300_texture *zstex = + fb->zsbuf ? r300_texture(fb->zsbuf->texture) : NULL; + boolean zmask_in_use = FALSE; + boolean hiz_in_use = FALSE; + z->gb_z_peq_config = 0; z->zb_bw_cntl = 0; z->sc_hyperz = R300_SC_HYPERZ_ADJ_2; + z->flush = 0; - if (r300->cbzb_clear) + if (r300->cbzb_clear) { z->zb_bw_cntl |= R300_ZB_CB_CLEAR_CACHE_LINE_WRITE_ONLY; + return; + } + + if (!zstex) + return; + + if (!r300->rws->get_value(r300->rws, R300_CAN_HYPERZ)) + return; + + zmask_in_use = zstex->zmask_in_use[fb->zsbuf->level]; + hiz_in_use = zstex->hiz_in_use[fb->zsbuf->level]; + + /* Z fastfill. */ + if (zmask_in_use) { + z->zb_bw_cntl |= R300_FAST_FILL_ENABLE; /* | R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE;*/ + } + + /* Zbuffer compression. */ + if (zmask_in_use && r300->z_compression) { + z->zb_bw_cntl |= R300_RD_COMP_ENABLE; + if (r300->z_decomp_rd == false) + z->zb_bw_cntl |= R300_WR_COMP_ENABLE; + } + /* RV350 and up optimizations. */ + /* The section 10.4.9 in the docs is a lie. */ + if (r300->z_compression == RV350_Z_COMPRESS_88) + z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8; + + if (hiz_in_use) { + bool can_hiz = r300_can_hiz(r300); + if (can_hiz) { + z->zb_bw_cntl |= R300_HIZ_ENABLE; + z->sc_hyperz |= R300_SC_HYPERZ_ENABLE; + z->sc_hyperz |= r300_get_sc_hz_max(r300); + z->zb_bw_cntl |= r300_get_hiz_min(r300); + } + } + + /* R500-specific features and optimizations. */ + if (r300->screen->caps.is_r500) { + z->zb_bw_cntl |= R500_HIZ_FP_EXP_BITS_3; + z->zb_bw_cntl |= + R500_HIZ_EQUAL_REJECT_ENABLE | + R500_PEQ_PACKING_ENABLE | + R500_COVERED_PTR_MASKING_ENABLE; + } } /*****************************************************************************/ @@ -126,15 +275,121 @@ static void r300_update_ztop(struct r300_context* r300) } else { ztop_state->z_buffer_top = R300_ZTOP_ENABLE; } - if (ztop_state->z_buffer_top != old_ztop) r300->ztop_state.dirty = TRUE; } +#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y)) + +static void r300_update_hiz_clear(struct r300_context *r300) +{ + struct pipe_framebuffer_state *fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; + uint32_t height; + + height = ALIGN_DIVUP(fb->zsbuf->height, 4); + r300->hiz_clear.size = height * 4; +} + +static void r300_update_zmask_clear(struct r300_context *r300) +{ + struct pipe_framebuffer_state *fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; + uint32_t height; + int mult; + + if (r300->z_compression == RV350_Z_COMPRESS_88) + mult = 8; + else + mult = 4; + + height = ALIGN_DIVUP(fb->zsbuf->height, mult); + + r300->zmask_clear.size = height * 4; +} + void r300_update_hyperz_state(struct r300_context* r300) { r300_update_ztop(r300); if (r300->hyperz_state.dirty) { r300_update_hyperz(r300); } + + if (r300->hiz_clear.dirty) { + r300_update_hiz_clear(r300); + } + if (r300->zmask_clear.dirty) { + r300_update_zmask_clear(r300); + } +} + +void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf) +{ + struct r300_texture *tex; + uint32_t zsize, ndw; + int level = surf->base.level; + + tex = r300_texture(surf->base.texture); + + if (tex->hiz_mem[level]) + return; + + zsize = tex->desc.layer_size_in_bytes[level]; + zsize /= util_format_get_blocksize(tex->desc.b.b.format); + ndw = ALIGN_DIVUP(zsize, 64); + + tex->hiz_mem[level] = u_mmAllocMem(r300->hiz_mm, ndw, 0, 0); + return; +} + +void r300_zmask_alloc_block(struct r300_context *r300, struct r300_surface *surf, int compress) +{ + int bsize = 256; + uint32_t zsize, ndw; + int level = surf->base.level; + struct r300_texture *tex; + + tex = r300_texture(surf->base.texture); + + /* We currently don't handle decompression for 3D textures and cubemaps + * correctly. */ + if (tex->desc.b.b.target != PIPE_TEXTURE_1D && + tex->desc.b.b.target != PIPE_TEXTURE_2D) + return; + + if (tex->zmask_mem[level]) + return; + + zsize = tex->desc.layer_size_in_bytes[level]; + zsize /= util_format_get_blocksize(tex->desc.b.b.format); + + /* each zmask dword represents 16 4x4 blocks - which is 256 pixels + or 16 8x8 depending on the gb peq flag = 1024 pixels */ + if (compress == RV350_Z_COMPRESS_88) + bsize = 1024; + + ndw = ALIGN_DIVUP(zsize, bsize); + tex->zmask_mem[level] = u_mmAllocMem(r300->zmask_mm, ndw, 0, 0); + return; +} + +void r300_hyperz_init_mm(struct r300_context *r300) +{ + struct r300_screen* r300screen = r300->screen; + int frag_pipes = r300screen->caps.num_frag_pipes; + + if (r300screen->caps.hiz_ram) + r300->hiz_mm = u_mmInit(0, r300screen->caps.hiz_ram * frag_pipes); + + r300->zmask_mm = u_mmInit(0, r300screen->caps.zmask_ram * frag_pipes); +} + +void r300_hyperz_destroy_mm(struct r300_context *r300) +{ + struct r300_screen* r300screen = r300->screen; + + if (r300screen->caps.hiz_ram) + u_mmDestroy(r300->hiz_mm); + + u_mmDestroy(r300->zmask_mm); } diff --git a/src/gallium/drivers/r300/r300_hyperz.h b/src/gallium/drivers/r300/r300_hyperz.h index 3df5053b896..09e1ff6625c 100644 --- a/src/gallium/drivers/r300/r300_hyperz.h +++ b/src/gallium/drivers/r300/r300_hyperz.h @@ -27,4 +27,9 @@ struct r300_context; void r300_update_hyperz_state(struct r300_context* r300); +void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf); +void r300_zmask_alloc_block(struct r300_context *r300, struct r300_surface *surf, int compress); + +void r300_hyperz_init_mm(struct r300_context *r300); +void r300_hyperz_destroy_mm(struct r300_context *r300); #endif diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 2acc1a903e8..60d3b600cb7 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -496,6 +496,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R300_VAP_GB_HORZ_CLIP_ADJ 0x2228 #define R300_VAP_GB_HORZ_DISC_ADJ 0x222c +#define R300_VAP_PVS_FLOW_CNTL_ADDRS_0 0x2230 +#define R300_PVS_FC_ACT_ADRS(x) ((x) << 0) +#define R300_PVS_FC_LOOP_CNT_JMP_INST(x) ((x) << 8) +#define R300_PVS_FC_LAST_INST(x) ((x) << 16) +#define R300_PVS_FC_RTN_INST(x) ((x) << 24) + /* gap */ /* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between @@ -514,6 +520,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_2288_R300 0x00750000 /* -- nh */ # define R300_2288_RV350 0x0000FFFF /* -- Vladimir */ +#define R300_VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 0x2290 +#define R300_PVS_FC_LOOP_INIT_VAL(x) ((x) << 0) +#define R300_PVS_FC_LOOP_STEP_VAL(x) ((x) << 8) + /* gap */ /* Addresses are relative to the vertex program instruction area of the @@ -548,6 +558,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R300_VAP_PVS_CODE_CNTL_1 0x22D8 # define R300_PVS_LAST_VTX_SRC_INST_SHIFT 0 #define R300_VAP_PVS_FLOW_CNTL_OPC 0x22DC +#define R300_VAP_PVS_FC_OPC_JUMP(x) (1 << (2 * (x))) +#define R300_VAP_PVS_FC_OPC_LOOP(x) (2 << (2 * (x))) +#define R300_VAP_PVS_FC_OPC_JSR(x) (3 << (2 * (x))) /* The entire range from 0x2300 to 0x2AC inclusive seems to be used for * immediate vertices @@ -564,6 +577,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* write 0 to indicate end of packet? */ #define R300_VAP_VTX_END_OF_PKT 0x24AC +#define R500_VAP_PVS_FLOW_CNTL_ADDRS_LW_0 0x2500 +#define R500_PVS_FC_ACT_ADRS(x) ((x) << 0) +#define R500_PVS_FC_LOOP_CNT_JMP_INST(x) ((x) << 16) + +#define R500_VAP_PVS_FLOW_CNTL_ADDRS_UW_0 0x2504 +#define R500_PVS_FC_LAST_INST(x) ((x) << 0) +#define R500_PVS_FC_RTN_INST(x) ((x) << 16) + /* gap */ /* These are values from r300_reg/r300_reg.h - they are known to be correct @@ -3436,6 +3457,7 @@ enum { # define R300_VBPNTR_SIZE1(x) (((x) >> 2) << 16) # define R300_VBPNTR_STRIDE1(x) (((x) >> 2) << 24) +#define R300_PACKET3_3D_CLEAR_ZMASK 0x00003200 #define R300_PACKET3_INDX_BUFFER 0x00003300 # define R300_INDX_BUFFER_DST_SHIFT 0 # define R300_INDX_BUFFER_SKIP_SHIFT 16 diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index bae02135da9..86b11ca0458 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -186,20 +186,14 @@ enum r300_prepare_flags { * \param cs_dwords The number of dwords to reserve in CS. * \param aos_offset The offset passed to emit_aos. * \param index_bias The index bias to emit. - * \param end_cs_dwords The number of free dwords which must be available - * at the end of CS after drawing in case the CS space - * management is performed by a draw_* function manually. - * The parameter may be NULL. */ static void r300_prepare_for_rendering(struct r300_context *r300, enum r300_prepare_flags flags, struct pipe_resource *index_buffer, unsigned cs_dwords, int aos_offset, - int index_bias, - unsigned *end_cs_dwords) + int index_bias) { - unsigned end_dwords = 0; boolean flushed = FALSE; boolean first_draw = flags & PREP_FIRST_DRAW; boolean emit_aos = flags & PREP_EMIT_AOS; @@ -221,11 +215,7 @@ static void r300_prepare_for_rendering(struct r300_context *r300, cs_dwords += 7; /* emit_aos_swtcl */ } - /* Emitted in flush. */ - end_dwords += 26; /* emit_query_end */ - end_dwords += r300->hyperz_state.size; /* emit_hyperz_end */ - - cs_dwords += end_dwords; + cs_dwords += r300_get_num_cs_end_dwords(r300); /* Reserve requested CS space. */ if (cs_dwords > (r300->cs->ndw - r300->cs->cdw)) { @@ -250,9 +240,6 @@ static void r300_prepare_for_rendering(struct r300_context *r300, if (emit_aos_swtcl) r300_emit_aos_swtcl(r300, indexed); } - - if (end_cs_dwords) - *end_cs_dwords = end_dwords; } static boolean immd_is_good_idea(struct r300_context *r300, @@ -353,7 +340,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300, dwords = 9 + count * vertex_size; - r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0, NULL); + r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0); BEGIN_CS(dwords); OUT_CS_REG(R300_GA_COLOR_CONTROL, @@ -533,7 +520,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe, /* 15 dwords for emit_draw_elements */ r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, - indexBuffer, 15, buffer_offset, indexBias, NULL); + indexBuffer, 15, buffer_offset, indexBias); if (alt_num_verts || count <= 65535) { r300_emit_draw_elements(r300, indexBuffer, indexSize, @@ -552,7 +539,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe, if (count) { r300_prepare_for_rendering(r300, PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, - indexBuffer, 15, buffer_offset, indexBias, NULL); + indexBuffer, 15, buffer_offset, indexBias); } } while (count); } @@ -566,19 +553,6 @@ static void r300_draw_range_elements(struct pipe_context* pipe, } } -/* Simple helpers for context setup. Should probably be moved to util. */ -static void r300_draw_elements(struct pipe_context* pipe, - struct pipe_resource* indexBuffer, - unsigned indexSize, int indexBias, unsigned mode, - unsigned start, unsigned count) -{ - struct r300_context *r300 = r300_context(pipe); - - pipe->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, - 0, r300->vertex_buffer_max_index, - mode, start, count); -} - static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, unsigned start, unsigned count) { @@ -610,7 +584,7 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, } else { /* 9 spare dwords for emit_draw_arrays. */ r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS, - NULL, 9, start, 0, NULL); + NULL, 9, start, 0); if (alt_num_verts || count <= 65535) { r300_emit_draw_arrays(r300, mode, count); @@ -626,7 +600,7 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, if (count) { r300_prepare_for_rendering(r300, PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, - start, 0, NULL); + start, 0); } } while (count); } @@ -638,111 +612,104 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode, } } -/**************************************************************************** - * The rest of this file is for SW TCL rendering only. Please be polite and * - * keep these functions separated so that they are easier to locate. ~C. * - ***************************************************************************/ - -/* SW TCL arrays, using Draw. */ -static void r300_swtcl_draw_arrays(struct pipe_context* pipe, - unsigned mode, - unsigned start, - unsigned count) +static void r300_draw_vbo(struct pipe_context* pipe, + const struct pipe_draw_info *info) { struct r300_context* r300 = r300_context(pipe); - struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; - int i; - if (r300->skip_rendering) { - return; + if (info->indexed && r300->index_buffer.buffer) { + unsigned offset; + + assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0); + offset = r300->index_buffer.offset / r300->index_buffer.index_size; + + r300_draw_range_elements(pipe, + r300->index_buffer.buffer, + r300->index_buffer.index_size, + info->index_bias, + info->min_index, + info->max_index, + info->mode, + info->start + offset, + info->count); } - - if (!u_trim_pipe_prim(mode, &count)) { - return; - } - - r300_update_derived_state(r300); - - for (i = 0; i < r300->vertex_buffer_count; i++) { - void* buf = pipe_buffer_map(pipe, - r300->vertex_buffer[i].buffer, - PIPE_TRANSFER_READ, - &vb_transfer[i]); - draw_set_mapped_vertex_buffer(r300->draw, i, buf); - } - - draw_set_mapped_element_buffer(r300->draw, 0, 0, NULL); - - draw_arrays(r300->draw, mode, start, count); - - /* XXX Not sure whether this is the best fix. - * It prevents CS from being rejected and weird assertion failures. */ - draw_flush(r300->draw); - - for (i = 0; i < r300->vertex_buffer_count; i++) { - pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, - vb_transfer[i]); - draw_set_mapped_vertex_buffer(r300->draw, i, NULL); + else { + r300_draw_arrays(pipe, + info->mode, + info->start, + info->count); } } +/**************************************************************************** + * The rest of this file is for SW TCL rendering only. Please be polite and * + * keep these functions separated so that they are easier to locate. ~C. * + ***************************************************************************/ + /* SW TCL elements, using Draw. */ -static void r300_swtcl_draw_range_elements(struct pipe_context* pipe, - struct pipe_resource* indexBuffer, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) +static void r300_swtcl_draw_vbo(struct pipe_context* pipe, + const struct pipe_draw_info *info) { struct r300_context* r300 = r300_context(pipe); struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; - struct pipe_transfer *ib_transfer; + struct pipe_transfer *ib_transfer = NULL; + unsigned count = info->count; int i; - void* indices; + void* indices = NULL; if (r300->skip_rendering) { return; } - if (!u_trim_pipe_prim(mode, &count)) { + if (!u_trim_pipe_prim(info->mode, &count)) { return; } r300_update_derived_state(r300); for (i = 0; i < r300->vertex_buffer_count; i++) { - void* buf = pipe_buffer_map(pipe, - r300->vertex_buffer[i].buffer, - PIPE_TRANSFER_READ, - &vb_transfer[i]); - draw_set_mapped_vertex_buffer(r300->draw, i, buf); + if (r300->vertex_buffer[i].buffer) { + void *buf = pipe_buffer_map(pipe, + r300->vertex_buffer[i].buffer, + PIPE_TRANSFER_READ, + &vb_transfer[i]); + draw_set_mapped_vertex_buffer(r300->draw, i, buf); + } } - indices = pipe_buffer_map(pipe, indexBuffer, - PIPE_TRANSFER_READ, &ib_transfer); - draw_set_mapped_element_buffer_range(r300->draw, indexSize, indexBias, - minIndex, maxIndex, indices); + if (info->indexed && r300->index_buffer.buffer) { + indices = pipe_buffer_map(pipe, r300->index_buffer.buffer, + PIPE_TRANSFER_READ, &ib_transfer); + if (indices) + indices = (void *) ((char *) indices + r300->index_buffer.offset); + } - draw_arrays(r300->draw, mode, start, count); + draw_set_mapped_element_buffer_range(r300->draw, (indices) ? + r300->index_buffer.index_size : 0, + info->index_bias, + info->min_index, + info->max_index, + indices); + + draw_arrays(r300->draw, info->mode, info->start, count); /* XXX Not sure whether this is the best fix. * It prevents CS from being rejected and weird assertion failures. */ draw_flush(r300->draw); for (i = 0; i < r300->vertex_buffer_count; i++) { - pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, - vb_transfer[i]); - draw_set_mapped_vertex_buffer(r300->draw, i, NULL); + if (r300->vertex_buffer[i].buffer) { + pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer, + vb_transfer[i]); + draw_set_mapped_vertex_buffer(r300->draw, i, NULL); + } } - pipe_buffer_unmap(pipe, indexBuffer, - ib_transfer); - draw_set_mapped_element_buffer_range(r300->draw, 0, 0, - start, start + count - 1, - NULL); + if (ib_transfer) { + pipe_buffer_unmap(pipe, r300->index_buffer.buffer, ib_transfer); + draw_set_mapped_element_buffer_range(r300->draw, 0, 0, info->start, + info->start + count - 1, NULL); + } } /* Object for rendering using Draw. */ @@ -820,6 +787,8 @@ static void* r300_render_map_vertices(struct vbuf_render* render) PIPE_TRANSFER_WRITE, &r300render->vbo_transfer); + assert(r300render->vbo_ptr); + return ((uint8_t*)r300render->vbo_ptr + r300render->vbo_offset); } @@ -872,7 +841,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render, (void) i; (void) ptr; r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL, - NULL, dwords, 0, 0, NULL); + NULL, dwords, 0, 0); DBG(r300, DBG_DRAW, "r300: render_draw_arrays (count: %d)\n", count); @@ -925,7 +894,8 @@ static void r300_render_draw_elements(struct vbuf_render* render, * indices than it can fit in CS. */ r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, - NULL, 256, 0, 0, &end_cs_dwords); + NULL, 256, 0, 0); + end_cs_dwords = r300_get_num_cs_end_dwords(r300); while (count) { free_dwords = r300->cs->ndw - r300->cs->cdw; @@ -955,7 +925,8 @@ static void r300_render_draw_elements(struct vbuf_render* render, if (count) { r300_prepare_for_rendering(r300, PREP_EMIT_AOS_SWTCL | PREP_INDEXED, - NULL, 256, 0, 0, &end_cs_dwords); + NULL, 256, 0, 0); + end_cs_dwords = r300_get_num_cs_end_dwords(r300); } } } @@ -1049,7 +1020,7 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter, r300->clip_state.dirty = FALSE; r300->viewport_state.dirty = FALSE; - r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0, NULL); + r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0); DBG(r300, DBG_DRAW, "r300: draw_rectangle\n"); @@ -1141,16 +1112,11 @@ static void r300_resource_resolve(struct pipe_context* pipe, void r300_init_render_functions(struct r300_context *r300) { - /* Set generic functions. */ - r300->context.draw_elements = r300_draw_elements; - /* Set draw functions based on presence of HW TCL. */ if (r300->screen->caps.has_tcl) { - r300->context.draw_arrays = r300_draw_arrays; - r300->context.draw_range_elements = r300_draw_range_elements; + r300->context.draw_vbo = r300_draw_vbo; } else { - r300->context.draw_arrays = r300_swtcl_draw_arrays; - r300->context.draw_range_elements = r300_swtcl_draw_range_elements; + r300->context.draw_vbo = r300_swtcl_draw_vbo; } r300->context.resource_resolve = r300_resource_resolve; diff --git a/src/gallium/drivers/r300/r300_render_stencilref.c b/src/gallium/drivers/r300/r300_render_stencilref.c index 9a6b4e12ff1..1f035d64a28 100644 --- a/src/gallium/drivers/r300/r300_render_stencilref.c +++ b/src/gallium/drivers/r300/r300_render_stencilref.c @@ -34,13 +34,8 @@ #include "r300_reg.h" struct r300_stencilref_context { - void (*draw_arrays)(struct pipe_context *pipe, - unsigned mode, unsigned start, unsigned count); - - void (*draw_range_elements)( - struct pipe_context *pipe, struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex, - unsigned mode, unsigned start, unsigned count); + void (*draw_vbo)(struct pipe_context *pipe, + const struct pipe_draw_info *info); uint32_t rs_cull_mode; uint32_t zb_stencilrefmask; @@ -105,41 +100,19 @@ static void r300_stencilref_end(struct r300_context *r300) r300->dsa_state.dirty = TRUE; } -static void r300_stencilref_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count) -{ - struct r300_context *r300 = r300_context(pipe); - struct r300_stencilref_context *sr = r300->stencilref_fallback; - - if (!r300_stencilref_needed(r300)) { - sr->draw_arrays(pipe, mode, start, count); - } else { - r300_stencilref_begin(r300); - sr->draw_arrays(pipe, mode, start, count); - r300_stencilref_switch_side(r300); - sr->draw_arrays(pipe, mode, start, count); - r300_stencilref_end(r300); - } -} - -static void r300_stencilref_draw_range_elements( - struct pipe_context *pipe, struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex, - unsigned mode, unsigned start, unsigned count) +static void r300_stencilref_draw_vbo(struct pipe_context *pipe, + const struct pipe_draw_info *info) { struct r300_context *r300 = r300_context(pipe); struct r300_stencilref_context *sr = r300->stencilref_fallback; if (!r300_stencilref_needed(r300)) { - sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, - minIndex, maxIndex, mode, start, count); + sr->draw_vbo(pipe, info); } else { r300_stencilref_begin(r300); - sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, - minIndex, maxIndex, mode, start, count); + sr->draw_vbo(pipe, info); r300_stencilref_switch_side(r300); - sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias, - minIndex, maxIndex, mode, start, count); + sr->draw_vbo(pipe, info); r300_stencilref_end(r300); } } @@ -148,11 +121,9 @@ void r300_plug_in_stencil_ref_fallback(struct r300_context *r300) { r300->stencilref_fallback = CALLOC_STRUCT(r300_stencilref_context); - /* Save original draw functions. */ - r300->stencilref_fallback->draw_arrays = r300->context.draw_arrays; - r300->stencilref_fallback->draw_range_elements = r300->context.draw_range_elements; + /* Save original draw function. */ + r300->stencilref_fallback->draw_vbo = r300->context.draw_vbo; - /* Override the draw functions. */ - r300->context.draw_arrays = r300_stencilref_draw_arrays; - r300->context.draw_range_elements = r300_stencilref_draw_range_elements; + /* Override the draw function. */ + r300->context.draw_vbo = r300_stencilref_draw_vbo; } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 5a11b98eb6c..1e4edcdbc31 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -115,7 +115,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_REPEAT: case PIPE_CAP_BLEND_EQUATION_SEPARATE: case PIPE_CAP_TEXTURE_SWIZZLE: - case PIPE_CAP_DEPTH_CLAMP: return 1; /* Unsupported features (boolean caps). */ @@ -124,6 +123,8 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_CONT_SUPPORTED: case PIPE_CAP_INDEP_BLEND_ENABLE: case PIPE_CAP_INDEP_BLEND_FUNC: + case PIPE_CAP_DEPTH_CLAMP: /* XXX implemented, but breaks Regnum Online */ + case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: return 0; /* Texturing. */ @@ -150,9 +151,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_CONST_BUFFER_SIZE: return 256; - case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: - return 1; - /* Fragment coordinate conventions. */ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: @@ -257,8 +255,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, uint32_t retval = 0; boolean is_r500 = r300_screen(screen)->caps.is_r500; boolean is_r400 = r300_screen(screen)->caps.is_r400; - boolean is_z24 = format == PIPE_FORMAT_X8Z24_UNORM || - format == PIPE_FORMAT_S8_USCALED_Z24_UNORM; boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM || format == PIPE_FORMAT_R10G10B10X2_SNORM || format == PIPE_FORMAT_B10G10R10A2_UNORM || @@ -281,11 +277,14 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, case 3: case 4: case 6: + return FALSE; +#if 0 if (usage != PIPE_BIND_RENDER_TARGET || !util_format_is_rgba8_variant( util_format_description(format))) { return FALSE; } +#endif break; default: return FALSE; @@ -293,8 +292,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, /* Check sampler format support. */ if ((usage & PIPE_BIND_SAMPLER_VIEW) && - /* Z24 cannot be sampled from on non-r5xx. */ - (is_r500 || !is_z24) && /* ATI1N is r5xx-only. */ (is_r500 || !is_ati1n) && /* ATI2N is supported on r4xx-r5xx. */ diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h index edc494ff6ca..13a3320b992 100644 --- a/src/gallium/drivers/r300/r300_screen.h +++ b/src/gallium/drivers/r300/r300_screen.h @@ -90,6 +90,8 @@ r300_winsys_screen(struct pipe_screen *screen) { #define DBG_FALL (1 << 8) #define DBG_FB (1 << 9) #define DBG_RS_BLOCK (1 << 10) +#define DBG_CBZB (1 << 11) +#define DBG_HYPERZ (1 << 12) /* Features. */ #define DBG_ANISOHQ (1 << 16) #define DBG_NO_TILING (1 << 17) diff --git a/src/gallium/drivers/r300/r300_shader_semantics.h b/src/gallium/drivers/r300/r300_shader_semantics.h index cb7a37033f3..4be23e64ce7 100644 --- a/src/gallium/drivers/r300/r300_shader_semantics.h +++ b/src/gallium/drivers/r300/r300_shader_semantics.h @@ -38,6 +38,7 @@ struct r300_shader_semantics { int psize; int color[ATTR_COLOR_COUNT]; int bcolor[ATTR_COLOR_COUNT]; + int face; int generic[ATTR_GENERIC_COUNT]; int fog; int wpos; @@ -50,6 +51,7 @@ static INLINE void r300_shader_semantics_reset( info->pos = ATTR_UNUSED; info->psize = ATTR_UNUSED; + info->face = ATTR_UNUSED; info->fog = ATTR_UNUSED; info->wpos = ATTR_UNUSED; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index f52265b1c03..239edd98e32 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -25,6 +25,7 @@ #include "util/u_blitter.h" #include "util/u_math.h" +#include "util/u_mm.h" #include "util/u_memory.h" #include "util/u_pack_color.h" @@ -43,6 +44,7 @@ #include "r300_texture.h" #include "r300_vs.h" #include "r300_winsys.h" +#include "r300_hyperz.h" /* r300_state: Functions used to intialize state context by translating * Gallium state objects into semi-native r300 state objects. */ @@ -446,7 +448,6 @@ static void r300_set_clip_state(struct pipe_context* pipe, r300->clip_state.dirty = TRUE; } else { - draw_flush(r300->draw); draw_set_clip_state(r300->draw, state); } } @@ -473,14 +474,14 @@ static void* dsa->dsa = *state; - /* Depth test setup. */ + /* Depth test setup. - separate write mask depth for decomp flush */ + if (state->depth.writemask) { + dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; + } + if (state->depth.enabled) { dsa->z_buffer_control |= R300_Z_ENABLE; - if (state->depth.writemask) { - dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; - } - dsa->z_stencil_control |= (r300_translate_depth_stencil_function(state->depth.func) << R300_Z_FUNC_SHIFT); @@ -593,6 +594,7 @@ static void r300_bind_dsa_state(struct pipe_context* pipe, UPDATE_STATE(state, r300->dsa_state); + r300->hyperz_state.dirty = TRUE; /* Will be updated before the emission. */ r300_dsa_inject_stencilref(r300); } @@ -619,7 +621,8 @@ static void r300_tex_set_tiling_flags(struct r300_context *r300, { /* Check if the macrotile flag needs to be changed. * Skip changing the flags otherwise. */ - if (tex->mip_macrotile[tex->surface_level] != tex->mip_macrotile[level]) { + if (tex->desc.macrotile[tex->surface_level] != + tex->desc.macrotile[level]) { /* Tiling determines how DRM treats the buffer data. * We must flush CS when changing it if the buffer is referenced. */ if (r300->rws->cs_is_buffer_referenced(r300->cs, @@ -627,8 +630,8 @@ static void r300_tex_set_tiling_flags(struct r300_context *r300, r300->context.flush(&r300->context, 0, NULL); r300->rws->buffer_set_tiling(r300->rws, tex->buffer, - tex->microtile, tex->mip_macrotile[level], - tex->pitch[0] * util_format_get_blocksize(tex->b.b.format)); + tex->desc.microtile, tex->desc.macrotile[level], + tex->desc.stride_in_bytes[0]); tex->surface_level = level; } @@ -670,8 +673,10 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index, surf->zslice, surf->face, surf->level, util_format_short_name(surf->format), - rtex->macrotile ? "YES" : " NO", rtex->microtile ? "YES" : " NO", - rtex->hwpitch[0], tex->width0, tex->height0, tex->depth0, + rtex->desc.macrotile[0] ? "YES" : " NO", + rtex->desc.microtile ? "YES" : " NO", + rtex->desc.stride_in_pixels[0], + tex->width0, tex->height0, tex->depth0, tex->last_level, util_format_short_name(tex->format)); } @@ -679,6 +684,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, enum r300_fb_state_change change) { struct pipe_framebuffer_state *state = r300->fb_state.state; + boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); /* What is marked as dirty depends on the enum r300_fb_state_change. */ r300->gpu_flush.dirty = TRUE; @@ -695,8 +701,11 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, if (r300->cbzb_clear) r300->fb_state.size += 10; - else if (state->zsbuf) - r300->fb_state.size += r300->screen->caps.has_hiz ? 18 : 14; + else if (state->zsbuf) { + r300->fb_state.size += 10; + if (has_hyperz) + r300->fb_state.size += r300->screen->caps.hiz_ram ? 8 : 4; + } /* The size of the rest of atoms stays the same. */ } @@ -708,8 +717,10 @@ static void struct r300_context* r300 = r300_context(pipe); struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state; struct pipe_framebuffer_state *old_state = r300->fb_state.state; + boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); unsigned max_width, max_height, i; uint32_t zbuffer_bpp = 0; + int blocksize; if (r300->screen->caps.is_r500) { max_width = max_height = 4096; @@ -725,10 +736,6 @@ static void return; } - if (r300->draw) { - draw_flush(r300->draw); - } - /* If nr_cbufs is changed from zero to non-zero or vice versa... */ if (!!old_state->nr_cbufs != !!state->nr_cbufs) { r300->blend_state.dirty = TRUE; @@ -745,20 +752,50 @@ static void r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE); - /* Polygon offset depends on the zbuffer bit depth. */ - if (state->zsbuf && r300->polygon_offset_enabled) { - switch (util_format_get_blocksize(state->zsbuf->texture->format)) { - case 2: - zbuffer_bpp = 16; - break; - case 4: - zbuffer_bpp = 24; - break; + r300->z_compression = false; + + if (state->zsbuf) { + blocksize = util_format_get_blocksize(state->zsbuf->texture->format); + switch (blocksize) { + case 2: + zbuffer_bpp = 16; + break; + case 4: + zbuffer_bpp = 24; + break; + } + if (has_hyperz) { + struct r300_surface *zs_surf = r300_surface(state->zsbuf); + struct r300_texture *tex; + int compress = r300->screen->caps.is_rv350 ? RV350_Z_COMPRESS_88 : R300_Z_COMPRESS_44; + int level = zs_surf->base.level; + + tex = r300_texture(zs_surf->base.texture); + + /* work out whether we can support hiz on this buffer */ + r300_hiz_alloc_block(r300, zs_surf); + + /* work out whether we can support zmask features on this buffer */ + r300_zmask_alloc_block(r300, zs_surf, compress); + + if (tex->zmask_mem[level]) { + /* compression causes hangs on 16-bit */ + if (zbuffer_bpp == 24) + r300->z_compression = compress; + } + DBG(r300, DBG_HYPERZ, + "hyper-z features: hiz: %d @ %08x z-compression: %d z-fastfill: %d @ %08x\n", tex->hiz_mem[level] ? 1 : 0, + tex->hiz_mem[level] ? tex->hiz_mem[level]->ofs : 0xdeadbeef, + r300->z_compression, tex->zmask_mem[level] ? 1 : 0, + tex->zmask_mem[level] ? tex->zmask_mem[level]->ofs : 0xdeadbeef); } + /* Polygon offset depends on the zbuffer bit depth. */ if (r300->zbuffer_bpp != zbuffer_bpp) { r300->zbuffer_bpp = zbuffer_bpp; - r300->rs_state.dirty = TRUE; + + if (r300->polygon_offset_enabled) + r300->rs_state.dirty = TRUE; } } @@ -1016,7 +1053,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe, for (i = 0; i < 8; i++) { if (state->sprite_coord_enable & (1 << i)) stuffing_enable |= - R300_GB_TEX_STR << (R300_GB_TEX0_SOURCE_SHIFT + (i*2)); + R300_GB_TEX_ST << (R300_GB_TEX0_SOURCE_SHIFT + (i*2)); } point_texcoord_left = 0.0f; @@ -1093,14 +1130,11 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) boolean last_two_sided_color = r300->two_sided_color; if (r300->draw && rs) { - draw_flush(r300->draw); draw_set_rasterizer_state(r300->draw, &rs->rs_draw, state); } if (rs) { - r300->polygon_offset_enabled = (rs->rs.offset_point || - rs->rs.offset_line || - rs->rs.offset_tri); + r300->polygon_offset_enabled = rs->polygon_offset_enable; r300->sprite_coord_enable = rs->rs.sprite_coord_enable; r300->two_sided_color = rs->rs.light_twoside; } else { @@ -1293,7 +1327,7 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe, /* Set the texrect factor in the fragment shader. * Needed for RECT and NPOT fallback. */ texture = r300_texture(views[i]->texture); - if (texture->uses_pitch) { + if (texture->desc.is_npot) { r300->fs_rc_constant_state.dirty = TRUE; } @@ -1327,6 +1361,7 @@ r300_create_sampler_view(struct pipe_context *pipe, { struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view); struct r300_texture *tex = r300_texture(texture); + boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500; if (view) { view->base = *templ; @@ -1342,8 +1377,9 @@ r300_create_sampler_view(struct pipe_context *pipe, view->format = tex->tx_format; view->format.format1 |= r300_translate_texformat(templ->format, - view->swizzle); - if (r300_screen(pipe->screen)->caps.is_r500) { + view->swizzle, + is_r500); + if (is_r500) { view->format.format2 |= r500_tx_format_msb_bit(templ->format); } } @@ -1380,7 +1416,6 @@ static void r300_set_viewport_state(struct pipe_context* pipe, r300->viewport = *state; if (r300->draw) { - draw_flush(r300->draw); draw_set_viewport_state(r300->draw, state); viewport->vte_control = R300_VTX_XY_FMT | R300_VTX_Z_FMT; return; @@ -1481,7 +1516,6 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, } else { /* SW TCL. */ - draw_flush(r300->draw); draw_set_vertex_buffers(r300->draw, count, buffers); } @@ -1500,6 +1534,23 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, r300->vertex_buffer_count = count; } +static void r300_set_index_buffer(struct pipe_context* pipe, + const struct pipe_index_buffer *ib) +{ + struct r300_context* r300 = r300_context(pipe); + + if (ib) { + pipe_resource_reference(&r300->index_buffer.buffer, ib->buffer); + memcpy(&r300->index_buffer, ib, sizeof(r300->index_buffer)); + } + else { + pipe_resource_reference(&r300->index_buffer.buffer, NULL); + memset(&r300->index_buffer, 0, sizeof(r300->index_buffer)); + } + + /* TODO make this more like a state */ +} + /* Initialize the PSC tables. */ static void r300_vertex_psc(struct r300_vertex_element_state *velems) { @@ -1649,7 +1700,6 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe, r300->velems = velems; if (r300->draw) { - draw_flush(r300->draw); draw_set_vertex_elements(r300->draw, velems->count, velems->velem); return; } @@ -1701,10 +1751,12 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300->rs_block_state.dirty = TRUE; /* Will be updated before the emission. */ if (r300->screen->caps.has_tcl) { + unsigned fc_op_dwords = r300->screen->caps.is_r500 ? 3 : 2; r300->vs_state.dirty = TRUE; r300->vs_state.size = vs->code.length + 9 + - (vs->immediates_count ? vs->immediates_count * 4 + 3 : 0); + (vs->immediates_count ? vs->immediates_count * 4 + 3 : 0) + + (vs->code.num_fc_ops ? vs->code.num_fc_ops * fc_op_dwords + 4 : 0); if (vs->externals_count) { r300->vs_constants.dirty = TRUE; @@ -1715,7 +1767,6 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) r300->pvs_flush.dirty = TRUE; } else { - draw_flush(r300->draw); draw_bind_vertex_shader(r300->draw, (struct draw_vertex_shader*)vs->draw_vs); } @@ -1847,6 +1898,7 @@ void r300_init_state_functions(struct r300_context* r300) r300->context.set_viewport_state = r300_set_viewport_state; r300->context.set_vertex_buffers = r300_set_vertex_buffers; + r300->context.set_index_buffer = r300_set_index_buffer; r300->context.create_vertex_elements_state = r300_create_vertex_elements_state; r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 2ef9766578c..4a63ed7fc13 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -46,6 +46,11 @@ enum r300_rs_swizzle { SWIZ_0001, }; +enum r300_rs_col_write_type { + WRITE_COLOR = 0, + WRITE_FACE +}; + static void r300_draw_emit_attrib(struct r300_context* r300, enum attrib_emit emit, enum interp_mode interp, @@ -203,8 +208,10 @@ static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr, rs->inst[id] |= R300_RS_INST_COL_ID(id); } -static void r300_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset) +static void r300_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset, + enum r300_rs_col_write_type type) { + assert(type != WRITE_COLOR); rs->inst[id] |= R300_RS_INST_COL_CN_WRITE | R300_RS_INST_COL_ADDR(fp_offset); } @@ -213,19 +220,19 @@ static void r300_rs_tex(struct r300_rs_block* rs, int id, int ptr, enum r300_rs_swizzle swiz) { if (swiz == SWIZ_X001) { - rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | + rs->ip[id] |= R300_RS_TEX_PTR(ptr) | R300_RS_SEL_S(R300_RS_SEL_C0) | R300_RS_SEL_T(R300_RS_SEL_K0) | R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1); } else if (swiz == SWIZ_XY01) { - rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | + rs->ip[id] |= R300_RS_TEX_PTR(ptr) | R300_RS_SEL_S(R300_RS_SEL_C0) | R300_RS_SEL_T(R300_RS_SEL_C1) | R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1); } else { - rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | + rs->ip[id] |= R300_RS_TEX_PTR(ptr) | R300_RS_SEL_S(R300_RS_SEL_C0) | R300_RS_SEL_T(R300_RS_SEL_C1) | R300_RS_SEL_R(R300_RS_SEL_C2) | @@ -252,32 +259,36 @@ static void r500_rs_col(struct r300_rs_block* rs, int id, int ptr, rs->inst[id] |= R500_RS_INST_COL_ID(id); } -static void r500_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset) +static void r500_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset, + enum r300_rs_col_write_type type) { - rs->inst[id] |= R500_RS_INST_COL_CN_WRITE | - R500_RS_INST_COL_ADDR(fp_offset); + if (type == WRITE_FACE) + rs->inst[id] |= R500_RS_INST_COL_CN_WRITE_BACKFACE | + R500_RS_INST_COL_ADDR(fp_offset); + else + rs->inst[id] |= R500_RS_INST_COL_CN_WRITE | + R500_RS_INST_COL_ADDR(fp_offset); + } static void r500_rs_tex(struct r300_rs_block* rs, int id, int ptr, enum r300_rs_swizzle swiz) { - int rs_tex_comp = ptr*4; - if (swiz == SWIZ_X001) { - rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | + rs->ip[id] |= R500_RS_SEL_S(ptr) | R500_RS_SEL_T(R500_RS_IP_PTR_K0) | R500_RS_SEL_R(R500_RS_IP_PTR_K0) | R500_RS_SEL_Q(R500_RS_IP_PTR_K1); } else if (swiz == SWIZ_XY01) { - rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | - R500_RS_SEL_T(rs_tex_comp + 1) | + rs->ip[id] |= R500_RS_SEL_S(ptr) | + R500_RS_SEL_T(ptr + 1) | R500_RS_SEL_R(R500_RS_IP_PTR_K0) | R500_RS_SEL_Q(R500_RS_IP_PTR_K1); } else { - rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | - R500_RS_SEL_T(rs_tex_comp + 1) | - R500_RS_SEL_R(rs_tex_comp + 2) | - R500_RS_SEL_Q(rs_tex_comp + 3); + rs->ip[id] |= R500_RS_SEL_S(ptr) | + R500_RS_SEL_T(ptr + 1) | + R500_RS_SEL_R(ptr + 2) | + R500_RS_SEL_Q(ptr + 3); } rs->inst[id] |= R500_RS_INST_TEX_ID(id); } @@ -305,9 +316,9 @@ static void r300_update_rs_block(struct r300_context *r300) struct r300_shader_semantics *vs_outputs = &vs->outputs; struct r300_shader_semantics *fs_inputs = &r300_fs(r300)->shader->inputs; struct r300_rs_block rs = {0}; - int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0; + int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0, tex_ptr = 0; void (*rX00_rs_col)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); - void (*rX00_rs_col_write)(struct r300_rs_block*, int, int); + void (*rX00_rs_col_write)(struct r300_rs_block*, int, int, enum r300_rs_col_write_type); void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int); boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED || @@ -326,6 +337,11 @@ static void r300_update_rs_block(struct r300_context *r300) rX00_rs_tex_write = r300_rs_tex_write; } + /* 0x5555 copied from classic, which means: + * Select user color 0 for COLOR0 up to COLOR7. + * What the hell does that mean? */ + rs.vap_vtx_state_cntl = 0x5555; + /* The position is always present in VAP. */ rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS; rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT; @@ -352,7 +368,7 @@ static void r300_update_rs_block(struct r300_context *r300) /* Write it to the FS input register if it's needed by the FS. */ if (fs_inputs->color[i] != ATTR_UNUSED) { - rX00_rs_col_write(&rs, col_count, fp_offset); + rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_COLOR); fp_offset++; DBG(r300, DBG_RS, @@ -393,12 +409,31 @@ static void r300_update_rs_block(struct r300_context *r300) stream_loc_notcl[loc++] = 6 + tex_count; /* Rasterize it. */ - rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW); + rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_XYZW); tex_count++; + tex_ptr += 4; } } } + /* gl_FrontFacing. + * Note that we can use either the two-sided color selection based on + * the front and back vertex shader colors, or gl_FrontFacing, + * but not both! It locks up otherwise. + * + * In Direct3D 9, the two-sided color selection can be used + * with shaders 2.0 only, while gl_FrontFacing can be used + * with shaders 3.0 only. The hardware apparently hasn't been designed + * to support both at the same time. */ + if (r300->screen->caps.is_r500 && fs_inputs->face != ATTR_UNUSED && + !(any_bcolor_used && r300->two_sided_color)) { + rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW); + rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_FACE); + fp_offset++; + col_count++; + DBG(r300, DBG_RS, "r300: Rasterized FACE written to FS.\n"); + } + /* Rasterize texture coordinates. */ for (i = 0; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) { bool sprite_coord = !!(r300->sprite_coord_enable & (1 << i)); @@ -412,7 +447,7 @@ static void r300_update_rs_block(struct r300_context *r300) } /* Rasterize it. */ - rX00_rs_tex(&rs, tex_count, tex_count, + rX00_rs_tex(&rs, tex_count, tex_ptr, sprite_coord ? SWIZ_XY01 : SWIZ_XYZW); /* Write it to the FS input register if it's needed by the FS. */ @@ -429,6 +464,7 @@ static void r300_update_rs_block(struct r300_context *r300) i, sprite_coord ? " (sprite coord)" : ""); } tex_count++; + tex_ptr += sprite_coord ? 2 : 4; } else { /* Skip the FS input register, leave it uninitialized. */ /* If we try to set it to (0,0,0,1), it will lock up. */ @@ -449,7 +485,7 @@ static void r300_update_rs_block(struct r300_context *r300) stream_loc_notcl[loc++] = 6 + tex_count; /* Rasterize it. */ - rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_X001); + rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_X001); /* Write it to the FS input register if it's needed by the FS. */ if (fs_inputs->fog != ATTR_UNUSED) { @@ -461,6 +497,7 @@ static void r300_update_rs_block(struct r300_context *r300) DBG(r300, DBG_RS, "r300: Rasterized fog unused.\n"); } tex_count++; + tex_ptr += 4; } else { /* Skip the FS input register, leave it uninitialized. */ /* If we try to set it to (0,0,0,1), it will lock up. */ @@ -480,7 +517,7 @@ static void r300_update_rs_block(struct r300_context *r300) stream_loc_notcl[loc++] = 6 + tex_count; /* Rasterize it. */ - rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW); + rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_XYZW); /* Write it to the FS input register. */ rX00_rs_tex_write(&rs, tex_count, fp_offset); @@ -489,6 +526,7 @@ static void r300_update_rs_block(struct r300_context *r300) fp_offset++; tex_count++; + tex_ptr += 4; } /* Invalidate the rest of the no-TCL (GA) stream locations. */ @@ -507,7 +545,7 @@ static void r300_update_rs_block(struct r300_context *r300) DBG(r300, DBG_RS, "r300: --- Rasterizer status ---: colors: %i, " "generics: %i.\n", col_count, tex_count); - rs.count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) | + rs.count = MIN2(tex_ptr, 32) | (col_count << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; count = MAX3(col_count, tex_count, 1); @@ -528,15 +566,9 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) struct r300_sampler_state *sampler; struct r300_sampler_view *view; struct r300_texture *tex; - unsigned min_level, max_level, i, size; + unsigned min_level, max_level, i, j, size; unsigned count = MIN2(state->sampler_view_count, state->sampler_state_count); - unsigned char depth_swizzle[4] = { - UTIL_FORMAT_SWIZZLE_X, - UTIL_FORMAT_SWIZZLE_X, - UTIL_FORMAT_SWIZZLE_X, - UTIL_FORMAT_SWIZZLE_X - }; /* The KIL opcode fix, see below. */ if (!count && !r300->screen->caps.is_r500) @@ -563,14 +595,29 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) /* Assign a texture cache region. */ texstate->format.format1 |= view->texcache_region; - /* If compare mode is disabled, the sampler view swizzles - * are stored in the format. - * Otherwise, swizzles must be applied after the compare mode - * in the fragment shader. */ - if (util_format_is_depth_or_stencil(tex->b.b.format)) { + /* Depth textures are kinda special. */ + if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) { + unsigned char depth_swizzle[4]; + + if (!r300->screen->caps.is_r500 && + util_format_get_blocksizebits(tex->desc.b.b.format) == 32) { + /* X24x8 is sampled as Y16X16 on r3xx-r4xx. + * The depth here is at the Y component. */ + for (j = 0; j < 4; j++) + depth_swizzle[j] = UTIL_FORMAT_SWIZZLE_Y; + } else { + for (j = 0; j < 4; j++) + depth_swizzle[j] = UTIL_FORMAT_SWIZZLE_X; + } + + /* If compare mode is disabled, sampler view swizzles + * are stored in the format. + * Otherwise, the swizzles must be applied after the compare + * mode in the fragment shader. */ if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) { texstate->format.format1 |= - r300_get_swizzle_combined(depth_swizzle, view->swizzle); + r300_get_swizzle_combined(depth_swizzle, + view->swizzle); } else { texstate->format.format1 |= r300_get_swizzle_combined(depth_swizzle, 0); @@ -578,12 +625,12 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) } /* to emulate 1D textures through 2D ones correctly */ - if (tex->b.b.target == PIPE_TEXTURE_1D) { + if (tex->desc.b.b.target == PIPE_TEXTURE_1D) { texstate->filter0 &= ~R300_TX_WRAP_T_MASK; texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE); } - if (tex->uses_pitch) { + if (tex->desc.is_npot) { /* NPOT textures don't support mip filter, unfortunately. * This prevents incorrect rendering. */ texstate->filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK; @@ -610,7 +657,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) /* determine min/max levels */ /* the MAX_MIP level is the largest (finest) one */ max_level = MIN3(sampler->max_lod + view->base.first_level, - tex->b.b.last_level, view->base.last_level); + tex->desc.b.b.last_level, view->base.last_level); min_level = MIN2(sampler->min_lod + view->base.first_level, max_level); texstate->format.format0 |= R300_TX_NUM_LEVELS(max_level); @@ -665,8 +712,44 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300) } } +/* We can't use compressed zbuffers as samplers. */ +static void r300_flush_depth_textures(struct r300_context *r300) +{ + struct r300_textures_state *state = + (struct r300_textures_state*)r300->textures_state.state; + unsigned i, level; + unsigned count = MIN2(state->sampler_view_count, + state->sampler_state_count); + + if (r300->z_decomp_rd) + return; + + for (i = 0; i < count; i++) + if (state->sampler_views[i] && state->sampler_states[i]) { + struct pipe_resource *tex = state->sampler_views[i]->base.texture; + + if (tex->target == PIPE_TEXTURE_3D || + tex->target == PIPE_TEXTURE_CUBE) + continue; + + /* Ignore non-depth textures. + * Also ignore reinterpreted depth textures, e.g. resource_copy. */ + if (!util_format_is_depth_or_stencil(tex->format)) + continue; + + for (level = 0; level <= tex->last_level; level++) + if (r300_texture(tex)->zmask_in_use[level]) { + /* We don't handle 3D textures and cubemaps yet. */ + r300_flush_depth_stencil(&r300->context, tex, + u_subresource(0, level), 0); + } + } +} + void r300_update_derived_state(struct r300_context* r300) { + r300_flush_depth_textures(r300); + if (r300->textures_state.dirty) { r300_merge_textures_and_samplers(r300); } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 5750bc4329f..da8eadd3b53 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -26,6 +26,7 @@ #include "r300_context.h" #include "r300_reg.h" +#include "r300_texture_desc.h" #include "r300_transfer.h" #include "r300_screen.h" #include "r300_winsys.h" @@ -34,14 +35,10 @@ #include "util/u_format_s3tc.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_mm.h" #include "pipe/p_screen.h" -enum r300_dim { - DIM_WIDTH = 0, - DIM_HEIGHT = 1 -}; - unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, const unsigned char *swizzle_view) { @@ -109,7 +106,8 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, * The FORMAT specifies how the texture sampler will treat the texture, and * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */ uint32_t r300_translate_texformat(enum pipe_format format, - const unsigned char *swizzle_view) + const unsigned char *swizzle_view, + boolean is_r500) { uint32_t result = 0; const struct util_format_description *desc; @@ -134,7 +132,10 @@ uint32_t r300_translate_texformat(enum pipe_format format, return R300_TX_FORMAT_X16; case PIPE_FORMAT_X8Z24_UNORM: case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - return R500_TX_FORMAT_Y8X24; + if (is_r500) + return R500_TX_FORMAT_Y8X24; + else + return R300_TX_FORMAT_Y16X16; default: return ~0; /* Unsupported. */ } @@ -537,26 +538,27 @@ boolean r300_is_zs_format_supported(enum pipe_format format) boolean r300_is_sampler_format_supported(enum pipe_format format) { - return r300_translate_texformat(format, 0) != ~0; + return r300_translate_texformat(format, 0, TRUE) != ~0; } static void r300_texture_setup_immutable_state(struct r300_screen* screen, struct r300_texture* tex) { struct r300_texture_format_state* f = &tex->tx_format; - struct pipe_resource *pt = &tex->b.b; + struct pipe_resource *pt = &tex->desc.b.b; boolean is_r500 = screen->caps.is_r500; /* Set sampler state. */ f->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) | R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff); - if (tex->uses_pitch) { + if (tex->desc.uses_stride_addressing) { /* rectangles love this */ f->format0 |= R300_TX_PITCH_EN; - f->format2 = (tex->hwpitch[0] - 1) & 0x1fff; + f->format2 = (tex->desc.stride_in_pixels[0] - 1) & 0x1fff; } else { - /* power of two textures (3D, mipmaps, and no pitch) */ + /* Power of two textures (3D, mipmaps, and no pitch), + * also NPOT textures with a width being POT. */ f->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf); } @@ -579,8 +581,8 @@ static void r300_texture_setup_immutable_state(struct r300_screen* screen, } } - f->tile_config = R300_TXO_MACRO_TILE(tex->macrotile) | - R300_TXO_MICRO_TILE(tex->microtile); + f->tile_config = R300_TXO_MACRO_TILE(tex->desc.macrotile[0]) | + R300_TXO_MICRO_TILE(tex->desc.microtile); } static void r300_texture_setup_fb_state(struct r300_screen* screen, @@ -589,23 +591,23 @@ static void r300_texture_setup_fb_state(struct r300_screen* screen, unsigned i; /* Set framebuffer state. */ - if (util_format_is_depth_or_stencil(tex->b.b.format)) { - for (i = 0; i <= tex->b.b.last_level; i++) { + if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) { + for (i = 0; i <= tex->desc.b.b.last_level; i++) { tex->fb_state.pitch[i] = - tex->hwpitch[i] | - R300_DEPTHMACROTILE(tex->mip_macrotile[i]) | - R300_DEPTHMICROTILE(tex->microtile); + tex->desc.stride_in_pixels[i] | + R300_DEPTHMACROTILE(tex->desc.macrotile[i]) | + R300_DEPTHMICROTILE(tex->desc.microtile); } - tex->fb_state.format = r300_translate_zsformat(tex->b.b.format); + tex->fb_state.format = r300_translate_zsformat(tex->desc.b.b.format); } else { - for (i = 0; i <= tex->b.b.last_level; i++) { + for (i = 0; i <= tex->desc.b.b.last_level; i++) { tex->fb_state.pitch[i] = - tex->hwpitch[i] | - r300_translate_colorformat(tex->b.b.format) | - R300_COLOR_TILE(tex->mip_macrotile[i]) | - R300_COLOR_MICROTILE(tex->microtile); + tex->desc.stride_in_pixels[i] | + r300_translate_colorformat(tex->desc.b.b.format) | + R300_COLOR_TILE(tex->desc.macrotile[i]) | + R300_COLOR_MICROTILE(tex->desc.microtile); } - tex->fb_state.format = r300_translate_out_fmt(tex->b.b.format); + tex->fb_state.format = r300_translate_out_fmt(tex->desc.b.b.format); } } @@ -625,282 +627,6 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen, r300_texture_setup_fb_state(r300_screen(screen), r300_texture(tex)); } -unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, - unsigned zslice, unsigned face) -{ - unsigned offset = tex->offset[level]; - - switch (tex->b.b.target) { - case PIPE_TEXTURE_3D: - assert(face == 0); - return offset + zslice * tex->layer_size[level]; - - case PIPE_TEXTURE_CUBE: - assert(zslice == 0); - return offset + face * tex->layer_size[level]; - - default: - assert(zslice == 0 && face == 0); - return offset; - } -} - -/* Returns the number of pixels that the texture should be aligned to - * in the given dimension. */ -static unsigned r300_get_pixel_alignment(struct r300_texture *tex, - enum r300_buffer_tiling macrotile, - enum r300_dim dim) -{ - static const unsigned table[2][5][3][2] = - { - { - /* Macro: linear linear linear - Micro: linear tiled square-tiled */ - {{ 32, 1}, { 8, 4}, { 0, 0}}, /* 8 bits per pixel */ - {{ 16, 1}, { 8, 2}, { 4, 4}}, /* 16 bits per pixel */ - {{ 8, 1}, { 4, 2}, { 0, 0}}, /* 32 bits per pixel */ - {{ 4, 1}, { 0, 0}, { 2, 2}}, /* 64 bits per pixel */ - {{ 2, 1}, { 0, 0}, { 0, 0}} /* 128 bits per pixel */ - }, - { - /* Macro: tiled tiled tiled - Micro: linear tiled square-tiled */ - {{256, 8}, {64, 32}, { 0, 0}}, /* 8 bits per pixel */ - {{128, 8}, {64, 16}, {32, 32}}, /* 16 bits per pixel */ - {{ 64, 8}, {32, 16}, { 0, 0}}, /* 32 bits per pixel */ - {{ 32, 8}, { 0, 0}, {16, 16}}, /* 64 bits per pixel */ - {{ 16, 8}, { 0, 0}, { 0, 0}} /* 128 bits per pixel */ - } - }; - static const unsigned aa_block[2] = {4, 8}; - unsigned res = 0; - unsigned pixsize = util_format_get_blocksize(tex->b.b.format); - - assert(macrotile <= R300_BUFFER_TILED); - assert(tex->microtile <= R300_BUFFER_SQUARETILED); - assert(pixsize <= 16); - assert(dim <= DIM_HEIGHT); - - if (tex->b.b.nr_samples > 1) { - /* Multisampled textures have their own alignment scheme. */ - if (pixsize == 4) - res = aa_block[dim]; - } else { - /* Standard alignment. */ - res = table[macrotile][util_logbase2(pixsize)][tex->microtile][dim]; - } - - assert(res); - return res; -} - -/* Return true if macrotiling should be enabled on the miplevel. */ -static boolean r300_texture_macro_switch(struct r300_texture *tex, - unsigned level, - boolean rv350_mode, - enum r300_dim dim) -{ - unsigned tile, texdim; - - tile = r300_get_pixel_alignment(tex, R300_BUFFER_TILED, dim); - if (dim == DIM_WIDTH) { - texdim = u_minify(tex->b.b.width0, level); - } else { - texdim = u_minify(tex->b.b.height0, level); - } - - /* See TX_FILTER1_n.MACRO_SWITCH. */ - if (rv350_mode) { - return texdim >= tile; - } else { - return texdim > tile; - } -} - -/** - * Return the stride, in bytes, of the texture images of the given texture - * at the given level. - */ -unsigned r300_texture_get_stride(struct r300_screen* screen, - struct r300_texture* tex, unsigned level) -{ - unsigned tile_width, width, stride; - - if (tex->stride_override) - return tex->stride_override; - - /* Check the level. */ - if (level > tex->b.b.last_level) { - SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n", - __FUNCTION__, level, tex->b.b.last_level); - return 0; - } - - width = u_minify(tex->b.b.width0, level); - - if (util_format_is_plain(tex->b.b.format)) { - tile_width = r300_get_pixel_alignment(tex, tex->mip_macrotile[level], - DIM_WIDTH); - width = align(width, tile_width); - - stride = util_format_get_stride(tex->b.b.format, width); - - /* Some IGPs need a minimum stride of 64 bytes, hmm... - * This doesn't seem to apply to tiled textures, according to r300c. */ - if (!tex->microtile && !tex->mip_macrotile[level] && - (screen->caps.family == CHIP_FAMILY_RS600 || - screen->caps.family == CHIP_FAMILY_RS690 || - screen->caps.family == CHIP_FAMILY_RS740)) { - return stride < 64 ? 64 : stride; - } - - /* The alignment to 32 bytes is sort of implied by the layout... */ - return stride; - } else { - return align(util_format_get_stride(tex->b.b.format, width), 32); - } -} - -static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, - unsigned level) -{ - unsigned height, tile_height; - - height = u_minify(tex->b.b.height0, level); - - if (util_format_is_plain(tex->b.b.format)) { - tile_height = r300_get_pixel_alignment(tex, tex->mip_macrotile[level], - DIM_HEIGHT); - height = align(height, tile_height); - - /* This is needed for the kernel checker, unfortunately. */ - height = util_next_power_of_two(height); - } - - return util_format_get_nblocksy(tex->b.b.format, height); -} - -static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen, - struct r300_texture *tex) -{ - /* The kernels <= 2.6.34-rc4 compute the size of mipmapped 3D textures - * incorrectly. This is a workaround to prevent CS from being rejected. */ - - unsigned i, size; - - if (!screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) && - tex->b.b.target == PIPE_TEXTURE_3D && - tex->b.b.last_level > 0) { - size = 0; - - for (i = 0; i <= tex->b.b.last_level; i++) { - size += r300_texture_get_stride(screen, tex, i) * - r300_texture_get_nblocksy(tex, i); - } - - size *= tex->b.b.depth0; - tex->size = size; - } -} - -static void r300_setup_miptree(struct r300_screen* screen, - struct r300_texture* tex) -{ - struct pipe_resource* base = &tex->b.b; - unsigned stride, size, layer_size, nblocksy, i; - boolean rv350_mode = screen->caps.is_rv350; - - SCREEN_DBG(screen, DBG_TEXALLOC, - "r300: Making miptree for texture, format %s\n", - util_format_short_name(base->format)); - - for (i = 0; i <= base->last_level; i++) { - /* Let's see if this miplevel can be macrotiled. */ - tex->mip_macrotile[i] = - (tex->macrotile == R300_BUFFER_TILED && - r300_texture_macro_switch(tex, i, rv350_mode, DIM_WIDTH) && - r300_texture_macro_switch(tex, i, rv350_mode, DIM_HEIGHT)) ? - R300_BUFFER_TILED : R300_BUFFER_LINEAR; - - stride = r300_texture_get_stride(screen, tex, i); - nblocksy = r300_texture_get_nblocksy(tex, i); - layer_size = stride * nblocksy; - - if (base->nr_samples) { - layer_size *= base->nr_samples; - } - - if (base->target == PIPE_TEXTURE_CUBE) - size = layer_size * 6; - else - size = layer_size * u_minify(base->depth0, i); - - tex->offset[i] = tex->size; - tex->size = tex->offset[i] + size; - tex->layer_size[i] = layer_size; - tex->pitch[i] = stride / util_format_get_blocksize(base->format); - tex->hwpitch[i] = - tex->pitch[i] * util_format_get_blockwidth(base->format); - - SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d " - "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n", - i, u_minify(base->width0, i), u_minify(base->height0, i), - u_minify(base->depth0, i), stride, tex->size, - tex->mip_macrotile[i] ? "TRUE" : "FALSE"); - } -} - -static void r300_setup_flags(struct r300_texture* tex) -{ - tex->uses_pitch = !util_is_power_of_two(tex->b.b.width0) || - !util_is_power_of_two(tex->b.b.height0) || - tex->stride_override; -} - -static void r300_setup_tiling(struct pipe_screen *screen, - struct r300_texture *tex) -{ - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; - enum pipe_format format = tex->b.b.format; - boolean rv350_mode = r300_screen(screen)->caps.is_rv350; - boolean is_zb = util_format_is_depth_or_stencil(format); - boolean dbg_no_tiling = SCREEN_DBG_ON(r300_screen(screen), DBG_NO_TILING); - - if (!util_format_is_plain(format)) { - return; - } - - /* If height == 1, disable microtiling except for zbuffer. */ - if (!is_zb && (tex->b.b.height0 == 1 || dbg_no_tiling)) { - return; - } - - /* Set microtiling. */ - switch (util_format_get_blocksize(format)) { - case 1: - case 4: - tex->microtile = R300_BUFFER_TILED; - break; - - case 2: - case 8: - if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) { - tex->microtile = R300_BUFFER_SQUARETILED; - } - break; - } - - if (dbg_no_tiling) { - return; - } - - /* Set macrotiling. */ - if (r300_texture_macro_switch(tex, 0, rv350_mode, DIM_WIDTH) && - r300_texture_macro_switch(tex, 0, rv350_mode, DIM_HEIGHT)) { - tex->macrotile = R300_BUFFER_TILED; - } -} - static unsigned r300_texture_is_referenced(struct pipe_context *context, struct pipe_resource *texture, unsigned face, unsigned level) @@ -920,8 +646,16 @@ static void r300_texture_destroy(struct pipe_screen *screen, { struct r300_texture* tex = (struct r300_texture*)texture; struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys; + int i; rws->buffer_reference(rws, &tex->buffer, NULL); + for (i = 0; i < R300_MAX_TEXTURE_LEVELS; i++) { + if (tex->hiz_mem[i]) + u_mmFreeMem(tex->hiz_mem[i]); + if (tex->zmask_mem[i]) + u_mmFreeMem(tex->zmask_mem[i]); + } + FREE(tex); } @@ -937,11 +671,10 @@ static boolean r300_texture_get_handle(struct pipe_screen* screen, } return rws->buffer_get_handle(rws, tex->buffer, - r300_texture_get_stride(r300_screen(screen), tex, 0), - whandle); + tex->desc.stride_in_bytes[0], whandle); } -struct u_resource_vtbl r300_texture_vtbl = +struct u_resource_vtbl r300_texture_vtbl = { r300_texture_get_handle, /* get_handle */ r300_texture_destroy, /* resource_destroy */ @@ -954,17 +687,69 @@ struct u_resource_vtbl r300_texture_vtbl = u_default_transfer_inline_write /* transfer_inline_write */ }; -/* Create a new texture. */ -struct pipe_resource* r300_texture_create(struct pipe_screen* screen, - const struct pipe_resource* base) +/* The common texture constructor. */ +static struct r300_texture* +r300_texture_create_object(struct r300_screen *rscreen, + const struct pipe_resource *base, + enum r300_buffer_tiling microtile, + enum r300_buffer_tiling macrotile, + unsigned stride_in_bytes_override, + unsigned max_buffer_size, + struct r300_winsys_buffer *buffer) { - struct r300_texture* tex = CALLOC_STRUCT(r300_texture); - struct r300_screen* rscreen = r300_screen(screen); - struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys; - + struct r300_winsys_screen *rws = rscreen->rws; + struct r300_texture *tex = CALLOC_STRUCT(r300_texture); if (!tex) { + if (buffer) + rws->buffer_reference(rws, &buffer, NULL); + return NULL; + } + + /* Initialize the descriptor. */ + if (!r300_texture_desc_init(rscreen, &tex->desc, base, + microtile, macrotile, + stride_in_bytes_override, + max_buffer_size)) { + if (buffer) + rws->buffer_reference(rws, &buffer, NULL); + FREE(tex); return NULL; } + /* Initialize the hardware state. */ + r300_texture_setup_immutable_state(rscreen, tex); + r300_texture_setup_fb_state(rscreen, tex); + + tex->desc.b.vtbl = &r300_texture_vtbl; + pipe_reference_init(&tex->desc.b.b.reference, 1); + tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ? + R300_DOMAIN_GTT : + R300_DOMAIN_VRAM | R300_DOMAIN_GTT; + tex->buffer = buffer; + + /* Create the backing buffer if needed. */ + if (!tex->buffer) { + tex->buffer = rws->buffer_create(rws, tex->desc.size_in_bytes, 2048, + base->bind, base->usage, tex->domain); + + if (!tex->buffer) { + FREE(tex); + return NULL; + } + } + + rws->buffer_set_tiling(rws, tex->buffer, + tex->desc.microtile, tex->desc.macrotile[0], + tex->desc.stride_in_bytes[0]); + + return tex; +} + +/* Create a new texture. */ +struct pipe_resource *r300_texture_create(struct pipe_screen *screen, + const struct pipe_resource *base) +{ + struct r300_screen *rscreen = r300_screen(screen); + enum r300_buffer_tiling microtile, macrotile; /* Refuse to create a texture with size 0. */ if (!base->width0 || @@ -974,58 +759,70 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen, fprintf(stderr, "r300: texture_create: " "Got invalid texture dimensions: %ix%ix%i\n", base->width0, base->height0, base->depth0); - FREE(tex); return NULL; } - tex->b.b = *base; - tex->b.vtbl = &r300_texture_vtbl; - pipe_reference_init(&tex->b.b.reference, 1); - tex->b.b.screen = screen; + if ((base->flags & R300_RESOURCE_FLAG_TRANSFER) || + (base->bind & PIPE_BIND_SCANOUT)) { + microtile = R300_BUFFER_LINEAR; + macrotile = R300_BUFFER_LINEAR; + } else { + microtile = R300_BUFFER_SELECT_LAYOUT; + macrotile = R300_BUFFER_SELECT_LAYOUT; + } + + return (struct pipe_resource*) + r300_texture_create_object(rscreen, base, microtile, macrotile, + 0, 0, NULL); +} + +struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen, + const struct pipe_resource *base, + struct winsys_handle *whandle) +{ + struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys; + struct r300_screen *rscreen = r300_screen(screen); + struct r300_winsys_buffer *buffer; + enum r300_buffer_tiling microtile, macrotile; + unsigned stride, size; - r300_setup_flags(tex); - if (!(base->flags & R300_RESOURCE_FLAG_TRANSFER) && - !(base->bind & PIPE_BIND_SCANOUT)) { - r300_setup_tiling(screen, tex); + /* Support only 2D textures without mipmaps */ + if (base->target != PIPE_TEXTURE_2D || + base->depth0 != 1 || + base->last_level != 0) { + return NULL; } - r300_setup_miptree(rscreen, tex); - r300_texture_3d_fix_mipmapping(rscreen, tex); - r300_texture_setup_immutable_state(rscreen, tex); - r300_texture_setup_fb_state(rscreen, tex); - SCREEN_DBG(rscreen, DBG_TEX, - "r300: texture_create: Macro: %s, Micro: %s, Pitch: %i, " - "Dim: %ix%ix%i, LastLevel: %i, Size: %i, Format: %s\n", - tex->macrotile ? "YES" : " NO", - tex->microtile ? "YES" : " NO", - tex->hwpitch[0], - base->width0, base->height0, base->depth0, base->last_level, - tex->size, - util_format_short_name(base->format)); + buffer = rws->buffer_from_handle(rws, whandle, &stride, &size); + if (!buffer) + return NULL; - tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ? - R300_DOMAIN_GTT : - R300_DOMAIN_VRAM | R300_DOMAIN_GTT; + rws->buffer_get_tiling(rws, buffer, µtile, ¯otile); - tex->buffer = rws->buffer_create(rws, tex->size, 2048, base->bind, - base->usage, tex->domain); + /* Enforce a microtiled zbuffer. */ + if (util_format_is_depth_or_stencil(base->format) && + microtile == R300_BUFFER_LINEAR) { + switch (util_format_get_blocksize(base->format)) { + case 4: + microtile = R300_BUFFER_TILED; + break; - if (!tex->buffer) { - FREE(tex); - return NULL; + case 2: + if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) + microtile = R300_BUFFER_SQUARETILED; + break; + } } - rws->buffer_set_tiling(rws, tex->buffer, - tex->microtile, tex->macrotile, - tex->pitch[0] * util_format_get_blocksize(tex->b.b.format)); - - return (struct pipe_resource*)tex; + return (struct pipe_resource*) + r300_texture_create_object(rscreen, base, microtile, macrotile, + stride, size, buffer); } /* Not required to implement u_resource_vtbl, consider moving to another file: */ struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, - struct pipe_resource* texture, + struct pipe_resource* texture, unsigned face, unsigned level, unsigned zslice, @@ -1035,7 +832,7 @@ struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, struct r300_surface* surface = CALLOC_STRUCT(r300_surface); if (surface) { - uint32_t stride, offset, tile_height; + uint32_t offset, tile_height; pipe_reference_init(&surface->base.reference, 1); pipe_resource_reference(&surface->base.texture, texture); @@ -1054,23 +851,29 @@ struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, if (surface->domain & R300_DOMAIN_VRAM) surface->domain &= ~R300_DOMAIN_GTT; - surface->offset = r300_texture_get_offset(tex, level, zslice, face); + surface->offset = r300_texture_get_offset(&tex->desc, + level, zslice, face); surface->pitch = tex->fb_state.pitch[level]; surface->format = tex->fb_state.format; /* Parameters for the CBZB clear. */ + surface->cbzb_allowed = tex->desc.cbzb_allowed[level]; surface->cbzb_width = align(surface->base.width, 64); /* Height must be aligned to the size of a tile. */ - tile_height = r300_get_pixel_alignment(tex, tex->mip_macrotile[level], + tile_height = r300_get_pixel_alignment(tex->desc.b.b.format, + tex->desc.b.b.nr_samples, + tex->desc.microtile, + tex->desc.macrotile[level], DIM_HEIGHT); + surface->cbzb_height = align((surface->base.height + 1) / 2, tile_height); /* Offset must be aligned to 2K and must point at the beginning * of a scanline. */ - stride = r300_texture_get_stride(r300_screen(screen), tex, level); - offset = surface->offset + stride * surface->cbzb_height; + offset = surface->offset + + tex->desc.stride_in_bytes[level] * surface->cbzb_height; surface->cbzb_midpoint_offset = offset & ~2047; surface->cbzb_pitch = surface->pitch & 0x1ffffc; @@ -1080,11 +883,11 @@ struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, else surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z; - SCREEN_DBG(r300_screen(screen), DBG_TEX, + SCREEN_DBG(r300_screen(screen), DBG_CBZB, "CBZB Dim: %ix%i, Misalignment: %i, Macro: %s\n", surface->cbzb_width, surface->cbzb_height, offset & 2047, - tex->mip_macrotile[level] ? "YES" : " NO"); + tex->desc.macrotile[level] ? "YES" : " NO"); } return &surface->base; @@ -1097,88 +900,3 @@ void r300_tex_surface_destroy(struct pipe_surface* s) pipe_resource_reference(&s->texture, NULL); FREE(s); } - -struct pipe_resource* -r300_texture_from_handle(struct pipe_screen* screen, - const struct pipe_resource* base, - struct winsys_handle *whandle) -{ - struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys; - struct r300_screen* rscreen = r300_screen(screen); - struct r300_winsys_buffer *buffer; - struct r300_texture* tex; - unsigned stride; - boolean override_zb_flags; - - /* Support only 2D textures without mipmaps */ - if (base->target != PIPE_TEXTURE_2D || - base->depth0 != 1 || - base->last_level != 0) { - return NULL; - } - - buffer = rws->buffer_from_handle(rws, whandle, &stride); - if (!buffer) { - return NULL; - } - - tex = CALLOC_STRUCT(r300_texture); - if (!tex) { - return NULL; - } - - tex->b.b = *base; - tex->b.vtbl = &r300_texture_vtbl; - pipe_reference_init(&tex->b.b.reference, 1); - tex->b.b.screen = screen; - tex->domain = R300_DOMAIN_VRAM; - - tex->stride_override = stride; - - /* one ref already taken */ - tex->buffer = buffer; - - rws->buffer_get_tiling(rws, buffer, &tex->microtile, &tex->macrotile); - r300_setup_flags(tex); - SCREEN_DBG(rscreen, DBG_TEX, - "r300: texture_from_handle: Macro: %s, Micro: %s, " - "Pitch: % 4i, Dim: %ix%i, Format: %s\n", - tex->macrotile ? "YES" : " NO", - tex->microtile ? "YES" : " NO", - stride / util_format_get_blocksize(base->format), - base->width0, base->height0, - util_format_short_name(base->format)); - - /* Enforce microtiled zbuffer. */ - override_zb_flags = util_format_is_depth_or_stencil(base->format) && - tex->microtile == R300_BUFFER_LINEAR; - - if (override_zb_flags) { - switch (util_format_get_blocksize(base->format)) { - case 4: - tex->microtile = R300_BUFFER_TILED; - break; - - case 2: - if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) { - tex->microtile = R300_BUFFER_SQUARETILED; - break; - } - /* Pass through. */ - - default: - override_zb_flags = FALSE; - } - } - - r300_setup_miptree(rscreen, tex); - r300_texture_setup_immutable_state(rscreen, tex); - r300_texture_setup_fb_state(rscreen, tex); - - if (override_zb_flags) { - rws->buffer_set_tiling(rws, tex->buffer, - tex->microtile, tex->macrotile, - tex->pitch[0] * util_format_get_blocksize(tex->b.b.format)); - } - return (struct pipe_resource*)tex; -} diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 99e7694254e..a4524320fda 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -35,16 +35,11 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format, const unsigned char *swizzle_view); uint32_t r300_translate_texformat(enum pipe_format format, - const unsigned char *swizzle_view); + const unsigned char *swizzle_view, + boolean is_r500); uint32_t r500_tx_format_msb_bit(enum pipe_format format); -unsigned r300_texture_get_stride(struct r300_screen* screen, - struct r300_texture* tex, unsigned level); - -unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, - unsigned zslice, unsigned face); - void r300_texture_reinterpret_format(struct pipe_screen *screen, struct pipe_resource *tex, enum pipe_format new_format); diff --git a/src/gallium/drivers/r300/r300_texture_desc.c b/src/gallium/drivers/r300/r300_texture_desc.c new file mode 100644 index 00000000000..5d690e8c332 --- /dev/null +++ b/src/gallium/drivers/r300/r300_texture_desc.c @@ -0,0 +1,479 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Copyright 2010 Marek Olšák <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "r300_texture_desc.h" + +#include "r300_context.h" +#include "r300_winsys.h" + +#include "util/u_format.h" + +/* Returns the number of pixels that the texture should be aligned to + * in the given dimension. */ +unsigned r300_get_pixel_alignment(enum pipe_format format, + unsigned num_samples, + enum r300_buffer_tiling microtile, + enum r300_buffer_tiling macrotile, + enum r300_dim dim) +{ + static const unsigned table[2][5][3][2] = + { + { + /* Macro: linear linear linear + Micro: linear tiled square-tiled */ + {{ 32, 1}, { 8, 4}, { 0, 0}}, /* 8 bits per pixel */ + {{ 16, 1}, { 8, 2}, { 4, 4}}, /* 16 bits per pixel */ + {{ 8, 1}, { 4, 2}, { 0, 0}}, /* 32 bits per pixel */ + {{ 4, 1}, { 0, 0}, { 2, 2}}, /* 64 bits per pixel */ + {{ 2, 1}, { 0, 0}, { 0, 0}} /* 128 bits per pixel */ + }, + { + /* Macro: tiled tiled tiled + Micro: linear tiled square-tiled */ + {{256, 8}, {64, 32}, { 0, 0}}, /* 8 bits per pixel */ + {{128, 8}, {64, 16}, {32, 32}}, /* 16 bits per pixel */ + {{ 64, 8}, {32, 16}, { 0, 0}}, /* 32 bits per pixel */ + {{ 32, 8}, { 0, 0}, {16, 16}}, /* 64 bits per pixel */ + {{ 16, 8}, { 0, 0}, { 0, 0}} /* 128 bits per pixel */ + } + }; + static const unsigned aa_block[2] = {4, 8}; + unsigned tile = 0; + unsigned pixsize = util_format_get_blocksize(format); + + assert(macrotile <= R300_BUFFER_TILED); + assert(microtile <= R300_BUFFER_SQUARETILED); + assert(pixsize <= 16); + assert(dim <= DIM_HEIGHT); + + if (num_samples > 1) { + /* Multisampled textures have their own alignment scheme. */ + if (pixsize == 4) + tile = aa_block[dim]; + /* XXX FP16 AA. */ + } else { + /* Standard alignment. */ + tile = table[macrotile][util_logbase2(pixsize)][microtile][dim]; + } + + assert(tile); + return tile; +} + +/* Return true if macrotiling should be enabled on the miplevel. */ +static boolean r300_texture_macro_switch(struct r300_texture_desc *desc, + unsigned level, + boolean rv350_mode, + enum r300_dim dim) +{ + unsigned tile, texdim; + + tile = r300_get_pixel_alignment(desc->b.b.format, desc->b.b.nr_samples, + desc->microtile, R300_BUFFER_TILED, dim); + if (dim == DIM_WIDTH) { + texdim = u_minify(desc->b.b.width0, level); + } else { + texdim = u_minify(desc->b.b.height0, level); + } + + /* See TX_FILTER1_n.MACRO_SWITCH. */ + if (rv350_mode) { + return texdim >= tile; + } else { + return texdim > tile; + } +} + +/** + * Return the stride, in bytes, of the texture image of the given texture + * at the given level. + */ +static unsigned r300_texture_get_stride(struct r300_screen *screen, + struct r300_texture_desc *desc, + unsigned level) +{ + unsigned tile_width, width, stride; + + if (desc->stride_in_bytes_override) + return desc->stride_in_bytes_override; + + /* Check the level. */ + if (level > desc->b.b.last_level) { + SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n", + __FUNCTION__, level, desc->b.b.last_level); + return 0; + } + + width = u_minify(desc->b.b.width0, level); + + if (util_format_is_plain(desc->b.b.format)) { + tile_width = r300_get_pixel_alignment(desc->b.b.format, + desc->b.b.nr_samples, + desc->microtile, + desc->macrotile[level], + DIM_WIDTH); + width = align(width, tile_width); + + stride = util_format_get_stride(desc->b.b.format, width); + + /* Some IGPs need a minimum stride of 64 bytes, hmm... */ + if (!desc->macrotile[level] && + (screen->caps.family == CHIP_FAMILY_RS600 || + screen->caps.family == CHIP_FAMILY_RS690 || + screen->caps.family == CHIP_FAMILY_RS740)) { + unsigned min_stride; + + if (desc->microtile) { + unsigned tile_height = + r300_get_pixel_alignment(desc->b.b.format, + desc->b.b.nr_samples, + desc->microtile, + desc->macrotile[level], + DIM_HEIGHT); + + min_stride = 64 / tile_height; + } else { + min_stride = 64; + } + + return stride < min_stride ? min_stride : stride; + } + + /* The alignment to 32 bytes is sort of implied by the layout... */ + return stride; + } else { + return align(util_format_get_stride(desc->b.b.format, width), 32); + } +} + +static unsigned r300_texture_get_nblocksy(struct r300_texture_desc *desc, + unsigned level, + boolean *out_aligned_for_cbzb) +{ + unsigned height, tile_height; + + height = u_minify(desc->b.b.height0, level); + + if (util_format_is_plain(desc->b.b.format)) { + tile_height = r300_get_pixel_alignment(desc->b.b.format, + desc->b.b.nr_samples, + desc->microtile, + desc->macrotile[level], + DIM_HEIGHT); + height = align(height, tile_height); + + /* This is needed for the kernel checker, unfortunately. */ + if ((desc->b.b.target != PIPE_TEXTURE_1D && + desc->b.b.target != PIPE_TEXTURE_2D) || + desc->b.b.last_level != 0) { + height = util_next_power_of_two(height); + } + + /* See if the CBZB clear can be used on the buffer, + * taking the texture size into account. */ + if (out_aligned_for_cbzb) { + if (desc->macrotile[level]) { + /* When clearing, the layer (width*height) is horizontally split + * into two, and the upper and lower halves are cleared by the CB + * and ZB units, respectively. Therefore, the number of macrotiles + * in the Y direction must be even. */ + + /* Align the height so that there is an even number of macrotiles. + * Do so for 3 or more macrotiles in the Y direction. */ + if (level == 0 && desc->b.b.last_level == 0 && + (desc->b.b.target == PIPE_TEXTURE_1D || + desc->b.b.target == PIPE_TEXTURE_2D) && + height >= tile_height * 3) { + height = align(height, tile_height * 2); + } + + *out_aligned_for_cbzb = height % (tile_height * 2) == 0; + } else { + *out_aligned_for_cbzb = FALSE; + } + } + } + + return util_format_get_nblocksy(desc->b.b.format, height); +} + +static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen, + struct r300_texture_desc *desc) +{ + /* The kernels <= 2.6.34-rc4 compute the size of mipmapped 3D textures + * incorrectly. This is a workaround to prevent CS from being rejected. */ + + unsigned i, size; + + if (!screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) && + desc->b.b.target == PIPE_TEXTURE_3D && + desc->b.b.last_level > 0) { + size = 0; + + for (i = 0; i <= desc->b.b.last_level; i++) { + size += desc->stride_in_bytes[i] * + r300_texture_get_nblocksy(desc, i, FALSE); + } + + size *= desc->b.b.depth0; + desc->size_in_bytes = size; + } +} + +/* Get a width in pixels from a stride in bytes. */ +static unsigned stride_to_width(enum pipe_format format, + unsigned stride_in_bytes) +{ + return (stride_in_bytes / util_format_get_blocksize(format)) * + util_format_get_blockwidth(format); +} + +static void r300_setup_miptree(struct r300_screen *screen, + struct r300_texture_desc *desc, + boolean align_for_cbzb) +{ + struct pipe_resource *base = &desc->b.b; + unsigned stride, size, layer_size, nblocksy, i; + boolean rv350_mode = screen->caps.is_rv350; + boolean aligned_for_cbzb; + + desc->size_in_bytes = 0; + + SCREEN_DBG(screen, DBG_TEXALLOC, + "r300: Making miptree for texture, format %s\n", + util_format_short_name(base->format)); + + for (i = 0; i <= base->last_level; i++) { + /* Let's see if this miplevel can be macrotiled. */ + desc->macrotile[i] = + (desc->macrotile[0] == R300_BUFFER_TILED && + r300_texture_macro_switch(desc, i, rv350_mode, DIM_WIDTH) && + r300_texture_macro_switch(desc, i, rv350_mode, DIM_HEIGHT)) ? + R300_BUFFER_TILED : R300_BUFFER_LINEAR; + + stride = r300_texture_get_stride(screen, desc, i); + + /* Compute the number of blocks in Y, see if the CBZB clear can be + * used on the texture. */ + aligned_for_cbzb = FALSE; + if (align_for_cbzb && desc->cbzb_allowed[i]) + nblocksy = r300_texture_get_nblocksy(desc, i, &aligned_for_cbzb); + else + nblocksy = r300_texture_get_nblocksy(desc, i, NULL); + + layer_size = stride * nblocksy; + + if (base->nr_samples) { + layer_size *= base->nr_samples; + } + + if (base->target == PIPE_TEXTURE_CUBE) + size = layer_size * 6; + else + size = layer_size * u_minify(base->depth0, i); + + desc->offset_in_bytes[i] = desc->size_in_bytes; + desc->size_in_bytes = desc->offset_in_bytes[i] + size; + desc->layer_size_in_bytes[i] = layer_size; + desc->stride_in_bytes[i] = stride; + desc->stride_in_pixels[i] = stride_to_width(desc->b.b.format, stride); + desc->cbzb_allowed[i] = desc->cbzb_allowed[i] && aligned_for_cbzb; + + SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d " + "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n", + i, u_minify(base->width0, i), u_minify(base->height0, i), + u_minify(base->depth0, i), stride, desc->size_in_bytes, + desc->macrotile[i] ? "TRUE" : "FALSE"); + } +} + +static void r300_setup_flags(struct r300_texture_desc *desc) +{ + desc->uses_stride_addressing = + !util_is_power_of_two(desc->b.b.width0) || + !util_is_power_of_two(desc->b.b.height0) || + (desc->stride_in_bytes_override && + stride_to_width(desc->b.b.format, + desc->stride_in_bytes_override) != desc->b.b.width0); + + desc->is_npot = + desc->uses_stride_addressing || + !util_is_power_of_two(desc->b.b.height0); +} + +static void r300_setup_cbzb_flags(struct r300_screen *rscreen, + struct r300_texture_desc *desc) +{ + unsigned i, bpp; + boolean first_level_valid; + + bpp = util_format_get_blocksizebits(desc->b.b.format); + + /* 1) The texture must be point-sampled, + * 2) The depth must be 16 or 32 bits. + * 3) If the midpoint ZB offset is not aligned to 2048, it returns garbage + * with certain texture sizes. Macrotiling ensures the alignment. */ + first_level_valid = desc->b.b.nr_samples <= 1 && + (bpp == 16 || bpp == 32) && + desc->macrotile[0]; + + for (i = 0; i <= desc->b.b.last_level; i++) + desc->cbzb_allowed[i] = first_level_valid && desc->macrotile[i]; +} + +static void r300_setup_tiling(struct r300_screen *screen, + struct r300_texture_desc *desc) +{ + struct r300_winsys_screen *rws = screen->rws; + enum pipe_format format = desc->b.b.format; + boolean rv350_mode = screen->caps.is_rv350; + boolean is_zb = util_format_is_depth_or_stencil(format); + boolean dbg_no_tiling = SCREEN_DBG_ON(screen, DBG_NO_TILING); + + if (!util_format_is_plain(format)) { + return; + } + + /* If height == 1, disable microtiling except for zbuffer. */ + if (!is_zb && (desc->b.b.height0 == 1 || dbg_no_tiling)) { + return; + } + + /* Set microtiling. */ + switch (util_format_get_blocksize(format)) { + case 1: + case 4: + desc->microtile = R300_BUFFER_TILED; + break; + + case 2: + case 8: + if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) { + desc->microtile = R300_BUFFER_SQUARETILED; + } + break; + } + + if (dbg_no_tiling) { + return; + } + + /* Set macrotiling. */ + if (r300_texture_macro_switch(desc, 0, rv350_mode, DIM_WIDTH) && + r300_texture_macro_switch(desc, 0, rv350_mode, DIM_HEIGHT)) { + desc->macrotile[0] = R300_BUFFER_TILED; + } +} + +static void r300_tex_print_info(struct r300_screen *rscreen, + struct r300_texture_desc *desc, + const char *func) +{ + fprintf(stderr, + "r300: %s: Macro: %s, Micro: %s, Pitch: %i, Dim: %ix%ix%i, " + "LastLevel: %i, Size: %i, Format: %s\n", + func, + desc->macrotile[0] ? "YES" : " NO", + desc->microtile ? "YES" : " NO", + desc->stride_in_pixels[0], + desc->b.b.width0, desc->b.b.height0, desc->b.b.depth0, + desc->b.b.last_level, desc->size_in_bytes, + util_format_short_name(desc->b.b.format)); +} + +boolean r300_texture_desc_init(struct r300_screen *rscreen, + struct r300_texture_desc *desc, + const struct pipe_resource *base, + enum r300_buffer_tiling microtile, + enum r300_buffer_tiling macrotile, + unsigned stride_in_bytes_override, + unsigned max_buffer_size) +{ + desc->b.b = *base; + desc->b.b.screen = &rscreen->screen; + + desc->stride_in_bytes_override = stride_in_bytes_override; + + if (microtile == R300_BUFFER_SELECT_LAYOUT || + macrotile == R300_BUFFER_SELECT_LAYOUT) { + r300_setup_tiling(rscreen, desc); + } else { + desc->microtile = microtile; + desc->macrotile[0] = macrotile; + assert(desc->b.b.last_level == 0); + } + + r300_setup_flags(desc); + r300_setup_cbzb_flags(rscreen, desc); + + /* Setup the miptree description. */ + r300_setup_miptree(rscreen, desc, TRUE); + /* If the required buffer size is larger the given max size, + * try again without the alignment for the CBZB clear. */ + if (max_buffer_size && desc->size_in_bytes > max_buffer_size) { + r300_setup_miptree(rscreen, desc, FALSE); + } + + r300_texture_3d_fix_mipmapping(rscreen, desc); + + if (max_buffer_size) { + /* Make sure the buffer we got is large enough. */ + if (desc->size_in_bytes > max_buffer_size) { + fprintf(stderr, "r300: texture_from_handle: The buffer is not " + "large enough. Got: %i, Need: %i, Info:\n", + max_buffer_size, desc->size_in_bytes); + r300_tex_print_info(rscreen, desc, "texture_from_handle"); + return FALSE; + } + + desc->buffer_size_in_bytes = max_buffer_size; + } else { + desc->buffer_size_in_bytes = desc->size_in_bytes; + } + + if (SCREEN_DBG_ON(rscreen, DBG_TEX)) + r300_tex_print_info(rscreen, desc, "texture_from_handle"); + + return TRUE; +} + +unsigned r300_texture_get_offset(struct r300_texture_desc *desc, + unsigned level, unsigned zslice, + unsigned face) +{ + unsigned offset = desc->offset_in_bytes[level]; + + switch (desc->b.b.target) { + case PIPE_TEXTURE_3D: + assert(face == 0); + return offset + zslice * desc->layer_size_in_bytes[level]; + + case PIPE_TEXTURE_CUBE: + assert(zslice == 0); + return offset + face * desc->layer_size_in_bytes[level]; + + default: + assert(zslice == 0 && face == 0); + return offset; + } +} diff --git a/src/gallium/drivers/r300/r300_texture_desc.h b/src/gallium/drivers/r300/r300_texture_desc.h new file mode 100644 index 00000000000..95de66f6549 --- /dev/null +++ b/src/gallium/drivers/r300/r300_texture_desc.h @@ -0,0 +1,57 @@ +/* + * Copyright 2008 Corbin Simpson <[email protected]> + * Copyright 2010 Marek Olšák <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef R300_TEXTURE_DESC_H +#define R300_TEXTURE_DESC_H + +#include "r300_defines.h" + +struct pipe_resource; +struct r300_screen; +struct r300_texture_desc; +struct r300_texture; + +enum r300_dim { + DIM_WIDTH = 0, + DIM_HEIGHT = 1 +}; + +unsigned r300_get_pixel_alignment(enum pipe_format format, + unsigned num_samples, + enum r300_buffer_tiling microtile, + enum r300_buffer_tiling macrotile, + enum r300_dim dim); + +boolean r300_texture_desc_init(struct r300_screen *rscreen, + struct r300_texture_desc *desc, + const struct pipe_resource *base, + enum r300_buffer_tiling microtile, + enum r300_buffer_tiling macrotile, + unsigned stride_in_bytes_override, + unsigned max_buffer_size); + +unsigned r300_texture_get_offset(struct r300_texture_desc *desc, + unsigned level, unsigned zslice, + unsigned face); + +#endif diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index 51b2c555502..dd697b9c374 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -126,7 +126,7 @@ static unsigned translate_opcode(unsigned opcode) /* case TGSI_OPCODE_SAD: return RC_OPCODE_SAD; */ /* case TGSI_OPCODE_TXF: return RC_OPCODE_TXF; */ /* case TGSI_OPCODE_TXQ: return RC_OPCODE_TXQ; */ - /* case TGSI_OPCODE_CONT: return RC_OPCODE_CONT; */ + case TGSI_OPCODE_CONT: return RC_OPCODE_CONT; /* case TGSI_OPCODE_EMIT: return RC_OPCODE_EMIT; */ /* case TGSI_OPCODE_ENDPRIM: return RC_OPCODE_ENDPRIM; */ /* case TGSI_OPCODE_BGNLOOP2: return RC_OPCODE_BGNLOOP2; */ diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index 3cc4c8c9582..e9333b35ef5 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -22,7 +22,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "r300_transfer.h" -#include "r300_texture.h" +#include "r300_texture_desc.h" #include "r300_screen_buffer.h" #include "util/u_memory.h" @@ -35,8 +35,8 @@ struct r300_transfer { /* Offset from start of buffer. */ unsigned offset; - /* Detiled texture. */ - struct r300_texture *detiled_texture; + /* Linear texture. */ + struct r300_texture *linear_texture; }; /* Convenience cast wrapper. */ @@ -57,7 +57,7 @@ static void r300_copy_from_tiled_texture(struct pipe_context *ctx, subdst.face = 0; subdst.level = 0; - ctx->resource_copy_region(ctx, &r300transfer->detiled_texture->b.b, subdst, + ctx->resource_copy_region(ctx, &r300transfer->linear_texture->desc.b.b, subdst, 0, 0, 0, tex, transfer->sr, transfer->box.x, transfer->box.y, transfer->box.z, @@ -77,7 +77,7 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx, ctx->resource_copy_region(ctx, tex, transfer->sr, transfer->box.x, transfer->box.y, transfer->box.z, - &r300transfer->detiled_texture->b.b, subsrc, + &r300transfer->linear_texture->desc.b.b, subsrc, 0, 0, 0, transfer->box.width, transfer->box.height); @@ -93,7 +93,6 @@ r300_texture_get_transfer(struct pipe_context *ctx, { struct r300_context *r300 = r300_context(ctx); struct r300_texture *tex = r300_texture(texture); - struct r300_screen *r300screen = r300_screen(ctx->screen); struct r300_transfer *trans; struct pipe_resource base; boolean referenced_cs, referenced_hw, blittable; @@ -124,7 +123,7 @@ r300_texture_get_transfer(struct pipe_context *ctx, /* If the texture is tiled, we must create a temporary detiled texture * for this transfer. * Also make write transfers pipelined. */ - if (tex->microtile || tex->macrotile || + if (tex->desc.microtile || tex->desc.macrotile[sr.level] || ((referenced_hw & !(usage & PIPE_TRANSFER_READ)) && blittable)) { base.target = PIPE_TEXTURE_2D; base.format = texture->format; @@ -149,23 +148,23 @@ r300_texture_get_transfer(struct pipe_context *ctx, } /* Create the temporary texture. */ - trans->detiled_texture = r300_texture( + trans->linear_texture = r300_texture( ctx->screen->resource_create(ctx->screen, &base)); - if (!trans->detiled_texture) { + if (!trans->linear_texture) { /* Oh crap, the thing can't create the texture. * Let's flush and try again. */ ctx->flush(ctx, 0, NULL); - trans->detiled_texture = r300_texture( + trans->linear_texture = r300_texture( ctx->screen->resource_create(ctx->screen, &base)); - if (!trans->detiled_texture) { + if (!trans->linear_texture) { /* For linear textures, it's safe to fallback to * an unpipelined transfer. */ - if (!tex->microtile && !tex->macrotile) { + if (!tex->desc.microtile && !tex->desc.macrotile[sr.level]) { goto unpipelined; } @@ -177,8 +176,8 @@ r300_texture_get_transfer(struct pipe_context *ctx, } } - assert(!trans->detiled_texture->microtile && - !trans->detiled_texture->macrotile); + assert(!trans->linear_texture->desc.microtile && + !trans->linear_texture->desc.macrotile[0]); /* Set the stride. * @@ -188,7 +187,7 @@ r300_texture_get_transfer(struct pipe_context *ctx, * right thing internally. */ trans->transfer.stride = - r300_texture_get_stride(r300screen, trans->detiled_texture, 0); + trans->linear_texture->desc.stride_in_bytes[0]; if (usage & PIPE_TRANSFER_READ) { /* We cannot map a tiled texture directly because the data is @@ -203,9 +202,9 @@ r300_texture_get_transfer(struct pipe_context *ctx, unpipelined: /* Unpipelined transfer. */ - trans->transfer.stride = - r300_texture_get_stride(r300screen, tex, sr.level); - trans->offset = r300_texture_get_offset(tex, sr.level, box->z, sr.face); + trans->transfer.stride = tex->desc.stride_in_bytes[sr.level]; + trans->offset = r300_texture_get_offset(&tex->desc, + sr.level, box->z, sr.face); if (referenced_cs) ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); @@ -219,13 +218,13 @@ void r300_texture_transfer_destroy(struct pipe_context *ctx, { struct r300_transfer *r300transfer = r300_transfer(trans); - if (r300transfer->detiled_texture) { + if (r300transfer->linear_texture) { if (trans->usage & PIPE_TRANSFER_WRITE) { r300_copy_into_tiled_texture(ctx, r300transfer); } pipe_resource_reference( - (struct pipe_resource**)&r300transfer->detiled_texture, NULL); + (struct pipe_resource**)&r300transfer->linear_texture, NULL); } pipe_resource_reference(&trans->resource, NULL); FREE(trans); @@ -239,13 +238,13 @@ void* r300_texture_transfer_map(struct pipe_context *ctx, struct r300_transfer *r300transfer = r300_transfer(transfer); struct r300_texture *tex = r300_texture(transfer->resource); char *map; - enum pipe_format format = tex->b.b.format; + enum pipe_format format = tex->desc.b.b.format; - if (r300transfer->detiled_texture) { + if (r300transfer->linear_texture) { /* The detiled texture is of the same size as the region being mapped * (no offset needed). */ return rws->buffer_map(rws, - r300transfer->detiled_texture->buffer, + r300transfer->linear_texture->buffer, r300->cs, transfer->usage); } else { @@ -270,8 +269,8 @@ void r300_texture_transfer_unmap(struct pipe_context *ctx, struct r300_transfer *r300transfer = r300_transfer(transfer); struct r300_texture *tex = r300_texture(transfer->resource); - if (r300transfer->detiled_texture) { - rws->buffer_unmap(rws, r300transfer->detiled_texture->buffer); + if (r300transfer->linear_texture) { + rws->buffer_unmap(rws, r300transfer->linear_texture->buffer); } else { rws->buffer_unmap(rws, tex->buffer); } diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c index b25c786d6b3..54c8de12419 100644 --- a/src/gallium/drivers/r300/r300_vs.c +++ b/src/gallium/drivers/r300/r300_vs.c @@ -207,7 +207,7 @@ void r300_translate_vertex_shader(struct r300_context *r300, compiler.Base.max_temp_regs = 32; if (compiler.Base.Debug) { - debug_printf("r300: Initial vertex program\n"); + DBG(r300, DBG_VP, "r300: Initial vertex program\n"); tgsi_dump(vs->state.tokens, 0); } @@ -227,8 +227,7 @@ void r300_translate_vertex_shader(struct r300_context *r300, /* Invoke the compiler */ r3xx_compile_vertex_program(&compiler); if (compiler.Base.Error) { - /* XXX We should fallback using Draw. */ - fprintf(stderr, "r300 VP: Compiler error:\n%sUsing a dummy shader" + DBG(r300, DBG_VP, "r300 VP: Compiler error:\n%sUsing a dummy shader" " instead.\nIf there's an 'unknown opcode' message, please" " file a bug report and attach this log.\n", compiler.Base.ErrorMsg); diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index 7e115c2d624..187780750fa 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -49,6 +49,8 @@ enum r300_value_id { R300_VID_Z_PIPES, R300_VID_SQUARE_TILING_SUPPORT, R300_VID_DRM_2_3_0, + R300_VID_DRM_2_6_0, + R300_CAN_HYPERZ, }; enum r300_reference_domain { /* bitfield */ @@ -184,12 +186,13 @@ struct r300_winsys_screen { * \param ws The winsys this function is called from. * \param whandle A winsys handle pointer as was received from a state * tracker. - * \param stride A pointer to the stride return variable. - * The stride is in bytes. + * \param stride The returned buffer stride in bytes. + * \param size The returned buffer size. */ struct r300_winsys_buffer *(*buffer_from_handle)(struct r300_winsys_screen *ws, struct winsys_handle *whandle, - unsigned *stride); + unsigned *stride, + unsigned *size); /** * Get a winsys handle from a winsys buffer. The internal structure diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile index aae31a6a6eb..fc94ae71f4a 100644 --- a/src/gallium/drivers/r600/Makefile +++ b/src/gallium/drivers/r600/Makefile @@ -9,6 +9,7 @@ LIBRARY_INCLUDES = \ C_SOURCES = \ r600_buffer.c \ r600_context.c \ + r600_shader.c \ r600_draw.c \ r600_blit.c \ r600_helper.c \ @@ -17,11 +18,7 @@ C_SOURCES = \ r600_screen.c \ r600_state.c \ r600_texture.c \ - r600_shader.c \ - r600_compiler.c \ - r600_compiler_tgsi.c \ - r600_compiler_dump.c \ - r600_compiler_r600.c \ - r600_compiler_r700.c + r600_asm.c \ + r700_asm.c include ../../Makefile.template diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript index 26e2f1941cc..99c8644e026 100644 --- a/src/gallium/drivers/r600/SConscript +++ b/src/gallium/drivers/r600/SConscript @@ -27,11 +27,8 @@ r600 = env.ConvenienceLibrary( 'r600_state.c', 'r600_texture.c', 'r600_shader.c', - 'r600_compiler.c', - 'r600_compiler_tgsi.c', - 'r600_compiler_dump.c', - 'r600_compiler_r600.c', - 'r600_compiler_r700.c' + 'r600_asm.c', + 'r700_asm.c', ]) Export('r600') diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c new file mode 100644 index 00000000000..9ea9d4354d6 --- /dev/null +++ b/src/gallium/drivers/r600/r600_asm.c @@ -0,0 +1,476 @@ +/* + * Copyright 2010 Jerome Glisse <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "r600_asm.h" +#include "r600_context.h" +#include "util/u_memory.h" +#include "r600_sq.h" +#include <stdio.h> +#include <errno.h> + +int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id); + +static struct r600_bc_cf *r600_bc_cf(void) +{ + struct r600_bc_cf *cf = CALLOC_STRUCT(r600_bc_cf); + + if (cf == NULL) + return NULL; + LIST_INITHEAD(&cf->list); + LIST_INITHEAD(&cf->alu); + LIST_INITHEAD(&cf->vtx); + LIST_INITHEAD(&cf->tex); + return cf; +} + +static struct r600_bc_alu *r600_bc_alu(void) +{ + struct r600_bc_alu *alu = CALLOC_STRUCT(r600_bc_alu); + + if (alu == NULL) + return NULL; + LIST_INITHEAD(&alu->list); + return alu; +} + +static struct r600_bc_vtx *r600_bc_vtx(void) +{ + struct r600_bc_vtx *vtx = CALLOC_STRUCT(r600_bc_vtx); + + if (vtx == NULL) + return NULL; + LIST_INITHEAD(&vtx->list); + return vtx; +} + +static struct r600_bc_tex *r600_bc_tex(void) +{ + struct r600_bc_tex *tex = CALLOC_STRUCT(r600_bc_tex); + + if (tex == NULL) + return NULL; + LIST_INITHEAD(&tex->list); + return tex; +} + +int r600_bc_init(struct r600_bc *bc, enum radeon_family family) +{ + LIST_INITHEAD(&bc->cf); + bc->family = family; + return 0; +} + +static int r600_bc_add_cf(struct r600_bc *bc) +{ + struct r600_bc_cf *cf = r600_bc_cf(); + + if (cf == NULL) + return -ENOMEM; + LIST_ADDTAIL(&cf->list, &bc->cf); + if (bc->cf_last) + cf->id = bc->cf_last->id + 2; + bc->cf_last = cf; + bc->ncf++; + bc->ndw += 2; + bc->force_add_cf = 0; + return 0; +} + +int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output) +{ + int r; + + r = r600_bc_add_cf(bc); + if (r) + return r; + bc->cf_last->inst = output->inst; + memcpy(&bc->cf_last->output, output, sizeof(struct r600_bc_output)); + return 0; +} + +int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu) +{ + struct r600_bc_alu *nalu = r600_bc_alu(); + struct r600_bc_alu *lalu; + int i, r; + + if (nalu == NULL) + return -ENOMEM; + memcpy(nalu, alu, sizeof(struct r600_bc_alu)); + nalu->nliteral = 0; + + /* cf can contains only alu or only vtx or only tex */ + if (bc->cf_last == NULL || bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) || + bc->force_add_cf) { + /* at most 128 slots, one add alu can add 4 slots + 4 constant worst case */ + r = r600_bc_add_cf(bc); + if (r) { + free(nalu); + return r; + } + bc->cf_last->inst = V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3; + } + if (alu->last && (bc->cf_last->ndw >> 1) >= 124) { + bc->force_add_cf = 1; + } + /* number of gpr == the last gpr used in any alu */ + for (i = 0; i < 3; i++) { + if (alu->src[i].sel >= bc->ngpr && alu->src[i].sel < 128) { + bc->ngpr = alu->src[i].sel + 1; + } + /* compute how many literal are needed + * either 2 or 4 literals + */ + if (alu->src[i].sel == 253) { + if (((alu->src[i].chan + 2) & 0x6) > nalu->nliteral) { + nalu->nliteral = (alu->src[i].chan + 2) & 0x6; + } + } + } + if (!LIST_IS_EMPTY(&bc->cf_last->alu)) { + lalu = LIST_ENTRY(struct r600_bc_alu, bc->cf_last->alu.prev, list); + if (!lalu->last && lalu->nliteral > nalu->nliteral) { + nalu->nliteral = lalu->nliteral; + } + } + if (alu->dst.sel >= bc->ngpr) { + bc->ngpr = alu->dst.sel + 1; + } + LIST_ADDTAIL(&nalu->list, &bc->cf_last->alu); + /* each alu use 2 dwords */ + bc->cf_last->ndw += 2; + bc->ndw += 2; + return 0; +} + +int r600_bc_add_literal(struct r600_bc *bc, const u32 *value) +{ + struct r600_bc_alu *alu; + + if (bc->cf_last == NULL) { + return 0; + } + if (bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_TEX) { + return 0; + } + if (bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) || + LIST_IS_EMPTY(&bc->cf_last->alu)) { + R600_ERR("last CF is not ALU (%p)\n", bc->cf_last); + return -EINVAL; + } + alu = LIST_ENTRY(struct r600_bc_alu, bc->cf_last->alu.prev, list); + if (!alu->last || !alu->nliteral || alu->literal_added) { + return 0; + } + memcpy(alu->value, value, 4 * 4); + bc->cf_last->ndw += alu->nliteral; + bc->ndw += alu->nliteral; + alu->literal_added = 1; + return 0; +} + +int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx) +{ + struct r600_bc_vtx *nvtx = r600_bc_vtx(); + int r; + + if (nvtx == NULL) + return -ENOMEM; + memcpy(nvtx, vtx, sizeof(struct r600_bc_vtx)); + + /* cf can contains only alu or only vtx or only tex */ + if (bc->cf_last == NULL || + (bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX && + bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC)) { + r = r600_bc_add_cf(bc); + if (r) { + free(nvtx); + return r; + } + bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_VTX; + } + LIST_ADDTAIL(&nvtx->list, &bc->cf_last->vtx); + /* each fetch use 4 dwords */ + bc->cf_last->ndw += 4; + bc->ndw += 4; + return 0; +} + +int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex) +{ + struct r600_bc_tex *ntex = r600_bc_tex(); + int r; + + if (ntex == NULL) + return -ENOMEM; + memcpy(ntex, tex, sizeof(struct r600_bc_tex)); + + /* cf can contains only alu or only vtx or only tex */ + if (bc->cf_last == NULL || + bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_TEX) { + r = r600_bc_add_cf(bc); + if (r) { + free(ntex); + return r; + } + bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_TEX; + } + LIST_ADDTAIL(&ntex->list, &bc->cf_last->tex); + /* each texture fetch use 4 dwords */ + bc->cf_last->ndw += 4; + bc->ndw += 4; + return 0; +} + +static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id) +{ + bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) | + S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) | + S_SQ_VTX_WORD0_SRC_SEL_X(vtx->src_sel_x) | + S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(vtx->mega_fetch_count); + bc->bytecode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vtx->dst_sel_x) | + S_SQ_VTX_WORD1_DST_SEL_Y(vtx->dst_sel_y) | + S_SQ_VTX_WORD1_DST_SEL_Z(vtx->dst_sel_z) | + S_SQ_VTX_WORD1_DST_SEL_W(vtx->dst_sel_w) | + S_SQ_VTX_WORD1_USE_CONST_FIELDS(1) | + S_SQ_VTX_WORD1_GPR_DST_GPR(vtx->dst_gpr); + bc->bytecode[id++] = S_SQ_VTX_WORD2_MEGA_FETCH(1); + bc->bytecode[id++] = 0; + return 0; +} + +static int r600_bc_tex_build(struct r600_bc *bc, struct r600_bc_tex *tex, unsigned id) +{ + bc->bytecode[id++] = S_SQ_TEX_WORD0_TEX_INST(tex->inst) | + S_SQ_TEX_WORD0_RESOURCE_ID(tex->resource_id) | + S_SQ_TEX_WORD0_SRC_GPR(tex->src_gpr) | + S_SQ_TEX_WORD0_SRC_REL(tex->src_rel); + bc->bytecode[id++] = S_SQ_TEX_WORD1_DST_GPR(tex->dst_gpr) | + S_SQ_TEX_WORD1_DST_REL(tex->dst_rel) | + S_SQ_TEX_WORD1_DST_SEL_X(tex->dst_sel_x) | + S_SQ_TEX_WORD1_DST_SEL_Y(tex->dst_sel_y) | + S_SQ_TEX_WORD1_DST_SEL_Z(tex->dst_sel_z) | + S_SQ_TEX_WORD1_DST_SEL_W(tex->dst_sel_w) | + S_SQ_TEX_WORD1_LOD_BIAS(tex->lod_bias) | + S_SQ_TEX_WORD1_COORD_TYPE_X(tex->coord_type_x) | + S_SQ_TEX_WORD1_COORD_TYPE_Y(tex->coord_type_y) | + S_SQ_TEX_WORD1_COORD_TYPE_Z(tex->coord_type_z) | + S_SQ_TEX_WORD1_COORD_TYPE_W(tex->coord_type_w); + bc->bytecode[id++] = S_SQ_TEX_WORD2_OFFSET_X(tex->offset_x) | + S_SQ_TEX_WORD2_OFFSET_Y(tex->offset_y) | + S_SQ_TEX_WORD2_OFFSET_Z(tex->offset_z) | + S_SQ_TEX_WORD2_SAMPLER_ID(tex->sampler_id) | + S_SQ_TEX_WORD2_SRC_SEL_X(tex->src_sel_x) | + S_SQ_TEX_WORD2_SRC_SEL_Y(tex->src_sel_y) | + S_SQ_TEX_WORD2_SRC_SEL_Z(tex->src_sel_z) | + S_SQ_TEX_WORD2_SRC_SEL_W(tex->src_sel_w); + bc->bytecode[id++] = 0; + return 0; +} + +static int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id) +{ + unsigned i; + + /* don't replace gpr by pv or ps for destination register */ + if (alu->is_op3) { + bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) | + S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) | + S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) | + S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) | + S_SQ_ALU_WORD0_LAST(alu->last); + bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | + S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | + S_SQ_ALU_WORD1_CLAMP(alu->dst.clamp) | + S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) | + S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) | + S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) | + S_SQ_ALU_WORD1_OP3_ALU_INST(alu->inst) | + S_SQ_ALU_WORD1_BANK_SWIZZLE(0); + } else { + bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) | + S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) | + S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) | + S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) | + S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) | + S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) | + S_SQ_ALU_WORD0_LAST(alu->last); + bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | + S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | + S_SQ_ALU_WORD1_CLAMP(alu->dst.clamp) | + S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) | + S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) | + S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) | + S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) | + S_SQ_ALU_WORD1_BANK_SWIZZLE(0); + } + if (alu->last) { + for (i = 0; i < alu->nliteral; i++) { + bc->bytecode[id++] = alu->value[i]; + } + } + return 0; +} + +static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) +{ + unsigned id = cf->id; + + switch (cf->inst) { + case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): + bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1); + bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(cf->inst >> 3) | + S_SQ_CF_ALU_WORD1_BARRIER(1) | + S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1); + break; + case V_SQ_CF_WORD1_SQ_CF_INST_TEX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: + bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1); + bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) | + S_SQ_CF_WORD1_BARRIER(1) | + S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1); + break; + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) | + S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) | + S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) | + S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type); + bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(cf->output.swizzle_x) | + S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) | + S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) | + S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) | + S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) | + S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst) | + S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program); + break; + default: + R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); + return -EINVAL; + } + return 0; +} + +int r600_bc_build(struct r600_bc *bc) +{ + struct r600_bc_cf *cf; + struct r600_bc_alu *alu; + struct r600_bc_vtx *vtx; + struct r600_bc_tex *tex; + unsigned addr; + int r; + + + /* first path compute addr of each CF block */ + /* addr start after all the CF instructions */ + addr = bc->cf_last->id + 2; + LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { + switch (cf->inst) { + case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): + break; + case V_SQ_CF_WORD1_SQ_CF_INST_TEX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: + /* fetch node need to be 16 bytes aligned*/ + addr += 3; + addr &= 0xFFFFFFFCUL; + break; + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + break; + default: + R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); + return -EINVAL; + } + cf->addr = addr; + addr += cf->ndw; + bc->ndw = cf->addr + cf->ndw; + } + free(bc->bytecode); + bc->bytecode = calloc(1, bc->ndw * 4); + if (bc->bytecode == NULL) + return -ENOMEM; + LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { + addr = cf->addr; + r = r600_bc_cf_build(bc, cf); + if (r) + return r; + switch (cf->inst) { + case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): + LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { + switch (bc->family) { + case CHIP_R600: + case CHIP_RV610: + case CHIP_RV630: + case CHIP_RV670: + case CHIP_RV620: + case CHIP_RV635: + case CHIP_RS780: + case CHIP_RS880: + r = r600_bc_alu_build(bc, alu, addr); + break; + case CHIP_RV770: + case CHIP_RV730: + case CHIP_RV710: + case CHIP_RV740: + r = r700_bc_alu_build(bc, alu, addr); + break; + default: + R600_ERR("unknown family %d\n", bc->family); + return -EINVAL; + } + if (r) + return r; + addr += 2; + if (alu->last) { + addr += alu->nliteral; + } + } + break; + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: + LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) { + r = r600_bc_vtx_build(bc, vtx, addr); + if (r) + return r; + addr += 4; + } + break; + case V_SQ_CF_WORD1_SQ_CF_INST_TEX: + LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) { + r = r600_bc_tex_build(bc, tex, addr); + if (r) + return r; + addr += 4; + } + break; + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT: + case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE: + break; + default: + R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst); + return -EINVAL; + } + } + return 0; +} diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h new file mode 100644 index 00000000000..10d98afaf00 --- /dev/null +++ b/src/gallium/drivers/r600/r600_asm.h @@ -0,0 +1,143 @@ +/* + * Copyright 2010 Jerome Glisse <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef R600_ASM_H +#define R600_ASM_H + +#include "radeon.h" +#include "util/u_double_list.h" + +struct r600_bc_alu_src { + unsigned sel; + unsigned chan; + unsigned neg; + unsigned abs; +}; + +struct r600_bc_alu_dst { + unsigned sel; + unsigned chan; + unsigned clamp; + unsigned write; +}; + +struct r600_bc_alu { + struct list_head list; + struct r600_bc_alu_src src[3]; + struct r600_bc_alu_dst dst; + unsigned inst; + unsigned last; + unsigned is_op3; + unsigned nliteral; + unsigned literal_added; + u32 value[4]; +}; + +struct r600_bc_tex { + struct list_head list; + unsigned inst; + unsigned resource_id; + unsigned src_gpr; + unsigned src_rel; + unsigned dst_gpr; + unsigned dst_rel; + unsigned dst_sel_x; + unsigned dst_sel_y; + unsigned dst_sel_z; + unsigned dst_sel_w; + unsigned lod_bias; + unsigned coord_type_x; + unsigned coord_type_y; + unsigned coord_type_z; + unsigned coord_type_w; + unsigned offset_x; + unsigned offset_y; + unsigned offset_z; + unsigned sampler_id; + unsigned src_sel_x; + unsigned src_sel_y; + unsigned src_sel_z; + unsigned src_sel_w; +}; + +struct r600_bc_vtx { + struct list_head list; + unsigned inst; + unsigned fetch_type; + unsigned buffer_id; + unsigned src_gpr; + unsigned src_sel_x; + unsigned mega_fetch_count; + unsigned dst_gpr; + unsigned dst_sel_x; + unsigned dst_sel_y; + unsigned dst_sel_z; + unsigned dst_sel_w; +}; + +struct r600_bc_output { + unsigned array_base; + unsigned type; + unsigned end_of_program; + unsigned inst; + unsigned elem_size; + unsigned gpr; + unsigned swizzle_x; + unsigned swizzle_y; + unsigned swizzle_z; + unsigned swizzle_w; + unsigned barrier; +}; + +struct r600_bc_cf { + struct list_head list; + unsigned inst; + unsigned addr; + unsigned ndw; + unsigned id; + struct list_head alu; + struct list_head tex; + struct list_head vtx; + struct r600_bc_output output; +}; + +struct r600_bc { + enum radeon_family family; + struct list_head cf; + struct r600_bc_cf *cf_last; + unsigned ndw; + unsigned ncf; + unsigned ngpr; + unsigned nresource; + unsigned force_add_cf; + u32 *bytecode; +}; + +int r600_bc_init(struct r600_bc *bc, enum radeon_family family); +int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu); +int r600_bc_add_literal(struct r600_bc *bc, const u32 *value); +int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx); +int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex); +int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output); +int r600_bc_build(struct r600_bc *bc); + +#endif diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 1dcb19babc9..f4eedfe4cb1 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -34,31 +34,37 @@ static void r600_blitter_save_states(struct r600_context *rctx) { - util_blitter_save_blend(rctx->blitter, - rctx->draw->state[R600_BLEND]); - util_blitter_save_depth_stencil_alpha(rctx->blitter, - rctx->draw->state[R600_DSA]); - util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref); - util_blitter_save_rasterizer(rctx->blitter, - rctx->draw->state[R600_RASTERIZER]); - util_blitter_save_fragment_shader(rctx->blitter, - rctx->ps_shader); - util_blitter_save_vertex_shader(rctx->blitter, - rctx->vs_shader); - util_blitter_save_vertex_elements(rctx->blitter, - rctx->vertex_elements); - util_blitter_save_viewport(rctx->blitter, - &rctx->viewport); + util_blitter_save_blend(rctx->blitter, rctx->blend); + util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->dsa); + if (rctx->stencil_ref) { + util_blitter_save_stencil_ref(rctx->blitter, + &rctx->stencil_ref->state.stencil_ref); + } + util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer); + util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader); + util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader); + util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements); + if (rctx->viewport) { + util_blitter_save_viewport(rctx->blitter, &rctx->viewport->state.viewport); + } /* XXX util_blitter_save_clip(rctx->blitter, &rctx->clip); */ util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffer, - rctx->vertex_buffer); + rctx->vertex_buffer); + + /* remove ptr so they don't get deleted */ + rctx->blend = NULL; + rctx->vs_shader = NULL; + rctx->ps_shader = NULL; + rctx->rasterizer = NULL; + rctx->dsa = NULL; + rctx->vertex_elements = NULL; } static void r600_clear(struct pipe_context *ctx, unsigned buffers, const float *rgba, double depth, unsigned stencil) { struct r600_context *rctx = r600_context(ctx); - struct pipe_framebuffer_state *fb = &rctx->fb_state; + struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; r600_blitter_save_states(rctx); util_blitter_clear(rctx->blitter, fb->width, fb->height, @@ -73,9 +79,10 @@ static void r600_clear_render_target(struct pipe_context *pipe, unsigned width, unsigned height) { struct r600_context *rctx = r600_context(pipe); + struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; r600_blitter_save_states(rctx); - util_blitter_save_framebuffer(rctx->blitter, &rctx->fb_state); + util_blitter_save_framebuffer(rctx->blitter, fb); util_blitter_clear_render_target(rctx->blitter, dst, rgba, dstx, dsty, width, height); @@ -90,9 +97,10 @@ static void r600_clear_depth_stencil(struct pipe_context *pipe, unsigned width, unsigned height) { struct r600_context *rctx = r600_context(pipe); + struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; r600_blitter_save_states(rctx); - util_blitter_save_framebuffer(rctx->blitter, &rctx->fb_state); + util_blitter_save_framebuffer(rctx->blitter, fb); util_blitter_clear_depth_stencil(rctx->blitter, dst, clear_flags, depth, stencil, dstx, dsty, width, height); diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index bc6e336ba7b..7829a479c2e 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -32,10 +32,11 @@ #include "state_tracker/drm_driver.h" #include "r600_screen.h" #include "r600_context.h" +#include "r600_resource.h" extern struct u_resource_vtbl r600_buffer_vtbl; -static u32 r600_domain_from_usage(unsigned usage) +u32 r600_domain_from_usage(unsigned usage) { u32 domain = RADEON_GEM_DOMAIN_GTT; @@ -63,47 +64,47 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ) { struct r600_screen *rscreen = r600_screen(screen); - struct r600_buffer *rbuffer; + struct r600_resource *rbuffer; struct radeon_bo *bo; struct pb_desc desc; /* XXX We probably want a different alignment for buffers and textures. */ unsigned alignment = 4096; - rbuffer = CALLOC_STRUCT(r600_buffer); + rbuffer = CALLOC_STRUCT(r600_resource); if (rbuffer == NULL) return NULL; - rbuffer->b.b = *templ; - pipe_reference_init(&rbuffer->b.b.reference, 1); - rbuffer->b.b.screen = screen; - rbuffer->b.vtbl = &r600_buffer_vtbl; + rbuffer->base.b = *templ; + pipe_reference_init(&rbuffer->base.b.reference, 1); + rbuffer->base.b.screen = screen; + rbuffer->base.vtbl = &r600_buffer_vtbl; - if (rbuffer->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) { + if (rbuffer->base.b.bind & PIPE_BIND_CONSTANT_BUFFER) { desc.alignment = alignment; - desc.usage = rbuffer->b.b.bind; - rbuffer->pb = pb_malloc_buffer_create(rbuffer->b.b.width0, + desc.usage = rbuffer->base.b.bind; + rbuffer->pb = pb_malloc_buffer_create(rbuffer->base.b.width0, &desc); if (rbuffer->pb == NULL) { free(rbuffer); return NULL; } - return &rbuffer->b.b; + return &rbuffer->base.b; } - rbuffer->domain = r600_domain_from_usage(rbuffer->b.b.bind); - bo = radeon_bo(rscreen->rw, 0, rbuffer->b.b.width0, alignment, NULL); + rbuffer->domain = r600_domain_from_usage(rbuffer->base.b.bind); + bo = radeon_bo(rscreen->rw, 0, rbuffer->base.b.width0, alignment, NULL); if (bo == NULL) { FREE(rbuffer); return NULL; } rbuffer->bo = bo; - return &rbuffer->b.b; + return &rbuffer->base.b; } struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, void *ptr, unsigned bytes, unsigned bind) { - struct r600_buffer *rbuffer; + struct r600_resource *rbuffer; struct r600_screen *rscreen = r600_screen(screen); struct pipe_resource templ; @@ -116,20 +117,20 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, templ.height0 = 1; templ.depth0 = 1; - rbuffer = (struct r600_buffer*)r600_buffer_create(screen, &templ); + rbuffer = (struct r600_resource*)r600_buffer_create(screen, &templ); if (rbuffer == NULL) { return NULL; } radeon_bo_map(rscreen->rw, rbuffer->bo); memcpy(rbuffer->bo->data, ptr, bytes); radeon_bo_unmap(rscreen->rw, rbuffer->bo); - return &rbuffer->b.b; + return &rbuffer->base.b; } static void r600_buffer_destroy(struct pipe_screen *screen, struct pipe_resource *buf) { - struct r600_buffer *rbuffer = (struct r600_buffer*)buf; + struct r600_resource *rbuffer = (struct r600_resource*)buf; struct r600_screen *rscreen = r600_screen(screen); if (rbuffer->pb) { @@ -140,13 +141,14 @@ static void r600_buffer_destroy(struct pipe_screen *screen, if (rbuffer->bo) { radeon_bo_decref(rscreen->rw, rbuffer->bo); } + memset(rbuffer, 0, sizeof(struct r600_resource)); FREE(rbuffer); } static void *r600_buffer_transfer_map(struct pipe_context *pipe, struct pipe_transfer *transfer) { - struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource; + struct r600_resource *rbuffer = (struct r600_resource*)transfer->resource; struct r600_screen *rscreen = r600_screen(pipe->screen); int write = 0; @@ -166,9 +168,9 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, } static void r600_buffer_transfer_unmap(struct pipe_context *pipe, - struct pipe_transfer *transfer) + struct pipe_transfer *transfer) { - struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource; + struct r600_resource *rbuffer = (struct r600_resource*)transfer->resource; struct r600_screen *rscreen = r600_screen(pipe->screen); if (rbuffer->pb) { @@ -188,7 +190,7 @@ unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context, struct pipe_resource *buf, unsigned face, unsigned level) { - /* XXX */ + /* FIXME */ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; } @@ -196,7 +198,7 @@ struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen, struct winsys_handle *whandle) { struct radeon *rw = (struct radeon*)screen->winsys; - struct r600_buffer *rbuffer; + struct r600_resource *rbuffer; struct radeon_bo *bo = NULL; bo = radeon_bo(rw, whandle->handle, 0, 0, NULL); @@ -204,18 +206,18 @@ struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen, return NULL; } - rbuffer = CALLOC_STRUCT(r600_buffer); + rbuffer = CALLOC_STRUCT(r600_resource); if (rbuffer == NULL) { radeon_bo_decref(rw, bo); return NULL; } - pipe_reference_init(&rbuffer->b.b.reference, 1); - rbuffer->b.b.target = PIPE_BUFFER; - rbuffer->b.b.screen = screen; - rbuffer->b.vtbl = &r600_buffer_vtbl; + pipe_reference_init(&rbuffer->base.b.reference, 1); + rbuffer->base.b.target = PIPE_BUFFER; + rbuffer->base.b.screen = screen; + rbuffer->base.vtbl = &r600_buffer_vtbl; rbuffer->bo = bo; - return &rbuffer->b.b; + return &rbuffer->base.b; } struct u_resource_vtbl r600_buffer_vtbl = diff --git a/src/gallium/drivers/r600/r600_compiler.c b/src/gallium/drivers/r600/r600_compiler.c deleted file mode 100644 index 1804b86d24e..00000000000 --- a/src/gallium/drivers/r600/r600_compiler.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse <[email protected]> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <stdio.h> -#include <errno.h> -#include "r600_compiler.h" - -struct c_vector *c_vector_new(void) -{ - struct c_vector *v = calloc(1, sizeof(struct c_vector)); - - if (v == NULL) { - return NULL; - } - LIST_INITHEAD(&v->head); - return v; -} - -static unsigned c_opcode_is_alu(unsigned opcode) -{ - switch (opcode) { - case C_OPCODE_MOV: - case C_OPCODE_MUL: - case C_OPCODE_MAD: - case C_OPCODE_ARL: - case C_OPCODE_LIT: - case C_OPCODE_RCP: - case C_OPCODE_RSQ: - case C_OPCODE_EXP: - case C_OPCODE_LOG: - case C_OPCODE_ADD: - case C_OPCODE_DP3: - case C_OPCODE_DP4: - case C_OPCODE_DST: - case C_OPCODE_MIN: - case C_OPCODE_MAX: - case C_OPCODE_SLT: - case C_OPCODE_SGE: - case C_OPCODE_SUB: - case C_OPCODE_LRP: - case C_OPCODE_CND: - case C_OPCODE_DP2A: - case C_OPCODE_FRC: - case C_OPCODE_CLAMP: - case C_OPCODE_FLR: - case C_OPCODE_ROUND: - case C_OPCODE_EX2: - case C_OPCODE_LG2: - case C_OPCODE_POW: - case C_OPCODE_XPD: - case C_OPCODE_ABS: - case C_OPCODE_RCC: - case C_OPCODE_DPH: - case C_OPCODE_COS: - case C_OPCODE_DDX: - case C_OPCODE_DDY: - case C_OPCODE_PK2H: - case C_OPCODE_PK2US: - case C_OPCODE_PK4B: - case C_OPCODE_PK4UB: - case C_OPCODE_RFL: - case C_OPCODE_SEQ: - case C_OPCODE_SFL: - case C_OPCODE_SGT: - case C_OPCODE_SIN: - case C_OPCODE_SLE: - case C_OPCODE_SNE: - case C_OPCODE_STR: - case C_OPCODE_UP2H: - case C_OPCODE_UP2US: - case C_OPCODE_UP4B: - case C_OPCODE_UP4UB: - case C_OPCODE_X2D: - case C_OPCODE_ARA: - case C_OPCODE_ARR: - case C_OPCODE_BRA: - case C_OPCODE_SSG: - case C_OPCODE_CMP: - case C_OPCODE_SCS: - case C_OPCODE_NRM: - case C_OPCODE_DIV: - case C_OPCODE_DP2: - case C_OPCODE_CEIL: - case C_OPCODE_I2F: - case C_OPCODE_NOT: - case C_OPCODE_TRUNC: - case C_OPCODE_SHL: - case C_OPCODE_AND: - case C_OPCODE_OR: - case C_OPCODE_MOD: - case C_OPCODE_XOR: - case C_OPCODE_SAD: - case C_OPCODE_NRM4: - case C_OPCODE_F2I: - case C_OPCODE_IDIV: - case C_OPCODE_IMAX: - case C_OPCODE_IMIN: - case C_OPCODE_INEG: - case C_OPCODE_ISGE: - case C_OPCODE_ISHR: - case C_OPCODE_ISLT: - case C_OPCODE_F2U: - case C_OPCODE_U2F: - case C_OPCODE_UADD: - case C_OPCODE_UDIV: - case C_OPCODE_UMAD: - case C_OPCODE_UMAX: - case C_OPCODE_UMIN: - case C_OPCODE_UMOD: - case C_OPCODE_UMUL: - case C_OPCODE_USEQ: - case C_OPCODE_USGE: - case C_OPCODE_USHR: - case C_OPCODE_USLT: - case C_OPCODE_USNE: - return 1; - case C_OPCODE_END: - case C_OPCODE_VFETCH: - case C_OPCODE_KILP: - case C_OPCODE_CAL: - case C_OPCODE_RET: - case C_OPCODE_TXB: - case C_OPCODE_TXL: - case C_OPCODE_BRK: - case C_OPCODE_IF: - case C_OPCODE_BGNFOR: - case C_OPCODE_REP: - case C_OPCODE_ELSE: - case C_OPCODE_ENDIF: - case C_OPCODE_ENDFOR: - case C_OPCODE_ENDREP: - case C_OPCODE_PUSHA: - case C_OPCODE_POPA: - case C_OPCODE_TXF: - case C_OPCODE_TXQ: - case C_OPCODE_CONT: - case C_OPCODE_EMIT: - case C_OPCODE_ENDPRIM: - case C_OPCODE_BGNLOOP: - case C_OPCODE_BGNSUB: - case C_OPCODE_ENDLOOP: - case C_OPCODE_ENDSUB: - case C_OPCODE_NOP: - case C_OPCODE_CALLNZ: - case C_OPCODE_IFC: - case C_OPCODE_BREAKC: - case C_OPCODE_KIL: - case C_OPCODE_TEX: - case C_OPCODE_TXD: - case C_OPCODE_TXP: - case C_OPCODE_SWITCH: - case C_OPCODE_CASE: - case C_OPCODE_DEFAULT: - case C_OPCODE_ENDSWITCH: - default: - return 0; - } -} - - -/* NEW */ -void c_node_init(struct c_node *node) -{ - memset(node, 0, sizeof(struct c_node)); - LIST_INITHEAD(&node->predecessors); - LIST_INITHEAD(&node->successors); - LIST_INITHEAD(&node->childs); - LIST_INITHEAD(&node->insts); - node->parent = NULL; -} - -static struct c_node_link *c_node_link_new(struct c_node *node) -{ - struct c_node_link *link; - - link = calloc(1, sizeof(struct c_node_link)); - if (link == NULL) - return NULL; - LIST_INITHEAD(&link->head); - link->node = node; - return link; -} - -int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor) -{ - struct c_node_link *pedge, *sedge; - - pedge = c_node_link_new(successor); - sedge = c_node_link_new(predecessor); - if (sedge == NULL || pedge == NULL) { - free(sedge); - free(pedge); - return -ENOMEM; - } - LIST_ADDTAIL(&pedge->head, &predecessor->successors); - LIST_ADDTAIL(&sedge->head, &successor->predecessors); - - return 0; -} - -int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction) -{ - struct c_instruction *inst = malloc(sizeof(struct c_instruction)); - - if (inst == NULL) - return -ENOMEM; - memcpy(inst, instruction, sizeof(struct c_instruction)); - LIST_ADD(&inst->head, &node->insts); - return 0; -} - -int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction) -{ - struct c_instruction *inst = malloc(sizeof(struct c_instruction)); - - if (inst == NULL) - return -ENOMEM; - memcpy(inst, instruction, sizeof(struct c_instruction)); - LIST_ADDTAIL(&inst->head, &node->insts); - return 0; -} - -struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor) -{ - struct c_node *node = calloc(1, sizeof(struct c_node)); - - if (node == NULL) - return NULL; - c_node_init(node); - if (c_node_cfg_link(predecessor, node)) { - free(node); - return NULL; - } - LIST_ADDTAIL(&node->head, &shader->nodes); - return node; -} - -int c_shader_init(struct c_shader *shader, unsigned type) -{ - unsigned i; - int r; - - shader->type = type; - for (i = 0; i < C_FILE_COUNT; i++) { - shader->files[i].nvectors = 0; - LIST_INITHEAD(&shader->files[i].vectors); - } - LIST_INITHEAD(&shader->nodes); - c_node_init(&shader->entry); - c_node_init(&shader->end); - shader->entry.opcode = C_OPCODE_ENTRY; - shader->end.opcode = C_OPCODE_END; - r = c_node_cfg_link(&shader->entry, &shader->end); - if (r) - return r; - return 0; -} - -struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid) -{ - struct c_vector *v = calloc(1, sizeof(struct c_vector)); - int i; - - if (v == NULL) { - return NULL; - } - for (i = 0; i < 4; i++) { - v->channel[i] = calloc(1, sizeof(struct c_channel)); - if (v->channel[i] == NULL) - goto out_err; - v->channel[i]->vindex = i; - v->channel[i]->vector = v; - } - v->file = file; - v->name = name; - v->sid = sid; - shader->files[v->file].nvectors++; - v->id = shader->nvectors++; - LIST_ADDTAIL(&v->head, &shader->files[v->file].vectors); - return v; -out_err: - for (i = 0; i < 4; i++) { - free(v->channel[i]); - } - free(v); - return NULL; -} - -static void c_node_remove_link(struct list_head *head, struct c_node *node) -{ - struct c_node_link *link, *tmp; - - LIST_FOR_EACH_ENTRY_SAFE(link, tmp, head, head) { - if (link->node == node) { - LIST_DEL(&link->head); - free(link); - } - } -} - -static void c_node_destroy(struct c_node *node) -{ - struct c_instruction *i, *ni; - struct c_node_link *link, *tmp; - - LIST_FOR_EACH_ENTRY_SAFE(i, ni, &node->insts, head) { - LIST_DEL(&i->head); - free(i); - } - if (node->parent) - c_node_remove_link(&node->parent->childs, node); - node->parent = NULL; - LIST_FOR_EACH_ENTRY_SAFE(link, tmp, &node->predecessors, head) { - c_node_remove_link(&link->node->successors, node); - LIST_DEL(&link->head); - free(link); - } - LIST_FOR_EACH_ENTRY_SAFE(link, tmp, &node->successors, head) { - c_node_remove_link(&link->node->predecessors, node); - LIST_DEL(&link->head); - free(link); - } - LIST_FOR_EACH_ENTRY_SAFE(link, tmp, &node->childs, head) { - link->node->parent = NULL; - LIST_DEL(&link->head); - free(link); - } -} - -void c_shader_destroy(struct c_shader *shader) -{ - struct c_node *n, *nn; - struct c_vector *v, *nv; - unsigned i; - - for (i = 0; i < C_FILE_COUNT; i++) { - shader->files[i].nvectors = 0; - LIST_FOR_EACH_ENTRY_SAFE(v, nv, &shader->files[i].vectors, head) { - LIST_DEL(&v->head); - free(v->channel[0]); - free(v->channel[1]); - free(v->channel[2]); - free(v->channel[3]); - free(v); - } - } - LIST_FOR_EACH_ENTRY_SAFE(n, nn, &shader->nodes, head) { - LIST_DEL(&n->head); - c_node_destroy(n); - } - memset(shader, 0, sizeof(struct c_shader)); -} - -static void c_shader_dfs_without_rec(struct c_node *entry, struct c_node *node) -{ - struct c_node_link *link; - - if (entry == node || entry->visited) - return; - entry->visited = 1; - LIST_FOR_EACH_ENTRY(link, &entry->successors, head) { - c_shader_dfs_without_rec(link->node, node); - } -} - -static void c_shader_dfs_without(struct c_shader *shader, struct c_node *node) -{ - struct c_node *n; - - shader->entry.visited = 0; - shader->end.visited = 0; - LIST_FOR_EACH_ENTRY(n, &shader->nodes, head) { - n->visited = 0; - } - c_shader_dfs_without_rec(&shader->entry, node); -} - -static int c_shader_build_dominator_tree_rec(struct c_shader *shader, struct c_node *node) -{ - struct c_node_link *link, *nlink; - unsigned found = 0; - int r; - - if (node->done) - return 0; - node->done = 1; - LIST_FOR_EACH_ENTRY(link, &node->predecessors, head) { - /* if we remove this predecessor can we reach the current node ? */ - c_shader_dfs_without(shader, link->node); - if (node->visited == 0) { - /* we were unable to visit current node thus current - * predecessor is the immediate dominator of node, as - * their can be only one immediate dominator we break - */ - node->parent = link->node; - nlink = c_node_link_new(node); - if (nlink == NULL) - return -ENOMEM; - LIST_ADDTAIL(&nlink->head, &link->node->childs); - found = 1; - break; - } - } - /* this shouldn't happen there should at least be 1 denominator for each node */ - if (!found && node->opcode != C_OPCODE_ENTRY) { - fprintf(stderr, "invalid flow control graph node %p (%d) has no immediate dominator\n", - node, node->opcode); - return -EINVAL; - } - LIST_FOR_EACH_ENTRY(link, &node->predecessors, head) { - r = c_shader_build_dominator_tree_rec(shader, link->node); - if (r) - return r; - } - return 0; -} - -int c_shader_build_dominator_tree(struct c_shader *shader) -{ - struct c_node *node; - LIST_FOR_EACH_ENTRY(node, &shader->nodes, head) { - node->done = 0; - } - return c_shader_build_dominator_tree_rec(shader, &shader->end); -} diff --git a/src/gallium/drivers/r600/r600_compiler.h b/src/gallium/drivers/r600/r600_compiler.h deleted file mode 100644 index 77230aed73b..00000000000 --- a/src/gallium/drivers/r600/r600_compiler.h +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse <[email protected]> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef R600_COMPILER_H -#define R600_COMPILER_H - -#include "util/u_double_list.h" - -struct c_vector; - -/* operand are the basic source/destination of each operation */ -struct c_channel { - struct list_head head; - unsigned vindex; /**< index in vector X,Y,Z,W (0,1,2,3) */ - unsigned value; /**< immediate value 32bits */ - struct c_vector *vector; /**< vector to which it belongs */ -}; - -/* in GPU world most of the time operand are grouped into vector - * of 4 component this structure is mostly and handler to group - * operand into a same vector - */ -struct c_vector { - struct list_head head; - unsigned id; /**< vector uniq id */ - unsigned name; /**< semantic name */ - unsigned file; /**< operand file C_FILE_* */ - int sid; /**< semantic id */ - struct c_channel *channel[4]; /**< operands */ -}; - -#define C_PROGRAM_TYPE_VS 0 -#define C_PROGRAM_TYPE_FS 1 -#define C_PROGRAM_TYPE_COUNT 2 - -#define C_NODE_FLAG_ALU 1 -#define C_NODE_FLAG_FETCH 2 - -#define C_SWIZZLE_X 0 -#define C_SWIZZLE_Y 1 -#define C_SWIZZLE_Z 2 -#define C_SWIZZLE_W 3 -#define C_SWIZZLE_0 4 -#define C_SWIZZLE_1 5 -#define C_SWIZZLE_D 6 - -#define C_FILE_NULL 0 -#define C_FILE_CONSTANT 1 -#define C_FILE_INPUT 2 -#define C_FILE_OUTPUT 3 -#define C_FILE_TEMPORARY 4 -#define C_FILE_SAMPLER 5 -#define C_FILE_ADDRESS 6 -#define C_FILE_IMMEDIATE 7 -#define C_FILE_LOOP 8 -#define C_FILE_PREDICATE 9 -#define C_FILE_SYSTEM_VALUE 10 -#define C_FILE_RESOURCE 11 -#define C_FILE_COUNT 12 - -#define C_SEMANTIC_POSITION 0 -#define C_SEMANTIC_COLOR 1 -#define C_SEMANTIC_BCOLOR 2 /**< back-face color */ -#define C_SEMANTIC_FOG 3 -#define C_SEMANTIC_PSIZE 4 -#define C_SEMANTIC_GENERIC 5 -#define C_SEMANTIC_NORMAL 6 -#define C_SEMANTIC_FACE 7 -#define C_SEMANTIC_EDGEFLAG 8 -#define C_SEMANTIC_PRIMID 9 -#define C_SEMANTIC_INSTANCEID 10 -#define C_SEMANTIC_VERTEXID 11 -#define C_SEMANTIC_COUNT 12 /**< number of semantic values */ - -#define C_OPCODE_NOP 0 -#define C_OPCODE_MOV 1 -#define C_OPCODE_LIT 2 -#define C_OPCODE_RCP 3 -#define C_OPCODE_RSQ 4 -#define C_OPCODE_EXP 5 -#define C_OPCODE_LOG 6 -#define C_OPCODE_MUL 7 -#define C_OPCODE_ADD 8 -#define C_OPCODE_DP3 9 -#define C_OPCODE_DP4 10 -#define C_OPCODE_DST 11 -#define C_OPCODE_MIN 12 -#define C_OPCODE_MAX 13 -#define C_OPCODE_SLT 14 -#define C_OPCODE_SGE 15 -#define C_OPCODE_MAD 16 -#define C_OPCODE_SUB 17 -#define C_OPCODE_LRP 18 -#define C_OPCODE_CND 19 -/* gap */ -#define C_OPCODE_DP2A 21 -/* gap */ -#define C_OPCODE_FRC 24 -#define C_OPCODE_CLAMP 25 -#define C_OPCODE_FLR 26 -#define C_OPCODE_ROUND 27 -#define C_OPCODE_EX2 28 -#define C_OPCODE_LG2 29 -#define C_OPCODE_POW 30 -#define C_OPCODE_XPD 31 -/* gap */ -#define C_OPCODE_ABS 33 -#define C_OPCODE_RCC 34 -#define C_OPCODE_DPH 35 -#define C_OPCODE_COS 36 -#define C_OPCODE_DDX 37 -#define C_OPCODE_DDY 38 -#define C_OPCODE_KILP 39 /* predicated kill */ -#define C_OPCODE_PK2H 40 -#define C_OPCODE_PK2US 41 -#define C_OPCODE_PK4B 42 -#define C_OPCODE_PK4UB 43 -#define C_OPCODE_RFL 44 -#define C_OPCODE_SEQ 45 -#define C_OPCODE_SFL 46 -#define C_OPCODE_SGT 47 -#define C_OPCODE_SIN 48 -#define C_OPCODE_SLE 49 -#define C_OPCODE_SNE 50 -#define C_OPCODE_STR 51 -#define C_OPCODE_TEX 52 -#define C_OPCODE_TXD 53 -#define C_OPCODE_TXP 54 -#define C_OPCODE_UP2H 55 -#define C_OPCODE_UP2US 56 -#define C_OPCODE_UP4B 57 -#define C_OPCODE_UP4UB 58 -#define C_OPCODE_X2D 59 -#define C_OPCODE_ARA 60 -#define C_OPCODE_ARR 61 -#define C_OPCODE_BRA 62 -#define C_OPCODE_CAL 63 -#define C_OPCODE_RET 64 -#define C_OPCODE_SSG 65 /* SGN */ -#define C_OPCODE_CMP 66 -#define C_OPCODE_SCS 67 -#define C_OPCODE_TXB 68 -#define C_OPCODE_NRM 69 -#define C_OPCODE_DIV 70 -#define C_OPCODE_DP2 71 -#define C_OPCODE_TXL 72 -#define C_OPCODE_BRK 73 -#define C_OPCODE_IF 74 -#define C_OPCODE_BGNFOR 75 -#define C_OPCODE_REP 76 -#define C_OPCODE_ELSE 77 -#define C_OPCODE_ENDIF 78 -#define C_OPCODE_ENDFOR 79 -#define C_OPCODE_ENDREP 80 -#define C_OPCODE_PUSHA 81 -#define C_OPCODE_POPA 82 -#define C_OPCODE_CEIL 83 -#define C_OPCODE_I2F 84 -#define C_OPCODE_NOT 85 -#define C_OPCODE_TRUNC 86 -#define C_OPCODE_SHL 87 -/* gap */ -#define C_OPCODE_AND 89 -#define C_OPCODE_OR 90 -#define C_OPCODE_MOD 91 -#define C_OPCODE_XOR 92 -#define C_OPCODE_SAD 93 -#define C_OPCODE_TXF 94 -#define C_OPCODE_TXQ 95 -#define C_OPCODE_CONT 96 -#define C_OPCODE_EMIT 97 -#define C_OPCODE_ENDPRIM 98 -#define C_OPCODE_BGNLOOP 99 -#define C_OPCODE_BGNSUB 100 -#define C_OPCODE_ENDLOOP 101 -#define C_OPCODE_ENDSUB 102 -/* gap */ -#define C_OPCODE_NRM4 112 -#define C_OPCODE_CALLNZ 113 -#define C_OPCODE_IFC 114 -#define C_OPCODE_BREAKC 115 -#define C_OPCODE_KIL 116 /* conditional kill */ -#define C_OPCODE_END 117 /* aka HALT */ -/* gap */ -#define C_OPCODE_F2I 119 -#define C_OPCODE_IDIV 120 -#define C_OPCODE_IMAX 121 -#define C_OPCODE_IMIN 122 -#define C_OPCODE_INEG 123 -#define C_OPCODE_ISGE 124 -#define C_OPCODE_ISHR 125 -#define C_OPCODE_ISLT 126 -#define C_OPCODE_F2U 127 -#define C_OPCODE_U2F 128 -#define C_OPCODE_UADD 129 -#define C_OPCODE_UDIV 130 -#define C_OPCODE_UMAD 131 -#define C_OPCODE_UMAX 132 -#define C_OPCODE_UMIN 133 -#define C_OPCODE_UMOD 134 -#define C_OPCODE_UMUL 135 -#define C_OPCODE_USEQ 136 -#define C_OPCODE_USGE 137 -#define C_OPCODE_USHR 138 -#define C_OPCODE_USLT 139 -#define C_OPCODE_USNE 140 -#define C_OPCODE_SWITCH 141 -#define C_OPCODE_CASE 142 -#define C_OPCODE_DEFAULT 143 -#define C_OPCODE_ENDSWITCH 144 -#define C_OPCODE_VFETCH 145 -#define C_OPCODE_ENTRY 146 -#define C_OPCODE_ARL 147 -#define C_OPCODE_LAST 148 - -#define C_OPERAND_FLAG_ABS (1 << 0) -#define C_OPERAND_FLAG_NEG (1 << 1) - -struct c_operand { - struct c_vector *vector; - unsigned swizzle; - unsigned flag; -}; - -struct c_op { - unsigned ninput; - struct c_operand input[3]; - struct c_operand output; - unsigned opcode; -}; - -struct c_instruction { - struct list_head head; - unsigned nop; - struct c_op op[5]; -}; - -struct c_node; - -struct c_node_link { - struct list_head head; - struct c_node *node; -}; - -/** - * struct c_node - * - * @next: all node are in a double linked list, this point to - * next node - * @next: all node are in a double linked list, this point to - * previous node - * @predecessors: list of all predecessor nodes in the flow graph - * @successors: list of all sucessor nodes in the flow graph - * @parent: parent node in the depth first walk tree - * @childs: child nodes in the depth first walk tree - */ -struct c_node { - struct list_head head; - struct list_head predecessors; - struct list_head successors; - struct list_head childs; - struct c_node *parent; - struct list_head insts; - unsigned opcode; - unsigned visited; - unsigned done; - void *backend; -}; - -struct c_file { - unsigned nvectors; - struct list_head vectors; -}; - -struct c_shader { - unsigned nvectors; - struct c_file files[C_FILE_COUNT]; - struct list_head nodes; - struct c_node entry; - struct c_node end; - unsigned type; -}; - -int c_shader_init(struct c_shader *shader, unsigned type); -void c_shader_destroy(struct c_shader *shader); -struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid); -int c_shader_build_dominator_tree(struct c_shader *shader); -void c_shader_dump(struct c_shader *shader); - -void c_node_init(struct c_node *node); -int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction); -int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction); - -/* control flow graph functions */ -int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor); -struct c_node *c_node_cfg_new_after(struct c_node *predecessor); -struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor); - -struct c_vector *c_vector_new(void); - -#endif diff --git a/src/gallium/drivers/r600/r600_compiler_dump.c b/src/gallium/drivers/r600/r600_compiler_dump.c deleted file mode 100644 index bb022b7c298..00000000000 --- a/src/gallium/drivers/r600/r600_compiler_dump.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse <[email protected]> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <stdio.h> -#include "r600_compiler.h" - -static const char *c_file_swz[] = { - "x", - "y", - "z", - "w", - "0", - "1", - ".", -}; - -static const char *c_file_str[] = { - "NULL", - "CONSTANT", - "INPUT", - "OUTPUT", - "TEMPORARY", - "SAMPLER", - "ADDRESS", - "IMMEDIATE", - "LOOP", - "PREDICATE", - "SYSTEM_VALUE", -}; - -static const char *c_semantic_str[] = { - "POSITION", - "COLOR", - "BCOLOR", - "FOG", - "PSIZE", - "GENERIC", - "NORMAL", - "FACE", - "EDGEFLAG", - "PRIMID", - "INSTANCEID", -}; - -static const char *c_opcode_str[] = { - "ARL", - "MOV", - "LIT", - "RCP", - "RSQ", - "EXP", - "LOG", - "MUL", - "ADD", - "DP3", - "DP4", - "DST", - "MIN", - "MAX", - "SLT", - "SGE", - "MAD", - "SUB", - "LRP", - "CND", - "(INVALID)", - "DP2A", - "(INVALID)", - "(INVALID)", - "FRC", - "CLAMP", - "FLR", - "ROUND", - "EX2", - "LG2", - "POW", - "XPD", - "(INVALID)", - "ABS", - "RCC", - "DPH", - "COS", - "DDX", - "DDY", - "KILP", - "PK2H", - "PK2US", - "PK4B", - "PK4UB", - "RFL", - "SEQ", - "SFL", - "SGT", - "SIN", - "SLE", - "SNE", - "STR", - "TEX", - "TXD", - "TXP", - "UP2H", - "UP2US", - "UP4B", - "UP4UB", - "X2D", - "ARA", - "ARR", - "BRA", - "CAL", - "RET", - "SSG", - "CMP", - "SCS", - "TXB", - "NRM", - "DIV", - "DP2", - "TXL", - "BRK", - "IF", - "BGNFOR", - "REP", - "ELSE", - "ENDIF", - "ENDFOR", - "ENDREP", - "PUSHA", - "POPA", - "CEIL", - "I2F", - "NOT", - "TRUNC", - "SHL", - "(INVALID)", - "AND", - "OR", - "MOD", - "XOR", - "SAD", - "TXF", - "TXQ", - "CONT", - "EMIT", - "ENDPRIM", - "BGNLOOP", - "BGNSUB", - "ENDLOOP", - "ENDSUB", - "(INVALID)", - "(INVALID)", - "(INVALID)", - "(INVALID)", - "NOP", - "(INVALID)", - "(INVALID)", - "(INVALID)", - "(INVALID)", - "NRM4", - "CALLNZ", - "IFC", - "BREAKC", - "KIL", - "END", - "(INVALID)", - "F2I", - "IDIV", - "IMAX", - "IMIN", - "INEG", - "ISGE", - "ISHR", - "ISLT", - "F2U", - "U2F", - "UADD", - "UDIV", - "UMAD", - "UMAX", - "UMIN", - "UMOD", - "UMUL", - "USEQ", - "USGE", - "USHR", - "USLT", - "USNE", - "SWITCH", - "CASE", - "DEFAULT", - "ENDSWITCH", - "VFETCH", - "ENTRY", -}; - -static inline const char *c_get_name(const char *name[], unsigned i) -{ - return name[i]; -} - -static void pindent(unsigned indent) -{ - unsigned i; - for (i = 0; i < indent; i++) - fprintf(stderr, " "); -} - -static void c_node_dump(struct c_node *node, unsigned indent) -{ - struct c_instruction *i; - unsigned j, k; - - pindent(indent); fprintf(stderr, "# node %s\n", c_get_name(c_opcode_str, node->opcode)); - LIST_FOR_EACH_ENTRY(i, &node->insts, head) { - for (k = 0; k < i->nop; k++) { - pindent(indent); - fprintf(stderr, "%s", c_get_name(c_opcode_str, i->op[k].opcode)); - fprintf(stderr, " %s[%d][%s]", - c_get_name(c_file_str, i->op[k].output.vector->file), - i->op[k].output.vector->id, - c_get_name(c_file_swz, i->op[k].output.swizzle)); - for (j = 0; j < i->op[k].ninput; j++) { - fprintf(stderr, " %s[%d][%s]", - c_get_name(c_file_str, i->op[k].input[j].vector->file), - i->op[k].input[j].vector->id, - c_get_name(c_file_swz, i->op[k].input[j].swizzle)); - } - fprintf(stderr, ";\n"); - } - } -} - -static void c_shader_dump_rec(struct c_shader *shader, struct c_node *node, unsigned indent) -{ - struct c_node_link *link; - - c_node_dump(node, indent); - LIST_FOR_EACH_ENTRY(link, &node->childs, head) { - c_shader_dump_rec(shader, link->node, indent + 1); - } -} - -void c_shader_dump(struct c_shader *shader) -{ - c_shader_dump_rec(shader, &shader->entry, 0); -} diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c deleted file mode 100644 index 27ad8f1a182..00000000000 --- a/src/gallium/drivers/r600/r600_compiler_r600.c +++ /dev/null @@ -1,972 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse <[email protected]> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <stdio.h> -#include <errno.h> -#include <util/u_format.h> -#include "r600_screen.h" -#include "r600_context.h" -#include "r600_sq.h" - - -struct r600_alu_instruction { - unsigned copcode; - enum r600_instruction instruction; -}; - -static int r600_shader_alu_translate(struct r600_shader *rshader, - struct r600_shader_node *node, - struct c_instruction *instruction); -struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST]; -struct r600_instruction_info r600_instruction_info[]; - -int r600_shader_insert_fetch(struct c_shader *shader) -{ - struct c_vector *vi, *vr, *v, *nv; - struct c_instruction instruction; - int r; - - if (shader->type != C_PROGRAM_TYPE_VS) - return 0; - vi = c_shader_vector_new(shader, C_FILE_INPUT, C_SEMANTIC_VERTEXID, -1); - if (vi == NULL) - return -ENOMEM; - LIST_FOR_EACH_ENTRY_SAFE(v, nv, &shader->files[C_FILE_INPUT].vectors, head) { - if (v == vi) - continue; - vr = c_shader_vector_new(shader, C_FILE_RESOURCE, C_SEMANTIC_GENERIC, -1); - if (vr == NULL) - return -ENOMEM; - memset(&instruction, 0, sizeof(struct c_instruction)); - instruction.nop = 4; - instruction.op[0].opcode = C_OPCODE_VFETCH; - instruction.op[1].opcode = C_OPCODE_VFETCH; - instruction.op[2].opcode = C_OPCODE_VFETCH; - instruction.op[3].opcode = C_OPCODE_VFETCH; - instruction.op[0].ninput = 2; - instruction.op[1].ninput = 2; - instruction.op[2].ninput = 2; - instruction.op[3].ninput = 2; - instruction.op[0].output.vector = v; - instruction.op[1].output.vector = v; - instruction.op[2].output.vector = v; - instruction.op[3].output.vector = v; - instruction.op[0].input[0].vector = vi; - instruction.op[0].input[1].vector = vr; - instruction.op[1].input[0].vector = vi; - instruction.op[1].input[1].vector = vr; - instruction.op[2].input[0].vector = vi; - instruction.op[2].input[1].vector = vr; - instruction.op[3].input[0].vector = vi; - instruction.op[3].input[1].vector = vr; - instruction.op[0].output.swizzle = C_SWIZZLE_X; - instruction.op[1].output.swizzle = C_SWIZZLE_Y; - instruction.op[2].output.swizzle = C_SWIZZLE_Z; - instruction.op[3].output.swizzle = C_SWIZZLE_W; - r = c_node_add_new_instruction_head(&shader->entry, &instruction); - if (r) - return r; - LIST_DEL(&v->head); - shader->files[C_FILE_INPUT].nvectors--; - LIST_ADDTAIL(&v->head, &shader->files[C_FILE_TEMPORARY].vectors); - shader->files[C_FILE_TEMPORARY].nvectors++; - v->file = C_FILE_TEMPORARY; - } - return 0; -} - -void r600_shader_cleanup(struct r600_shader *rshader) -{ - struct r600_shader_node *n, *nn; - struct r600_shader_vfetch *vf, *nvf; - struct r600_shader_alu *alu, *nalu; - int i; - - if (rshader == NULL) - return; - if (rshader->gpr) { - for (i = 0; i < rshader->nvector; i++) { - free(rshader->gpr[i]); - } - free(rshader->gpr); - rshader->gpr = NULL; - } - LIST_FOR_EACH_ENTRY_SAFE(n, nn, &rshader->nodes, head) { - LIST_DEL(&n->head); - LIST_FOR_EACH_ENTRY_SAFE(vf, nvf, &n->vfetch, head) { - LIST_DEL(&vf->head); - free(vf); - } - LIST_FOR_EACH_ENTRY_SAFE(alu, nalu, &n->alu, head) { - LIST_DEL(&alu->head); - free(alu); - } - free(n); - } - free(rshader->bcode); - return; -} - -int r600_shader_vfetch_bytecode(struct r600_shader *rshader, - struct r600_shader_node *rnode, - struct r600_shader_vfetch *vfetch, - unsigned *cid) -{ - unsigned id = *cid; - - vfetch->cf_addr = id; - rshader->bcode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vfetch->src[1].sel) | - S_SQ_VTX_WORD0_SRC_GPR(vfetch->src[0].sel) | - S_SQ_VTX_WORD0_SRC_SEL_X(vfetch->src[0].sel) | - S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(0x1F); - rshader->bcode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vfetch->dst[0].chan) | - S_SQ_VTX_WORD1_DST_SEL_Y(vfetch->dst[1].chan) | - S_SQ_VTX_WORD1_DST_SEL_Z(vfetch->dst[2].chan) | - S_SQ_VTX_WORD1_DST_SEL_W(vfetch->dst[3].chan) | - S_SQ_VTX_WORD1_USE_CONST_FIELDS(1) | - S_SQ_VTX_WORD1_GPR_DST_GPR(vfetch->dst[0].sel); - rshader->bcode[id++] = S_SQ_VTX_WORD2_MEGA_FETCH(1); - rshader->bcode[id++] = 0; - *cid = id; - return 0; -} - -int r600_shader_update(struct r600_shader *rshader, enum pipe_format *resource_format) -{ - struct r600_shader_node *rnode; - struct r600_shader_vfetch *vfetch; - unsigned i; - - memcpy(rshader->resource_format, resource_format, - rshader->nresource * sizeof(enum pipe_format)); - LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) { - LIST_FOR_EACH_ENTRY(vfetch, &rnode->vfetch, head) { - const struct util_format_description *desc; - i = vfetch->cf_addr + 1; - rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_X; - rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_Y; - rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_Z; - rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_W; - desc = util_format_description(resource_format[vfetch->src[1].sel]); - if (desc == NULL) { - fprintf(stderr, "%s unknown format %d\n", __func__, resource_format[vfetch->src[1].sel]); - continue; - } - /* WARNING so far TGSI swizzle match R600 ones */ - rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_X(desc->swizzle[0]); - rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_Y(desc->swizzle[1]); - rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_Z(desc->swizzle[2]); - rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_W(desc->swizzle[3]); - } - } - return 0; -} - -int r600_shader_register(struct r600_shader *rshader) -{ - struct c_vector *v, *nv; - unsigned tid, cid, rid, i; - - rshader->nvector = rshader->cshader.nvectors; - rshader->gpr = calloc(rshader->nvector, sizeof(void*)); - if (rshader->gpr == NULL) - return -ENOMEM; - tid = 0; - cid = 0; - rid = 0; - /* alloc input first */ - LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[C_FILE_INPUT].vectors, head) { - nv = c_vector_new(); - if (nv == NULL) { - return -ENOMEM; - } - memcpy(nv, v, sizeof(struct c_vector)); - nv->id = tid++; - rshader->gpr[v->id] = nv; - } - for (i = 0; i < C_FILE_COUNT; i++) { - if (i == C_FILE_INPUT || i == C_FILE_IMMEDIATE) - continue; - LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[i].vectors, head) { - switch (v->file) { - case C_FILE_OUTPUT: - case C_FILE_TEMPORARY: - nv = c_vector_new(); - if (nv == NULL) { - return -ENOMEM; - } - memcpy(nv, v, sizeof(struct c_vector)); - nv->id = tid++; - rshader->gpr[v->id] = nv; - break; - case C_FILE_CONSTANT: - nv = c_vector_new(); - if (nv == NULL) { - return -ENOMEM; - } - memcpy(nv, v, sizeof(struct c_vector)); - nv->id = (cid++) + 256; - rshader->gpr[v->id] = nv; - break; - case C_FILE_RESOURCE: - nv = c_vector_new(); - if (nv == NULL) { - return -ENOMEM; - } - memcpy(nv, v, sizeof(struct c_vector)); - nv->id = (rid++); - rshader->gpr[v->id] = nv; - break; - default: - fprintf(stderr, "%s:%d unsupported file %d\n", __func__, __LINE__, v->file); - return -EINVAL; - } - } - } - rshader->ngpr = tid; - rshader->nconstant = cid; - rshader->nresource = rid; - return 0; -} - -int r600_shader_find_gpr(struct r600_shader *rshader, struct c_vector *v, unsigned swizzle, - struct r600_shader_operand *operand) -{ - struct c_vector *tmp; - - /* Values [0,127] correspond to GPR[0..127]. - * Values [256,511] correspond to cfile constants c[0..255]. - * Other special values are shown in the list below. - * 248 SQ_ALU_SRC_0: special constant 0.0. - * 249 SQ_ALU_SRC_1: special constant 1.0 float. - * 250 SQ_ALU_SRC_1_INT: special constant 1 integer. - * 251 SQ_ALU_SRC_M_1_INT: special constant -1 integer. - * 252 SQ_ALU_SRC_0_5: special constant 0.5 float. - * 253 SQ_ALU_SRC_LITERAL: literal constant. - * 254 SQ_ALU_SRC_PV: previous vector result. - * 255 SQ_ALU_SRC_PS: previous scalar result. - */ - operand->vector = v; - operand->sel = 248; - operand->chan = 0; - operand->neg = 0; - operand->abs = 0; - if (v == NULL) - return 0; - if (v->file == C_FILE_IMMEDIATE) { - operand->sel = 253; - } else { - tmp = rshader->gpr[v->id]; - if (tmp == NULL) { - fprintf(stderr, "%s %d unknown register\n", __FILE__, __LINE__); - return -EINVAL; - } - operand->sel = tmp->id; - } - operand->chan = swizzle; - switch (swizzle) { - case C_SWIZZLE_X: - case C_SWIZZLE_Y: - case C_SWIZZLE_Z: - case C_SWIZZLE_W: - break; - case C_SWIZZLE_0: - operand->sel = 248; - operand->chan = 0; - break; - case C_SWIZZLE_1: - operand->sel = 249; - operand->chan = 0; - break; - default: - fprintf(stderr, "%s %d invalid swizzle %d\n", __FILE__, __LINE__, swizzle); - return -EINVAL; - } - return 0; -} - -static struct r600_shader_node *r600_shader_new_node(struct r600_shader *rshader, struct c_node *node) -{ - struct r600_shader_node *rnode; - - rnode = CALLOC_STRUCT(r600_shader_node); - if (rnode == NULL) - return NULL; - rnode->node = node; - LIST_INITHEAD(&rnode->vfetch); -fprintf(stderr, "------------------------ new node (%p %p)\n", &rnode->vfetch, rnode->vfetch.next); - LIST_INITHEAD(&rnode->alu); - LIST_ADDTAIL(&rnode->head, &rshader->nodes); - return rnode; -} - -static int r600_shader_add_vfetch(struct r600_shader *rshader, - struct r600_shader_node *node, - struct c_instruction *instruction) -{ - struct r600_shader_vfetch *vfetch; - struct r600_shader_node *rnode; - int r; - - if (instruction == NULL) - return 0; - if (instruction->op[0].opcode != C_OPCODE_VFETCH) - return 0; - if (!LIST_IS_EMPTY(&node->alu)) { - rnode = r600_shader_new_node(rshader, node->node); - if (rnode == NULL) - return -ENOMEM; - node = rnode; - } - vfetch = calloc(1, sizeof(struct r600_shader_vfetch)); - if (vfetch == NULL) - return -ENOMEM; - r = r600_shader_find_gpr(rshader, instruction->op[0].output.vector, 0, &vfetch->dst[0]); - if (r) - return r; - r = r600_shader_find_gpr(rshader, instruction->op[0].input[0].vector, 0, &vfetch->src[0]); - if (r) - return r; - r = r600_shader_find_gpr(rshader, instruction->op[0].input[1].vector, 0, &vfetch->src[1]); - if (r) - return r; - vfetch->dst[0].chan = C_SWIZZLE_X; - vfetch->dst[1].chan = C_SWIZZLE_Y; - vfetch->dst[2].chan = C_SWIZZLE_Z; - vfetch->dst[3].chan = C_SWIZZLE_W; - LIST_ADDTAIL(&vfetch->head, &node->vfetch); - node->nslot += 2; - return 0; -} - -static int r600_node_translate(struct r600_shader *rshader, struct c_node *node) -{ - struct c_instruction *instruction; - struct r600_shader_node *rnode; - int r; - - rnode = r600_shader_new_node(rshader, node); - if (rnode == NULL) - return -ENOMEM; - LIST_FOR_EACH_ENTRY(instruction, &node->insts, head) { - switch (instruction->op[0].opcode) { - case C_OPCODE_VFETCH: - r = r600_shader_add_vfetch(rshader, rnode, instruction); - if (r) { - fprintf(stderr, "%s %d vfetch failed\n", __func__, __LINE__); - return r; - } - break; - default: - r = r600_shader_alu_translate(rshader, rnode, instruction); - if (r) { - fprintf(stderr, "%s %d alu failed\n", __func__, __LINE__); - return r; - } - break; - } - } - return 0; -} - -int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node) -{ - struct c_node_link *link; - int r; - - if (node->opcode == C_OPCODE_END) - return 0; - r = r600_node_translate(rshader, node); - if (r) - return r; - LIST_FOR_EACH_ENTRY(link, &node->childs, head) { - r = r600_shader_translate_rec(rshader, link->node); - if (r) - return r; - } - return 0; -} - -static struct r600_shader_alu *r600_shader_insert_alu(struct r600_shader *rshader, struct r600_shader_node *node) -{ - struct r600_shader_alu *alu; - - alu = CALLOC_STRUCT(r600_shader_alu); - if (alu == NULL) - return NULL; - alu->alu[0].inst = INST_NOP; - alu->alu[1].inst = INST_NOP; - alu->alu[2].inst = INST_NOP; - alu->alu[3].inst = INST_NOP; - alu->alu[4].inst = INST_NOP; - alu->alu[0].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - alu->alu[1].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - alu->alu[2].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - alu->alu[3].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - alu->alu[4].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; - alu->alu[1].dst.chan = 1; - alu->alu[2].dst.chan = 2; - alu->alu[3].dst.chan = 3; - LIST_ADDTAIL(&alu->head, &node->alu); - return alu; -} - -static int r600_shader_alu_translate(struct r600_shader *rshader, - struct r600_shader_node *node, - struct c_instruction *instruction) -{ - struct r600_shader_node *rnode; - struct r600_shader_alu *alu; - int i, j, r, litteral_lastcomp = -1; - - if (!LIST_IS_EMPTY(&node->vfetch)) { -fprintf(stderr, "------------------------ add node (%p %p)\n", &node->vfetch, node->vfetch.next); - rnode = r600_shader_new_node(rshader, node->node); - if (rnode == NULL) { - fprintf(stderr, "%s %d new node failed\n", __func__, __LINE__); - return -ENOMEM; - } - node = rnode; - } - - /* initialize alu */ - alu = r600_shader_insert_alu(rshader, node); - - /* check special operation like lit */ - - /* go through operation */ - for (i = 0; i < instruction->nop; i++) { - struct r600_alu_instruction *ainfo = &r600_alu_instruction[instruction->op[i].opcode]; - struct r600_instruction_info *iinfo = &r600_instruction_info[ainfo->instruction]; - unsigned comp; - - /* check that output is a valid component */ - comp = instruction->op[i].output.swizzle; - switch (comp) { - case C_SWIZZLE_X: - case C_SWIZZLE_Y: - case C_SWIZZLE_Z: - case C_SWIZZLE_W: - break; - case C_SWIZZLE_0: - case C_SWIZZLE_1: - default: - fprintf(stderr, "%s %d invalid output %d\n", __func__, __LINE__, comp); - return -EINVAL; - } - alu->alu[comp].inst = ainfo->instruction; - alu->alu[comp].opcode = iinfo->opcode; - alu->alu[comp].is_op3 = iinfo->is_op3; - for (j = 0; j < instruction->op[i].ninput; j++) { - r = r600_shader_find_gpr(rshader, instruction->op[i].input[j].vector, - instruction->op[i].input[j].swizzle, &alu->alu[comp].src[j]); - if (r) { - fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__); - return r; - } - if (instruction->op[i].input[j].vector->file == C_FILE_IMMEDIATE) { - r = instruction->op[i].input[j].swizzle; - switch (r) { - case C_SWIZZLE_X: - case C_SWIZZLE_Y: - case C_SWIZZLE_Z: - case C_SWIZZLE_W: - break; - case C_SWIZZLE_0: - case C_SWIZZLE_1: - default: - fprintf(stderr, "%s %d invalid input\n", __func__, __LINE__); - return -EINVAL; - } - alu->literal[r] = instruction->op[i].input[j].vector->channel[r]->value; - if (r > litteral_lastcomp) { - litteral_lastcomp = r; - } - } - } - r = r600_shader_find_gpr(rshader, instruction->op[i].output.vector, - instruction->op[i].output.swizzle, &alu->alu[comp].dst); - if (r) { - fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__); - return r; - } - } - switch (litteral_lastcomp) { - case 0: - case 1: - alu->nliteral = 2; - break; - case 2: - case 3: - alu->nliteral = 4; - break; - case -1: - default: - break; - } - for (i = 4; i >= 0; i--) { - if (alu->alu[i].inst != INST_NOP) { - alu->alu[i].last = 1; - alu->nalu = i + 1; - break; - } - } - return 0; -} - -void r600_shader_node_place(struct r600_shader *rshader) -{ - struct r600_shader_node *node, *nnode; - struct r600_shader_alu *alu, *nalu; - struct r600_shader_vfetch *vfetch, *nvfetch; - unsigned cf_id = 0, cf_addr = 0; - - rshader->ncf = 0; - rshader->nslot = 0; - LIST_FOR_EACH_ENTRY_SAFE(node, nnode, &rshader->nodes, head) { - LIST_FOR_EACH_ENTRY_SAFE(alu, nalu, &node->alu, head) { - node->nslot += alu->nalu; - node->nslot += alu->nliteral >> 1; - } - node->nfetch = 0; - LIST_FOR_EACH_ENTRY_SAFE(vfetch, nvfetch, &node->vfetch, head) { - node->nslot += 2; - node->nfetch += 1; - } - if (!LIST_IS_EMPTY(&node->vfetch)) { - /* fetch node need to be 16 bytes aligned*/ - cf_addr += 1; - cf_addr &= 0xFFFFFFFEUL; - } - node->cf_id = cf_id; - node->cf_addr = cf_addr; - cf_id += 2; - cf_addr += node->nslot * 2; - rshader->ncf++; - } - rshader->nslot = cf_addr; - LIST_FOR_EACH_ENTRY_SAFE(node, nnode, &rshader->nodes, head) { - node->cf_addr += cf_id * 2; - } - rshader->ncf += rshader->cshader.files[C_FILE_OUTPUT].nvectors; - rshader->ndw = rshader->ncf * 2 + rshader->nslot * 2; -} - -int r600_shader_legalize(struct r600_shader *rshader) -{ - return 0; -} - - -static int r600_cshader_legalize_rec(struct c_shader *shader, struct c_node *node) -{ - struct c_node_link *link; - struct c_instruction *i, *n; - struct c_operand operand; - unsigned k, inst; - int r; - - LIST_FOR_EACH_ENTRY(i, &node->insts, head) { - for (k = 0; k < i->nop; k++) { - switch (i->op[k].opcode) { - case C_OPCODE_SLT: - i->op[k].opcode = C_OPCODE_SGT; - memcpy(&operand, &i->op[k].input[0], sizeof(struct c_operand)); - memcpy(&i->op[k].input[0], &i->op[k].input[1], sizeof(struct c_operand)); - memcpy(&i->op[k].input[1], &operand, sizeof(struct c_operand)); - break; - default: - break; - } - inst = r600_alu_instruction[i->op[k].opcode].instruction; - if (r600_instruction_info[inst].is_trans && k < (i->nop -1)) { - /* split trans opcode */ - n = CALLOC_STRUCT(c_instruction); - if (n == NULL) - return -ENOMEM; - for (n->nop = 0, k = k + 1; k < i->nop; k++, n->nop++) { - memcpy(&n->op[n->nop - 0], &i->op[k], sizeof(struct c_op)); - } - i->nop -= n->nop; - LIST_ADD(&n->head, &i->head); - } - } - } - LIST_FOR_EACH_ENTRY(link, &node->childs, head) { - r = r600_cshader_legalize_rec(shader, link->node); - if (r) { - return r; - } - } - return 0; -} - -int r600_cshader_legalize(struct c_shader *shader) -{ - return r600_cshader_legalize_rec(shader, &shader->entry); -} - - -struct r600_instruction_info r600_instruction_info[] = { - {INST_ADD, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, 0, 0}, - {INST_MUL, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, 0, 0}, - {INST_MUL_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL_IEEE, 0, 0}, - {INST_MAX, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX, 0, 0}, - {INST_MIN, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN, 0, 0}, - {INST_MAX_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_DX10, 0, 0}, - {INST_MIN_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_DX10, 0, 0}, - {INST_SETE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE, 0, 0}, - {INST_SETGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT, 0, 0}, - {INST_SETGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE, 0, 0}, - {INST_SETNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, 0, 0}, - {INST_SETE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_DX10, 0, 0}, - {INST_SETGT_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_DX10, 0, 0}, - {INST_SETGE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_DX10, 0, 0}, - {INST_SETNE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_DX10, 0, 0}, - {INST_FRACT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT, 0, 0}, - {INST_TRUNC, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC, 0, 0}, - {INST_CEIL, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CEIL, 0, 0}, - {INST_RNDNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RNDNE, 0, 0}, - {INST_FLOOR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR, 0, 0}, - {INST_MOVA, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA, 0, 0}, - {INST_MOVA_FLOOR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR, 0, 0}, - {INST_MOVA_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT, 0, 0}, - {INST_MOV, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, 0, 0}, - {INST_NOP, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 0, 0}, - {INST_PRED_SETGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT, 0, 0}, - {INST_PRED_SETGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT, 0, 0}, - {INST_PRED_SETE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE, 0, 0}, - {INST_PRED_SETGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT, 0, 0}, - {INST_PRED_SETGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE, 0, 0}, - {INST_PRED_SETNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE, 0, 0}, - {INST_PRED_SET_INV, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV, 0, 0}, - {INST_PRED_SET_POP, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP, 0, 0}, - {INST_PRED_SET_CLR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR, 0, 0}, - {INST_PRED_SET_RESTORE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE, 0, 0}, - {INST_PRED_SETE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH, 0, 0}, - {INST_PRED_SETGT_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH, 0, 0}, - {INST_PRED_SETGE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH, 0, 0}, - {INST_PRED_SETNE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH, 0, 0}, - {INST_KILLE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE, 0, 0}, - {INST_KILLGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT, 0, 0}, - {INST_KILLGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE, 0, 0}, - {INST_KILLNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE, 0, 0}, - {INST_AND_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_AND_INT, 0, 0}, - {INST_OR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_OR_INT, 0, 0}, - {INST_XOR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_XOR_INT, 0, 0}, - {INST_NOT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOT_INT, 0, 0}, - {INST_ADD_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD_INT, 0, 0}, - {INST_SUB_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SUB_INT, 0, 0}, - {INST_MAX_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_INT, 0, 0}, - {INST_MIN_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_INT, 0, 0}, - {INST_MAX_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_UINT, 0, 0}, - {INST_MIN_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_UINT, 0, 0}, - {INST_SETE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_INT, 0, 0}, - {INST_SETGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_INT, 0, 0}, - {INST_SETGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_INT, 0, 0}, - {INST_SETNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_INT, 0, 0}, - {INST_SETGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_UINT, 0, 0}, - {INST_SETGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_UINT, 0, 0}, - {INST_KILLGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT, 0, 0}, - {INST_KILLGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT, 0, 0}, - {INST_PRED_SETE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT, 0, 0}, - {INST_PRED_SETGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT, 0, 0}, - {INST_PRED_SETGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT, 0, 0}, - {INST_PRED_SETNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT, 0, 0}, - {INST_KILLE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT, 0, 0}, - {INST_KILLGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT, 0, 0}, - {INST_KILLGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT, 0, 0}, - {INST_KILLNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT, 0, 0}, - {INST_PRED_SETE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT, 0, 0}, - {INST_PRED_SETGT_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT, 0, 0}, - {INST_PRED_SETGE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT, 0, 0}, - {INST_PRED_SETNE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT, 0, 0}, - {INST_PRED_SETLT_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT, 0, 0}, - {INST_PRED_SETLE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT, 0, 0}, - {INST_DOT4, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, 0, 0}, - {INST_DOT4_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE, 0, 0}, - {INST_CUBE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE, 0, 0}, - {INST_MAX4, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4, 0, 0}, - {INST_MOVA_GPR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_GPR_INT, 0, 0}, - {INST_EXP_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE, 1, 0}, - {INST_LOG_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED, 1, 0}, - {INST_LOG_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE, 1, 0}, - {INST_RECIP_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED, 1, 0}, - {INST_RECIP_FF, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF, 1, 0}, - {INST_RECIP_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, 1, 0}, - {INST_RECIPSQRT_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED, 1, 0}, - {INST_RECIPSQRT_FF, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF, 1, 0}, - {INST_RECIPSQRT_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, 1, 0}, - {INST_SQRT_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE, 1, 0}, - {INST_FLT_TO_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT, 1, 0}, - {INST_INT_TO_FLT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT, 1, 0}, - {INST_UINT_TO_FLT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT, 1, 0}, - {INST_SIN, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN, 1, 0}, - {INST_COS, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS, 1, 0}, - {INST_ASHR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT, 1, 0}, - {INST_LSHR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT, 1, 0}, - {INST_LSHL_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT, 1, 0}, - {INST_MULLO_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT, 1, 0}, - {INST_MULHI_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT, 1, 0}, - {INST_MULLO_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT, 1, 0}, - {INST_MULHI_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT, 1, 0}, - {INST_RECIP_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT, 1, 0}, - {INST_RECIP_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT, 1, 0}, - {INST_FLT_TO_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_UINT, 1, 0}, - {INST_MUL_LIT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT, 1, 1}, - {INST_MUL_LIT_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2, 1, 1}, - {INST_MUL_LIT_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4, 1, 1}, - {INST_MUL_LIT_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2, 1, 1}, - {INST_MULADD, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD, 0, 1}, - {INST_MULADD_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M2, 0, 1}, - {INST_MULADD_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M4, 0, 1}, - {INST_MULADD_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_D2, 0, 1}, - {INST_MULADD_IEEE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE, 0, 1}, - {INST_MULADD_IEEE_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M2, 0, 1}, - {INST_MULADD_IEEE_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M4, 0, 1}, - {INST_MULADD_IEEE_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_D2, 0, 1}, - {INST_CNDE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE, 0, 1}, - {INST_CNDGT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT, 0, 1}, - {INST_CNDGE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE, 0, 1}, - {INST_CNDE_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE_INT, 0, 1}, - {INST_CNDGT_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT_INT, 0, 1}, - {INST_CNDGE_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE_INT, 0, 1}, -}; - -struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST] = { - {C_OPCODE_NOP, INST_NOP}, - {C_OPCODE_MOV, INST_MOV}, - {C_OPCODE_LIT, INST_NOP}, - {C_OPCODE_RCP, INST_RECIP_IEEE}, - {C_OPCODE_RSQ, INST_RECIPSQRT_IEEE}, - {C_OPCODE_EXP, INST_EXP_IEEE}, - {C_OPCODE_LOG, INST_LOG_IEEE}, - {C_OPCODE_MUL, INST_MUL}, - {C_OPCODE_ADD, INST_ADD}, - {C_OPCODE_DP3, INST_DOT4}, - {C_OPCODE_DP4, INST_DOT4}, - {C_OPCODE_DST, INST_NOP}, - {C_OPCODE_MIN, INST_MIN}, - {C_OPCODE_MAX, INST_MAX}, - {C_OPCODE_SLT, INST_NOP}, - {C_OPCODE_SGE, INST_NOP}, - {C_OPCODE_MAD, INST_MULADD}, - {C_OPCODE_SUB, INST_COUNT}, - {C_OPCODE_LRP, INST_NOP}, - {C_OPCODE_CND, INST_NOP}, - {20, INST_NOP}, - {C_OPCODE_DP2A, INST_NOP}, - {22, INST_NOP}, - {23, INST_NOP}, - {C_OPCODE_FRC, INST_NOP}, - {C_OPCODE_CLAMP, INST_NOP}, - {C_OPCODE_FLR, INST_NOP}, - {C_OPCODE_ROUND, INST_NOP}, - {C_OPCODE_EX2, INST_NOP}, - {C_OPCODE_LG2, INST_NOP}, - {C_OPCODE_POW, INST_NOP}, - {C_OPCODE_XPD, INST_NOP}, - {32, INST_NOP}, - {C_OPCODE_ABS, INST_COUNT}, - {C_OPCODE_RCC, INST_NOP}, - {C_OPCODE_DPH, INST_NOP}, - {C_OPCODE_COS, INST_COS}, - {C_OPCODE_DDX, INST_NOP}, - {C_OPCODE_DDY, INST_NOP}, - {C_OPCODE_KILP, INST_NOP}, - {C_OPCODE_PK2H, INST_NOP}, - {C_OPCODE_PK2US, INST_NOP}, - {C_OPCODE_PK4B, INST_NOP}, - {C_OPCODE_PK4UB, INST_NOP}, - {C_OPCODE_RFL, INST_NOP}, - {C_OPCODE_SEQ, INST_NOP}, - {C_OPCODE_SFL, INST_NOP}, - {C_OPCODE_SGT, INST_SETGT}, - {C_OPCODE_SIN, INST_SIN}, - {C_OPCODE_SLE, INST_NOP}, - {C_OPCODE_SNE, INST_NOP}, - {C_OPCODE_STR, INST_NOP}, - {C_OPCODE_TEX, INST_NOP}, - {C_OPCODE_TXD, INST_NOP}, - {C_OPCODE_TXP, INST_NOP}, - {C_OPCODE_UP2H, INST_NOP}, - {C_OPCODE_UP2US, INST_NOP}, - {C_OPCODE_UP4B, INST_NOP}, - {C_OPCODE_UP4UB, INST_NOP}, - {C_OPCODE_X2D, INST_NOP}, - {C_OPCODE_ARA, INST_NOP}, - {C_OPCODE_ARR, INST_NOP}, - {C_OPCODE_BRA, INST_NOP}, - {C_OPCODE_CAL, INST_NOP}, - {C_OPCODE_RET, INST_NOP}, - {C_OPCODE_SSG, INST_NOP}, - {C_OPCODE_CMP, INST_NOP}, - {C_OPCODE_SCS, INST_NOP}, - {C_OPCODE_TXB, INST_NOP}, - {C_OPCODE_NRM, INST_NOP}, - {C_OPCODE_DIV, INST_NOP}, - {C_OPCODE_DP2, INST_NOP}, - {C_OPCODE_TXL, INST_NOP}, - {C_OPCODE_BRK, INST_NOP}, - {C_OPCODE_IF, INST_NOP}, - {C_OPCODE_BGNFOR, INST_NOP}, - {C_OPCODE_REP, INST_NOP}, - {C_OPCODE_ELSE, INST_NOP}, - {C_OPCODE_ENDIF, INST_NOP}, - {C_OPCODE_ENDFOR, INST_NOP}, - {C_OPCODE_ENDREP, INST_NOP}, - {C_OPCODE_PUSHA, INST_NOP}, - {C_OPCODE_POPA, INST_NOP}, - {C_OPCODE_CEIL, INST_NOP}, - {C_OPCODE_I2F, INST_NOP}, - {C_OPCODE_NOT, INST_NOP}, - {C_OPCODE_TRUNC, INST_NOP}, - {C_OPCODE_SHL, INST_NOP}, - {88, INST_NOP}, - {C_OPCODE_AND, INST_NOP}, - {C_OPCODE_OR, INST_NOP}, - {C_OPCODE_MOD, INST_NOP}, - {C_OPCODE_XOR, INST_NOP}, - {C_OPCODE_SAD, INST_NOP}, - {C_OPCODE_TXF, INST_NOP}, - {C_OPCODE_TXQ, INST_NOP}, - {C_OPCODE_CONT, INST_NOP}, - {C_OPCODE_EMIT, INST_NOP}, - {C_OPCODE_ENDPRIM, INST_NOP}, - {C_OPCODE_BGNLOOP, INST_NOP}, - {C_OPCODE_BGNSUB, INST_NOP}, - {C_OPCODE_ENDLOOP, INST_NOP}, - {C_OPCODE_ENDSUB, INST_NOP}, - {103, INST_NOP}, - {104, INST_NOP}, - {105, INST_NOP}, - {106, INST_NOP}, - {107, INST_NOP}, - {108, INST_NOP}, - {109, INST_NOP}, - {110, INST_NOP}, - {111, INST_NOP}, - {C_OPCODE_NRM4, INST_NOP}, - {C_OPCODE_CALLNZ, INST_NOP}, - {C_OPCODE_IFC, INST_NOP}, - {C_OPCODE_BREAKC, INST_NOP}, - {C_OPCODE_KIL, INST_NOP}, - {C_OPCODE_END, INST_NOP}, - {118, INST_NOP}, - {C_OPCODE_F2I, INST_NOP}, - {C_OPCODE_IDIV, INST_NOP}, - {C_OPCODE_IMAX, INST_NOP}, - {C_OPCODE_IMIN, INST_NOP}, - {C_OPCODE_INEG, INST_NOP}, - {C_OPCODE_ISGE, INST_NOP}, - {C_OPCODE_ISHR, INST_NOP}, - {C_OPCODE_ISLT, INST_NOP}, - {C_OPCODE_F2U, INST_NOP}, - {C_OPCODE_U2F, INST_NOP}, - {C_OPCODE_UADD, INST_NOP}, - {C_OPCODE_UDIV, INST_NOP}, - {C_OPCODE_UMAD, INST_NOP}, - {C_OPCODE_UMAX, INST_NOP}, - {C_OPCODE_UMIN, INST_NOP}, - {C_OPCODE_UMOD, INST_NOP}, - {C_OPCODE_UMUL, INST_NOP}, - {C_OPCODE_USEQ, INST_NOP}, - {C_OPCODE_USGE, INST_NOP}, - {C_OPCODE_USHR, INST_NOP}, - {C_OPCODE_USLT, INST_NOP}, - {C_OPCODE_USNE, INST_NOP}, - {C_OPCODE_SWITCH, INST_NOP}, - {C_OPCODE_CASE, INST_NOP}, - {C_OPCODE_DEFAULT, INST_NOP}, - {C_OPCODE_ENDSWITCH, INST_NOP}, - {C_OPCODE_VFETCH, INST_NOP}, - {C_OPCODE_ENTRY, INST_NOP}, - {C_OPCODE_ARL, INST_NOP}, -}; - - -static int r600_shader_alu_bytecode(struct r600_shader *rshader, - struct r600_shader_node *rnode, - struct r600_shader_inst *alu, - unsigned *cid) -{ - unsigned id = *cid; - - /* don't replace gpr by pv or ps for destination register */ - if (alu->is_op3) { - rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) | - S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) | - S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) | - S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) | - S_SQ_ALU_WORD0_LAST(alu->last); - rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | - S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | - S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) | - S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) | - S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) | - S_SQ_ALU_WORD1_OP3_ALU_INST(alu->opcode) | - S_SQ_ALU_WORD1_BANK_SWIZZLE(0); - } else { - rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) | - S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) | - S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) | - S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) | - S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) | - S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) | - S_SQ_ALU_WORD0_LAST(alu->last); - rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | - S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | - S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) | - S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) | - S_SQ_ALU_WORD1_OP2_WRITE_MASK(1) | - S_SQ_ALU_WORD1_OP2_ALU_INST(alu->opcode) | - S_SQ_ALU_WORD1_BANK_SWIZZLE(0); - } - *cid = id; - return 0; -} - -int r6xx_shader_alu_translate(struct r600_shader *rshader, - struct r600_shader_node *rnode, - unsigned *cid) -{ - struct r600_shader_alu *alu; - unsigned id = *cid; - int i; - int r = 0; - LIST_FOR_EACH_ENTRY(alu, &rnode->alu, head) { - for (i = 0; i < alu->nalu; i++) { - r = r600_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id); - if (r) - goto out; - } - for (i = 0; i < alu->nliteral; i++) { - rshader->bcode[id++] = alu->literal[i]; - } - } -out: - *cid = id; - return r; -} diff --git a/src/gallium/drivers/r600/r600_compiler_r700.c b/src/gallium/drivers/r600/r600_compiler_r700.c deleted file mode 100644 index 0b439428662..00000000000 --- a/src/gallium/drivers/r600/r600_compiler_r700.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse <[email protected]> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <stdio.h> -#include <errno.h> -#include "r600_context.h" -#include "r700_sq.h" - -static int r700_shader_cf_node_bytecode(struct r600_shader *rshader, - struct r600_shader_node *rnode, - unsigned *cid) -{ - unsigned id = *cid; - - if (rnode->nfetch) { - rshader->bcode[id++] = S_SQ_CF_WORD0_ADDR(rnode->cf_addr >> 1); - rshader->bcode[id++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) | - S_SQ_CF_WORD1_BARRIER(1) | - S_SQ_CF_WORD1_COUNT(rnode->nfetch - 1); - } else { - rshader->bcode[id++] = S_SQ_CF_ALU_WORD0_ADDR(rnode->cf_addr >> 1); - rshader->bcode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU) | - S_SQ_CF_ALU_WORD1_BARRIER(1) | - S_SQ_CF_ALU_WORD1_COUNT(rnode->nslot - 1); - } - *cid = id; - return 0; -} - -static int r700_shader_cf_output_bytecode(struct r600_shader *rshader, - struct c_vector *v, - unsigned *cid, - unsigned end) -{ - struct r600_shader_operand out; - unsigned id = *cid; - int r; - - r = r600_shader_find_gpr(rshader, v, 0, &out); - if (r) - return r; - rshader->bcode[id + 0] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(out.sel) | - S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(3); - rshader->bcode[id + 1] = S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(0) | - S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(1) | - S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(2) | - S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(3) | - S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(1) | - S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE) | - S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(end); - switch (v->name) { - case C_SEMANTIC_POSITION: - rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(60) | - S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS); - break; - case C_SEMANTIC_COLOR: - if (rshader->cshader.type == C_PROGRAM_TYPE_VS) { - rshader->output[rshader->noutput].gpr = out.sel; - rshader->output[rshader->noutput].sid = v->sid; - rshader->output[rshader->noutput].name = v->name; - rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(rshader->noutput++) | - S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM); - } else { - rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(0) | - S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL); - } - break; - case C_SEMANTIC_GENERIC: - rshader->output[rshader->noutput].gpr = out.sel; - rshader->output[rshader->noutput].sid = v->sid; - rshader->output[rshader->noutput].name = v->name; - rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(rshader->noutput++) | - S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM); - break; - default: - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - *cid = id + 2; - return 0; -} - -static int r700_shader_alu_bytecode(struct r600_shader *rshader, - struct r600_shader_node *rnode, - struct r600_shader_inst *alu, - unsigned *cid) -{ - unsigned id = *cid; - - /* don't replace gpr by pv or ps for destination register */ - if (alu->is_op3) { - rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) | - S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) | - S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) | - S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) | - S_SQ_ALU_WORD0_LAST(alu->last); - rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | - S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | - S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) | - S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) | - S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) | - S_SQ_ALU_WORD1_OP3_ALU_INST(alu->opcode) | - S_SQ_ALU_WORD1_BANK_SWIZZLE(0); - } else { - rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) | - S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) | - S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) | - S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) | - S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) | - S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) | - S_SQ_ALU_WORD0_LAST(alu->last); - rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | - S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | - S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) | - S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) | - S_SQ_ALU_WORD1_OP2_WRITE_MASK(1) | - S_SQ_ALU_WORD1_OP2_ALU_INST(alu->opcode) | - S_SQ_ALU_WORD1_BANK_SWIZZLE(0); - } - *cid = id; - return 0; -} - -static int r700_shader_alu_translate(struct r600_shader *rshader, - struct r600_shader_node *rnode, - unsigned *cid) - -{ - struct r600_shader_alu *alu; - unsigned id = *cid; - int i; - int r = 0; - LIST_FOR_EACH_ENTRY(alu, &rnode->alu, head) { - for (i = 0; i < alu->nalu; i++) { - r = r700_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id); - if (r) - goto out; - } - for (i = 0; i < alu->nliteral; i++) { - rshader->bcode[id++] = alu->literal[i]; - } - } - out: - *cid = id; - return r; -} - -int r700_shader_translate(struct r600_shader *rshader) -{ - struct c_shader *shader = &rshader->cshader; - struct r600_shader_node *rnode; - struct r600_shader_vfetch *vfetch; - struct c_vector *v; - unsigned id, end; - int r; - - r = r600_shader_register(rshader); - if (r) { - fprintf(stderr, "%s %d register allocation failed\n", __FILE__, __LINE__); - return r; - } - r = r600_shader_translate_rec(rshader, &shader->entry); - if (r) { - fprintf(stderr, "%s %d translation failed\n", __FILE__, __LINE__); - return r; - } - r = r600_shader_legalize(rshader); - if (r) { - fprintf(stderr, "%s %d legalize failed\n", __FILE__, __LINE__); - return r; - } - r600_shader_node_place(rshader); - rshader->bcode = malloc(rshader->ndw * 4); - if (rshader->bcode == NULL) - return -ENOMEM; - LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) { - id = rnode->cf_addr; - LIST_FOR_EACH_ENTRY(vfetch, &rnode->vfetch, head) { - r = r600_shader_vfetch_bytecode(rshader, rnode, vfetch, &id); - if (r) - return r; - } - if (rshader->r6xx_compile) - r = r6xx_shader_alu_translate(rshader, rnode, &id); - else - r = r700_shader_alu_translate(rshader, rnode, &id); - if (r) - return r; - } - id = 0; - LIST_FOR_EACH_ENTRY(rnode, &rshader->nodes, head) { - r = r700_shader_cf_node_bytecode(rshader, rnode, &id); - if (r) - return r; - } - LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[C_FILE_OUTPUT].vectors, head) { - end = 0; - if (v->head.next == &rshader->cshader.files[C_FILE_OUTPUT].vectors) - end = 1; - r = r700_shader_cf_output_bytecode(rshader, v, &id, end); - if (r) - return r; - } - LIST_FOR_EACH_ENTRY(v, &rshader->cshader.files[C_FILE_INPUT].vectors, head) { - rshader->input[rshader->ninput].gpr = rshader->ninput; - rshader->input[rshader->ninput].sid = v->sid; - rshader->input[rshader->ninput].name = v->name; - rshader->ninput++; - } - return 0; -} diff --git a/src/gallium/drivers/r600/r600_compiler_tgsi.c b/src/gallium/drivers/r600/r600_compiler_tgsi.c deleted file mode 100644 index 172cf154a34..00000000000 --- a/src/gallium/drivers/r600/r600_compiler_tgsi.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse <[email protected]> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <stdio.h> -#include <errno.h> -#include <tgsi/tgsi_parse.h> -#include <tgsi/tgsi_scan.h> -#include "r600_shader.h" -#include "r600_context.h" - -struct tgsi_shader { - struct c_vector **v[TGSI_FILE_COUNT]; - struct tgsi_shader_info info; - struct tgsi_parse_context parser; - const struct tgsi_token *tokens; - struct c_shader *shader; - struct c_node *node; -}; - -static unsigned tgsi_file_to_c_file(unsigned file); -static unsigned tgsi_sname_to_c_sname(unsigned sname); -static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode); - -static int tgsi_shader_init(struct tgsi_shader *ts, - const struct tgsi_token *tokens, - struct c_shader *shader) -{ - int i; - - ts->shader = shader; - ts->tokens = tokens; - tgsi_scan_shader(ts->tokens, &ts->info); - tgsi_parse_init(&ts->parser, ts->tokens); - /* initialize to NULL in case of error */ - for (i = 0; i < C_FILE_COUNT; i++) { - ts->v[i] = NULL; - } - for (i = 0; i < TGSI_FILE_COUNT; i++) { - if (ts->info.file_count[i] > 0) { - ts->v[i] = calloc(ts->info.file_count[i], sizeof(void*)); - if (ts->v[i] == NULL) { - fprintf(stderr, "%s:%d unsupported %d %d\n", __func__, __LINE__, i, ts->info.file_count[i]); - return -ENOMEM; - } - } - } - return 0; -} - -static void tgsi_shader_destroy(struct tgsi_shader *ts) -{ - int i; - - for (i = 0; i < TGSI_FILE_COUNT; i++) { - free(ts->v[i]); - } - tgsi_parse_free(&ts->parser); -} - -static int ntransform_declaration(struct tgsi_shader *ts) -{ - struct tgsi_full_declaration *fd = &ts->parser.FullToken.FullDeclaration; - struct c_vector *v; - unsigned file; - unsigned name; - int sid; - int i; - - if (fd->Declaration.Dimension) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - for (i = fd->Range.First ; i <= fd->Range.Last; i++) { - sid = i; - name = C_SEMANTIC_GENERIC; - file = tgsi_file_to_c_file(fd->Declaration.File); - if (file == TGSI_FILE_NULL) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - if (fd->Declaration.Semantic) { - name = tgsi_sname_to_c_sname(fd->Semantic.Name); - sid = fd->Semantic.Index; - } - v = c_shader_vector_new(ts->shader, file, name, sid); - if (v == NULL) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -ENOMEM; - } - ts->v[fd->Declaration.File][i] = v; - } - return 0; -} - -static int ntransform_immediate(struct tgsi_shader *ts) -{ - struct tgsi_full_immediate *fd = &ts->parser.FullToken.FullImmediate; - struct c_vector *v; - unsigned file; - unsigned name; - - if (fd->Immediate.DataType != TGSI_IMM_FLOAT32) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - name = C_SEMANTIC_GENERIC; - file = C_FILE_IMMEDIATE; - v = c_shader_vector_new(ts->shader, file, name, 0); - if (v == NULL) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return -ENOMEM; - } - v->channel[0]->value = fd->u[0].Uint; - v->channel[1]->value = fd->u[1].Uint; - v->channel[2]->value = fd->u[2].Uint; - v->channel[3]->value = fd->u[3].Uint; - ts->v[TGSI_FILE_IMMEDIATE][0] = v; - return 0; -} - -static int ntransform_instruction(struct tgsi_shader *ts) -{ - struct tgsi_full_instruction *fi = &ts->parser.FullToken.FullInstruction; - struct c_shader *shader = ts->shader; - struct c_instruction instruction; - unsigned opcode; - int i, j, r; - - if (fi->Instruction.NumDstRegs > 1) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - if (fi->Instruction.Saturate) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - if (fi->Instruction.Predicate) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - if (fi->Instruction.Label) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - if (fi->Instruction.Texture) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - for (i = 0; i < fi->Instruction.NumSrcRegs; i++) { - if (fi->Src[i].Register.Indirect || - fi->Src[i].Register.Dimension || - fi->Src[i].Register.Absolute) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - } - for (i = 0; i < fi->Instruction.NumDstRegs; i++) { - if (fi->Dst[i].Register.Indirect || fi->Dst[i].Register.Dimension) { - fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__); - return -EINVAL; - } - } - r = tgsi_opcode_to_c_opcode(fi->Instruction.Opcode, &opcode); - if (r) { - fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__); - return r; - } - if (opcode == C_OPCODE_END) { - return c_node_cfg_link(ts->node, &shader->end); - } - /* FIXME add flow instruction handling */ - memset(&instruction, 0, sizeof(struct c_instruction)); - instruction.nop = 0; - for (j = 0; j < 4; j++) { - instruction.op[instruction.nop].opcode = opcode; - instruction.op[instruction.nop].ninput = fi->Instruction.NumSrcRegs; - for (i = 0; i < fi->Instruction.NumSrcRegs; i++) { - instruction.op[instruction.nop].input[i].vector = ts->v[fi->Src[i].Register.File][fi->Src[i].Register.Index]; - switch (j) { - case 0: - instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleX; - break; - case 1: - instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleY; - break; - case 2: - instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleZ; - break; - case 3: - instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleW; - break; - default: - return -EINVAL; - } - } - instruction.op[instruction.nop].output.vector = ts->v[fi->Dst[0].Register.File][fi->Dst[0].Register.Index]; - switch (j) { - case 0: - instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_X : C_SWIZZLE_D; - break; - case 1: - instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_Y : C_SWIZZLE_D; - break; - case 2: - instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_Z : C_SWIZZLE_D; - break; - case 3: - instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_W : C_SWIZZLE_D; - break; - default: - return -EINVAL; - } - instruction.nop++; - } - return c_node_add_new_instruction(ts->node, &instruction); -} - -int c_shader_from_tgsi(struct c_shader *shader, unsigned type, - const struct tgsi_token *tokens) -{ - struct tgsi_shader ts; - int r = 0; - - c_shader_init(shader, type); - r = tgsi_shader_init(&ts, tokens, shader); - if (r) - goto out_err; - ts.shader = shader; - ts.node = &shader->entry; - while (!tgsi_parse_end_of_tokens(&ts.parser)) { - tgsi_parse_token(&ts.parser); - switch (ts.parser.FullToken.Token.Type) { - case TGSI_TOKEN_TYPE_IMMEDIATE: - r = ntransform_immediate(&ts); - if (r) - goto out_err; - break; - case TGSI_TOKEN_TYPE_DECLARATION: - r = ntransform_declaration(&ts); - if (r) - goto out_err; - break; - case TGSI_TOKEN_TYPE_INSTRUCTION: - r = ntransform_instruction(&ts); - if (r) - goto out_err; - break; - default: - r = -EINVAL; - goto out_err; - } - } - tgsi_shader_destroy(&ts); - return 0; -out_err: - c_shader_destroy(shader); - tgsi_shader_destroy(&ts); - return r; -} - -static unsigned tgsi_file_to_c_file(unsigned file) -{ - switch (file) { - case TGSI_FILE_CONSTANT: - return C_FILE_CONSTANT; - case TGSI_FILE_INPUT: - return C_FILE_INPUT; - case TGSI_FILE_OUTPUT: - return C_FILE_OUTPUT; - case TGSI_FILE_TEMPORARY: - return C_FILE_TEMPORARY; - case TGSI_FILE_SAMPLER: - return C_FILE_SAMPLER; - case TGSI_FILE_ADDRESS: - return C_FILE_ADDRESS; - case TGSI_FILE_IMMEDIATE: - return C_FILE_IMMEDIATE; - case TGSI_FILE_PREDICATE: - return C_FILE_PREDICATE; - case TGSI_FILE_SYSTEM_VALUE: - return C_FILE_SYSTEM_VALUE; - case TGSI_FILE_NULL: - return C_FILE_NULL; - default: - fprintf(stderr, "%s:%d unsupported file %d\n", __func__, __LINE__, file); - return C_FILE_NULL; - } -} - -static unsigned tgsi_sname_to_c_sname(unsigned sname) -{ - switch (sname) { - case TGSI_SEMANTIC_POSITION: - return C_SEMANTIC_POSITION; - case TGSI_SEMANTIC_COLOR: - return C_SEMANTIC_COLOR; - case TGSI_SEMANTIC_BCOLOR: - return C_SEMANTIC_BCOLOR; - case TGSI_SEMANTIC_FOG: - return C_SEMANTIC_FOG; - case TGSI_SEMANTIC_PSIZE: - return C_SEMANTIC_PSIZE; - case TGSI_SEMANTIC_GENERIC: - return C_SEMANTIC_GENERIC; - case TGSI_SEMANTIC_NORMAL: - return C_SEMANTIC_NORMAL; - case TGSI_SEMANTIC_FACE: - return C_SEMANTIC_FACE; - case TGSI_SEMANTIC_EDGEFLAG: - return C_SEMANTIC_EDGEFLAG; - case TGSI_SEMANTIC_PRIMID: - return C_SEMANTIC_PRIMID; - case TGSI_SEMANTIC_INSTANCEID: - return C_SEMANTIC_INSTANCEID; - default: - return C_SEMANTIC_GENERIC; - } -} - -static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode) -{ - switch (opcode) { - case TGSI_OPCODE_MOV: - *copcode = C_OPCODE_MOV; - return 0; - case TGSI_OPCODE_MUL: - *copcode = C_OPCODE_MUL; - return 0; - case TGSI_OPCODE_MAD: - *copcode = C_OPCODE_MAD; - return 0; - case TGSI_OPCODE_END: - *copcode = C_OPCODE_END; - return 0; - case TGSI_OPCODE_ARL: - *copcode = C_OPCODE_ARL; - return 0; - case TGSI_OPCODE_LIT: - *copcode = C_OPCODE_LIT; - return 0; - case TGSI_OPCODE_RCP: - *copcode = C_OPCODE_RCP; - return 0; - case TGSI_OPCODE_RSQ: - *copcode = C_OPCODE_RSQ; - return 0; - case TGSI_OPCODE_EXP: - *copcode = C_OPCODE_EXP; - return 0; - case TGSI_OPCODE_LOG: - *copcode = C_OPCODE_LOG; - return 0; - case TGSI_OPCODE_ADD: - *copcode = C_OPCODE_ADD; - return 0; - case TGSI_OPCODE_DP3: - *copcode = C_OPCODE_DP3; - return 0; - case TGSI_OPCODE_DP4: - *copcode = C_OPCODE_DP4; - return 0; - case TGSI_OPCODE_DST: - *copcode = C_OPCODE_DST; - return 0; - case TGSI_OPCODE_MIN: - *copcode = C_OPCODE_MIN; - return 0; - case TGSI_OPCODE_MAX: - *copcode = C_OPCODE_MAX; - return 0; - case TGSI_OPCODE_SLT: - *copcode = C_OPCODE_SLT; - return 0; - case TGSI_OPCODE_SGE: - *copcode = C_OPCODE_SGE; - return 0; - case TGSI_OPCODE_SUB: - *copcode = C_OPCODE_SUB; - return 0; - case TGSI_OPCODE_LRP: - *copcode = C_OPCODE_LRP; - return 0; - case TGSI_OPCODE_CND: - *copcode = C_OPCODE_CND; - return 0; - case TGSI_OPCODE_DP2A: - *copcode = C_OPCODE_DP2A; - return 0; - case TGSI_OPCODE_FRC: - *copcode = C_OPCODE_FRC; - return 0; - case TGSI_OPCODE_CLAMP: - *copcode = C_OPCODE_CLAMP; - return 0; - case TGSI_OPCODE_FLR: - *copcode = C_OPCODE_FLR; - return 0; - case TGSI_OPCODE_ROUND: - *copcode = C_OPCODE_ROUND; - return 0; - case TGSI_OPCODE_EX2: - *copcode = C_OPCODE_EX2; - return 0; - case TGSI_OPCODE_LG2: - *copcode = C_OPCODE_LG2; - return 0; - case TGSI_OPCODE_POW: - *copcode = C_OPCODE_POW; - return 0; - case TGSI_OPCODE_XPD: - *copcode = C_OPCODE_XPD; - return 0; - case TGSI_OPCODE_ABS: - *copcode = C_OPCODE_ABS; - return 0; - case TGSI_OPCODE_RCC: - *copcode = C_OPCODE_RCC; - return 0; - case TGSI_OPCODE_DPH: - *copcode = C_OPCODE_DPH; - return 0; - case TGSI_OPCODE_COS: - *copcode = C_OPCODE_COS; - return 0; - case TGSI_OPCODE_DDX: - *copcode = C_OPCODE_DDX; - return 0; - case TGSI_OPCODE_DDY: - *copcode = C_OPCODE_DDY; - return 0; - case TGSI_OPCODE_KILP: - *copcode = C_OPCODE_KILP; - return 0; - case TGSI_OPCODE_PK2H: - *copcode = C_OPCODE_PK2H; - return 0; - case TGSI_OPCODE_PK2US: - *copcode = C_OPCODE_PK2US; - return 0; - case TGSI_OPCODE_PK4B: - *copcode = C_OPCODE_PK4B; - return 0; - case TGSI_OPCODE_PK4UB: - *copcode = C_OPCODE_PK4UB; - return 0; - case TGSI_OPCODE_RFL: - *copcode = C_OPCODE_RFL; - return 0; - case TGSI_OPCODE_SEQ: - *copcode = C_OPCODE_SEQ; - return 0; - case TGSI_OPCODE_SFL: - *copcode = C_OPCODE_SFL; - return 0; - case TGSI_OPCODE_SGT: - *copcode = C_OPCODE_SGT; - return 0; - case TGSI_OPCODE_SIN: - *copcode = C_OPCODE_SIN; - return 0; - case TGSI_OPCODE_SLE: - *copcode = C_OPCODE_SLE; - return 0; - case TGSI_OPCODE_SNE: - *copcode = C_OPCODE_SNE; - return 0; - case TGSI_OPCODE_STR: - *copcode = C_OPCODE_STR; - return 0; - case TGSI_OPCODE_TEX: - *copcode = C_OPCODE_TEX; - return 0; - case TGSI_OPCODE_TXD: - *copcode = C_OPCODE_TXD; - return 0; - case TGSI_OPCODE_TXP: - *copcode = C_OPCODE_TXP; - return 0; - case TGSI_OPCODE_UP2H: - *copcode = C_OPCODE_UP2H; - return 0; - case TGSI_OPCODE_UP2US: - *copcode = C_OPCODE_UP2US; - return 0; - case TGSI_OPCODE_UP4B: - *copcode = C_OPCODE_UP4B; - return 0; - case TGSI_OPCODE_UP4UB: - *copcode = C_OPCODE_UP4UB; - return 0; - case TGSI_OPCODE_X2D: - *copcode = C_OPCODE_X2D; - return 0; - case TGSI_OPCODE_ARA: - *copcode = C_OPCODE_ARA; - return 0; - case TGSI_OPCODE_ARR: - *copcode = C_OPCODE_ARR; - return 0; - case TGSI_OPCODE_BRA: - *copcode = C_OPCODE_BRA; - return 0; - case TGSI_OPCODE_CAL: - *copcode = C_OPCODE_CAL; - return 0; - case TGSI_OPCODE_RET: - *copcode = C_OPCODE_RET; - return 0; - case TGSI_OPCODE_SSG: - *copcode = C_OPCODE_SSG; - return 0; - case TGSI_OPCODE_CMP: - *copcode = C_OPCODE_CMP; - return 0; - case TGSI_OPCODE_SCS: - *copcode = C_OPCODE_SCS; - return 0; - case TGSI_OPCODE_TXB: - *copcode = C_OPCODE_TXB; - return 0; - case TGSI_OPCODE_NRM: - *copcode = C_OPCODE_NRM; - return 0; - case TGSI_OPCODE_DIV: - *copcode = C_OPCODE_DIV; - return 0; - case TGSI_OPCODE_DP2: - *copcode = C_OPCODE_DP2; - return 0; - case TGSI_OPCODE_TXL: - *copcode = C_OPCODE_TXL; - return 0; - case TGSI_OPCODE_BRK: - *copcode = C_OPCODE_BRK; - return 0; - case TGSI_OPCODE_IF: - *copcode = C_OPCODE_IF; - return 0; - case TGSI_OPCODE_ELSE: - *copcode = C_OPCODE_ELSE; - return 0; - case TGSI_OPCODE_ENDIF: - *copcode = C_OPCODE_ENDIF; - return 0; - case TGSI_OPCODE_PUSHA: - *copcode = C_OPCODE_PUSHA; - return 0; - case TGSI_OPCODE_POPA: - *copcode = C_OPCODE_POPA; - return 0; - case TGSI_OPCODE_CEIL: - *copcode = C_OPCODE_CEIL; - return 0; - case TGSI_OPCODE_I2F: - *copcode = C_OPCODE_I2F; - return 0; - case TGSI_OPCODE_NOT: - *copcode = C_OPCODE_NOT; - return 0; - case TGSI_OPCODE_TRUNC: - *copcode = C_OPCODE_TRUNC; - return 0; - case TGSI_OPCODE_SHL: - *copcode = C_OPCODE_SHL; - return 0; - case TGSI_OPCODE_AND: - *copcode = C_OPCODE_AND; - return 0; - case TGSI_OPCODE_OR: - *copcode = C_OPCODE_OR; - return 0; - case TGSI_OPCODE_MOD: - *copcode = C_OPCODE_MOD; - return 0; - case TGSI_OPCODE_XOR: - *copcode = C_OPCODE_XOR; - return 0; - case TGSI_OPCODE_SAD: - *copcode = C_OPCODE_SAD; - return 0; - case TGSI_OPCODE_TXF: - *copcode = C_OPCODE_TXF; - return 0; - case TGSI_OPCODE_TXQ: - *copcode = C_OPCODE_TXQ; - return 0; - case TGSI_OPCODE_CONT: - *copcode = C_OPCODE_CONT; - return 0; - case TGSI_OPCODE_EMIT: - *copcode = C_OPCODE_EMIT; - return 0; - case TGSI_OPCODE_ENDPRIM: - *copcode = C_OPCODE_ENDPRIM; - return 0; - case TGSI_OPCODE_BGNLOOP: - *copcode = C_OPCODE_BGNLOOP; - return 0; - case TGSI_OPCODE_BGNSUB: - *copcode = C_OPCODE_BGNSUB; - return 0; - case TGSI_OPCODE_ENDLOOP: - *copcode = C_OPCODE_ENDLOOP; - return 0; - case TGSI_OPCODE_ENDSUB: - *copcode = C_OPCODE_ENDSUB; - return 0; - case TGSI_OPCODE_NOP: - *copcode = C_OPCODE_NOP; - return 0; - case TGSI_OPCODE_NRM4: - *copcode = C_OPCODE_NRM4; - return 0; - case TGSI_OPCODE_CALLNZ: - *copcode = C_OPCODE_CALLNZ; - return 0; - case TGSI_OPCODE_IFC: - *copcode = C_OPCODE_IFC; - return 0; - case TGSI_OPCODE_BREAKC: - *copcode = C_OPCODE_BREAKC; - return 0; - case TGSI_OPCODE_KIL: - *copcode = C_OPCODE_KIL; - return 0; - case TGSI_OPCODE_F2I: - *copcode = C_OPCODE_F2I; - return 0; - case TGSI_OPCODE_IDIV: - *copcode = C_OPCODE_IDIV; - return 0; - case TGSI_OPCODE_IMAX: - *copcode = C_OPCODE_IMAX; - return 0; - case TGSI_OPCODE_IMIN: - *copcode = C_OPCODE_IMIN; - return 0; - case TGSI_OPCODE_INEG: - *copcode = C_OPCODE_INEG; - return 0; - case TGSI_OPCODE_ISGE: - *copcode = C_OPCODE_ISGE; - return 0; - case TGSI_OPCODE_ISHR: - *copcode = C_OPCODE_ISHR; - return 0; - case TGSI_OPCODE_ISLT: - *copcode = C_OPCODE_ISLT; - return 0; - case TGSI_OPCODE_F2U: - *copcode = C_OPCODE_F2U; - return 0; - case TGSI_OPCODE_U2F: - *copcode = C_OPCODE_U2F; - return 0; - case TGSI_OPCODE_UADD: - *copcode = C_OPCODE_UADD; - return 0; - case TGSI_OPCODE_UDIV: - *copcode = C_OPCODE_UDIV; - return 0; - case TGSI_OPCODE_UMAD: - *copcode = C_OPCODE_UMAD; - return 0; - case TGSI_OPCODE_UMAX: - *copcode = C_OPCODE_UMAX; - return 0; - case TGSI_OPCODE_UMIN: - *copcode = C_OPCODE_UMIN; - return 0; - case TGSI_OPCODE_UMOD: - *copcode = C_OPCODE_UMOD; - return 0; - case TGSI_OPCODE_UMUL: - *copcode = C_OPCODE_UMUL; - return 0; - case TGSI_OPCODE_USEQ: - *copcode = C_OPCODE_USEQ; - return 0; - case TGSI_OPCODE_USGE: - *copcode = C_OPCODE_USGE; - return 0; - case TGSI_OPCODE_USHR: - *copcode = C_OPCODE_USHR; - return 0; - case TGSI_OPCODE_USLT: - *copcode = C_OPCODE_USLT; - return 0; - case TGSI_OPCODE_USNE: - *copcode = C_OPCODE_USNE; - return 0; - case TGSI_OPCODE_SWITCH: - *copcode = C_OPCODE_SWITCH; - return 0; - case TGSI_OPCODE_CASE: - *copcode = C_OPCODE_CASE; - return 0; - case TGSI_OPCODE_DEFAULT: - *copcode = C_OPCODE_DEFAULT; - return 0; - case TGSI_OPCODE_ENDSWITCH: - *copcode = C_OPCODE_ENDSWITCH; - return 0; - default: - fprintf(stderr, "%s:%d unsupported opcode %d\n", __func__, __LINE__, opcode); - return -EINVAL; - } -} diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c index 05575b57676..edde80c660a 100644 --- a/src/gallium/drivers/r600/r600_context.c +++ b/src/gallium/drivers/r600/r600_context.c @@ -29,9 +29,9 @@ #include <util/u_format.h> #include <util/u_memory.h> #include <util/u_blitter.h> -#include "r600_resource.h" #include "r600_screen.h" #include "r600_context.h" +#include "r600_resource.h" #include "r600d.h" static void r600_destroy_context(struct pipe_context *context) @@ -41,26 +41,31 @@ static void r600_destroy_context(struct pipe_context *context) FREE(rctx); } -static void r600_flush(struct pipe_context *ctx, unsigned flags, +void r600_flush(struct pipe_context *ctx, unsigned flags, struct pipe_fence_handle **fence) { struct r600_context *rctx = r600_context(ctx); struct r600_screen *rscreen = rctx->screen; static int dc = 0; + char dname[256]; if (radeon_ctx_pm4(rctx->ctx)) return; /* FIXME dumping should be removed once shader support instructions * without throwing bad code */ - if (!dc) - radeon_ctx_dump_bof(rctx->ctx, "gallium.bof"); -#if 0 + if (!rctx->ctx->cpm4) + goto out; + sprintf(dname, "gallium-%08d.bof", dc); + if (dc < 1) + radeon_ctx_dump_bof(rctx->ctx, dname); +#if 1 radeon_ctx_submit(rctx->ctx); #endif + dc++; +out: rctx->ctx = radeon_ctx_decref(rctx->ctx); rctx->ctx = radeon_ctx(rscreen->rw); - dc++; } static void r600_init_config(struct r600_context *rctx) @@ -202,27 +207,9 @@ static void r600_init_config(struct r600_context *rctx) num_es_stack_entries = 0; break; } - printf("ps_prio : %d\n", ps_prio); - printf("vs_prio : %d\n", vs_prio); - printf("gs_prio : %d\n", gs_prio); - printf("es_prio : %d\n", es_prio); - printf("num_ps_gprs : %d\n", num_ps_gprs); - printf("num_vs_gprs : %d\n", num_vs_gprs); - printf("num_gs_gprs : %d\n", num_gs_gprs); - printf("num_es_gprs : %d\n", num_es_gprs); - printf("num_temp_gprs : %d\n", num_temp_gprs); - printf("num_ps_threads : %d\n", num_ps_threads); - printf("num_vs_threads : %d\n", num_vs_threads); - printf("num_gs_threads : %d\n", num_gs_threads); - printf("num_es_threads : %d\n", num_es_threads); - printf("num_ps_stack_entries : %d\n", num_ps_stack_entries); - printf("num_vs_stack_entries : %d\n", num_vs_stack_entries); - printf("num_gs_stack_entries : %d\n", num_gs_stack_entries); - printf("num_es_stack_entries : %d\n", num_es_stack_entries); - - rctx->config = radeon_state(rctx->rw, R600_CONFIG_TYPE, R600_CONFIG); + rctx->hw_states.config = radeon_state(rctx->rw, R600_CONFIG_TYPE, R600_CONFIG); - rctx->config->states[R600_CONFIG__SQ_CONFIG] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] = 0x00000000; switch (family) { case CHIP_RV610: case CHIP_RV620: @@ -231,75 +218,75 @@ static void r600_init_config(struct r600_context *rctx) case CHIP_RV710: break; default: - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1); break; } - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1); - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1); - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio); - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio); - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio); - rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio); + rctx->hw_states.config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio); - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0; - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs); - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs); - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs); + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0; + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs); + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs); + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs); - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0; - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs); - rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs); + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0; + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs); + rctx->hw_states.config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs); - rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0; - rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads); - rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads); - rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads); - rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads); + rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0; + rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads); + rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads); + rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads); + rctx->hw_states.config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads); - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0; - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries); - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries); + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0; + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries); + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries); - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0; - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries); - rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries); + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0; + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries); + rctx->hw_states.config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries); - rctx->config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000; - rctx->config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002; - rctx->config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000; - rctx->config->states[R600_CONFIG__DB_DEBUG] = 0x00000000; - rctx->config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204; - rctx->config->states[R600_CONFIG__SX_MISC] = 0x00000000; - rctx->config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001; - rctx->config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003; - rctx->config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000; - rctx->config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000; - rctx->config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001; - rctx->config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000; - rctx->config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000; - radeon_state_pm4(rctx->config); + rctx->hw_states.config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000; + rctx->hw_states.config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002; + rctx->hw_states.config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__DB_DEBUG] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204; + rctx->hw_states.config->states[R600_CONFIG__SX_MISC] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001; + rctx->hw_states.config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003; + rctx->hw_states.config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000; + rctx->hw_states.config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001; + rctx->hw_states.config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000; + rctx->hw_states.config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000; + radeon_state_pm4(rctx->hw_states.config); } struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) @@ -313,9 +300,7 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) rctx->context.screen = screen; rctx->context.priv = priv; rctx->context.destroy = r600_destroy_context; - rctx->context.draw_arrays = r600_draw_arrays; - rctx->context.draw_elements = r600_draw_elements; - rctx->context.draw_range_elements = r600_draw_range_elements; + rctx->context.draw_vbo = r600_draw_vbo; rctx->context.flush = r600_flush; /* Easy accessing of screen/winsys. */ @@ -333,20 +318,6 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv) return NULL; } - rctx->cb_cntl = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL); - rctx->cb_cntl->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F; - rctx->cb_cntl->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x0000000F; - rctx->cb_cntl->states[R600_CB_CNTL__CB_COLOR_CONTROL] = 0x00CC0000; - rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000; - rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000; - rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000; - rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000; - rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000; - rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF; - rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF; - rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF; - radeon_state_pm4(rctx->cb_cntl); - r600_init_config(rctx); rctx->ctx = radeon_ctx(rscreen->rw); diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h index f27ff58ed46..76d5de86532 100644 --- a/src/gallium/drivers/r600/r600_context.h +++ b/src/gallium/drivers/r600/r600_context.h @@ -23,6 +23,7 @@ #ifndef R600_CONTEXT_H #define R600_CONTEXT_H +#include <stdio.h> #include <pipe/p_state.h> #include <pipe/p_context.h> #include <tgsi/tgsi_scan.h> @@ -33,17 +34,74 @@ #include "r600_shader.h" /* XXX move this to a more appropriate place */ -struct r600_vertex_elements_state +union pipe_states { + struct pipe_rasterizer_state rasterizer; + struct pipe_poly_stipple poly_stipple; + struct pipe_scissor_state scissor; + struct pipe_clip_state clip; + struct pipe_shader_state shader; + struct pipe_depth_state depth; + struct pipe_stencil_state stencil; + struct pipe_alpha_state alpha; + struct pipe_depth_stencil_alpha_state dsa; + struct pipe_blend_state blend; + struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref; + struct pipe_framebuffer_state framebuffer; + struct pipe_sampler_state sampler; + struct pipe_sampler_view sampler_view; + struct pipe_viewport_state viewport; +}; + +enum pipe_state_type { + pipe_rasterizer_type = 1, + pipe_poly_stipple_type, + pipe_scissor_type, + pipe_clip_type, + pipe_shader_type, + pipe_depth_type, + pipe_stencil_type, + pipe_alpha_type, + pipe_dsa_type, + pipe_blend_type, + pipe_stencil_ref_type, + pipe_framebuffer_type, + pipe_sampler_type, + pipe_sampler_view_type, + pipe_viewport_type, + pipe_type_count +}; + +struct r600_context_state { + union pipe_states state; + unsigned refcount; + unsigned type; + struct radeon_state *rstate; + struct r600_shader shader; + struct radeon_bo *bo; +}; + +struct r600_vertex_element { - unsigned count; - struct pipe_vertex_element elements[32]; + unsigned refcount; + unsigned count; + struct pipe_vertex_element elements[32]; }; -struct r600_pipe_shader { - unsigned type; - struct r600_shader shader; - struct radeon_bo *bo; - struct radeon_state *state; +struct r600_context_hw_states { + struct radeon_state *rasterizer; + struct radeon_state *scissor; + struct radeon_state *dsa; + struct radeon_state *blend; + struct radeon_state *viewport; + struct radeon_state *cb[8]; + struct radeon_state *config; + struct radeon_state *cb_cntl; + struct radeon_state *db; + unsigned ps_nresource; + unsigned ps_nsampler; + struct radeon_state *ps_resource[160]; + struct radeon_state *ps_sampler[16]; }; struct r600_context { @@ -51,20 +109,39 @@ struct r600_context { struct r600_screen *screen; struct radeon *rw; struct radeon_ctx *ctx; - struct radeon_state *cb_cntl; - struct radeon_state *db; - struct radeon_state *config; - struct r600_pipe_shader *ps_shader; - struct r600_pipe_shader *vs_shader; + struct blitter_context *blitter; + struct radeon_draw *draw; + /* hw states */ + struct r600_context_hw_states hw_states; + /* pipe states */ unsigned flat_shade; + unsigned ps_nsampler; + unsigned vs_nsampler; + unsigned ps_nsampler_view; + unsigned vs_nsampler_view; unsigned nvertex_buffer; - struct r600_vertex_elements_state *vertex_elements; + struct r600_context_state *rasterizer; + struct r600_context_state *poly_stipple; + struct r600_context_state *scissor; + struct r600_context_state *clip; + struct r600_context_state *ps_shader; + struct r600_context_state *vs_shader; + struct r600_context_state *depth; + struct r600_context_state *stencil; + struct r600_context_state *alpha; + struct r600_context_state *dsa; + struct r600_context_state *blend; + struct r600_context_state *stencil_ref; + struct r600_context_state *viewport; + struct r600_context_state *framebuffer; + struct r600_context_state *ps_sampler[PIPE_MAX_ATTRIBS]; + struct r600_context_state *vs_sampler[PIPE_MAX_ATTRIBS]; + struct r600_context_state *ps_sampler_view[PIPE_MAX_ATTRIBS]; + struct r600_context_state *vs_sampler_view[PIPE_MAX_ATTRIBS]; + struct r600_vertex_element *vertex_elements; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - struct blitter_context *blitter; - struct pipe_stencil_ref stencil_ref; - struct pipe_framebuffer_state fb_state; - struct radeon_draw *draw; - struct pipe_viewport_state viewport; + struct pipe_index_buffer index_buffer; + struct pipe_blend_color blend_color; }; /* Convenience cast wrapper. */ @@ -73,27 +150,32 @@ static INLINE struct r600_context *r600_context(struct pipe_context *pipe) return (struct r600_context*)pipe; } -void r600_draw_arrays(struct pipe_context *ctx, unsigned mode, - unsigned start, unsigned count); -void r600_draw_elements(struct pipe_context *ctx, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, unsigned mode, - unsigned start, unsigned count); -void r600_draw_range_elements(struct pipe_context *ctx, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, unsigned min_index, - unsigned max_index, unsigned mode, - unsigned start, unsigned count); +struct r600_context_state *r600_context_state(struct r600_context *rctx, unsigned type, const void *state); +struct r600_context_state *r600_context_state_incref(struct r600_context_state *rstate); +struct r600_context_state *r600_context_state_decref(struct r600_context_state *rstate); +void r600_flush(struct pipe_context *ctx, unsigned flags, + struct pipe_fence_handle **fence); + +int r600_context_hw_states(struct r600_context *rctx); + +void r600_draw_vbo(struct pipe_context *ctx, + const struct pipe_draw_info *info); void r600_init_blit_functions(struct r600_context *rctx); void r600_init_state_functions(struct r600_context *rctx); void r600_init_query_functions(struct r600_context* rctx); struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv); -void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader); -struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, - unsigned type, - const struct tgsi_token *tokens); -int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader); +extern int r600_pipe_shader_create(struct pipe_context *ctx, + struct r600_context_state *rstate, + const struct tgsi_token *tokens); +extern int r600_pipe_shader_update(struct pipe_context *ctx, + struct r600_context_state *rstate); + +#define R600_ERR(fmt, args...) \ + fprintf(stderr, "EE %s/%s:%d - "fmt, __FILE__, __func__, __LINE__, ##args) +uint32_t r600_translate_texformat(enum pipe_format format, + const unsigned char *swizzle_view, + uint32_t *word4_p, uint32_t *yuv_format_p); #endif diff --git a/src/gallium/drivers/r600/r600_draw.c b/src/gallium/drivers/r600/r600_draw.c index 724fb6c988e..f0584551620 100644 --- a/src/gallium/drivers/r600/r600_draw.c +++ b/src/gallium/drivers/r600/r600_draw.c @@ -33,7 +33,8 @@ #include <util/u_memory.h> #include "r600_screen.h" #include "r600_context.h" -#include "r600d.h" +#include "r600_resource.h" +#include "r600_state_inlines.h" struct r600_draw { struct pipe_context *ctx; @@ -51,11 +52,15 @@ static int r600_draw_common(struct r600_draw *draw) struct r600_context *rctx = r600_context(draw->ctx); struct r600_screen *rscreen = rctx->screen; struct radeon_state *vs_resource; - struct r600_buffer *rbuffer; + struct r600_resource *rbuffer; unsigned i, j, offset, format, prim; u32 vgt_dma_index_type, vgt_draw_initiator; + struct pipe_vertex_buffer *vertex_buffer; int r; + r = r600_context_hw_states(rctx); + if (r) + return r; switch (draw->index_size) { case 2: vgt_draw_initiator = 0; @@ -83,29 +88,19 @@ static int r600_draw_common(struct r600_draw *draw) r = r600_pipe_shader_update(draw->ctx, rctx->ps_shader); if (r) return r; - r = radeon_draw_set(rctx->draw, rctx->vs_shader->state); - if (r) - return r; - r = radeon_draw_set(rctx->draw, rctx->ps_shader->state); + r = radeon_draw_set(rctx->draw, rctx->vs_shader->rstate); if (r) return r; - r = radeon_draw_set(rctx->draw, rctx->cb_cntl); - if (r) - return r; - r = radeon_draw_set(rctx->draw, rctx->db); - if (r) - return r; - r = radeon_draw_set(rctx->draw, rctx->config); + r = radeon_draw_set(rctx->draw, rctx->ps_shader->rstate); if (r) return r; for (i = 0 ; i < rctx->vertex_elements->count; i++) { j = rctx->vertex_elements->elements[i].vertex_buffer_index; - rbuffer = (struct r600_buffer*)rctx->vertex_buffer[j].buffer; - offset = rctx->vertex_elements->elements[i].src_offset + rctx->vertex_buffer[j].buffer_offset; - r = r600_conv_pipe_format(rctx->vertex_elements->elements[i].src_format, &format); - if (r) - return r; + vertex_buffer = &rctx->vertex_buffer[j]; + rbuffer = (struct r600_resource*)vertex_buffer->buffer; + offset = rctx->vertex_elements->elements[i].src_offset + vertex_buffer->buffer_offset; + format = r600_translate_colorformat(rctx->vertex_elements->elements[i].src_format); vs_resource = radeon_state(rscreen->rw, R600_VS_RESOURCE_TYPE, R600_VS_RESOURCE + i); if (vs_resource == NULL) return -ENOMEM; @@ -113,7 +108,7 @@ static int r600_draw_common(struct r600_draw *draw) vs_resource->nbo = 1; vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD0] = offset; vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD1] = rbuffer->bo->size - offset; - vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(rctx->vertex_buffer[j].stride) | + vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(vertex_buffer->stride) | S_038008_DATA_FORMAT(format); vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = 0x00000000; vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD4] = 0x00000000; @@ -132,7 +127,7 @@ static int r600_draw_common(struct r600_draw *draw) draw->draw->states[R600_DRAW__VGT_NUM_INDICES] = draw->count; draw->draw->states[R600_DRAW__VGT_DRAW_INITIATOR] = vgt_draw_initiator; if (draw->index_buffer) { - rbuffer = (struct r600_buffer*)draw->index_buffer; + rbuffer = (struct r600_resource*)draw->index_buffer; draw->draw->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); draw->draw->placement[0] = RADEON_GEM_DOMAIN_GTT; draw->draw->placement[1] = RADEON_GEM_DOMAIN_GTT; @@ -160,58 +155,39 @@ static int r600_draw_common(struct r600_draw *draw) return r; /* FIXME */ r = radeon_ctx_set_draw_new(rctx->ctx, rctx->draw); + if (r == -EBUSY) { + r600_flush(draw->ctx, 0, NULL); + r = radeon_ctx_set_draw_new(rctx->ctx, rctx->draw); + } if (r) return r; rctx->draw = radeon_draw_duplicate(rctx->draw); return 0; } -void r600_draw_range_elements(struct pipe_context *ctx, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, unsigned min_index, - unsigned max_index, unsigned mode, - unsigned start, unsigned count) +void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) { + struct r600_context *rctx = r600_context(ctx); struct r600_draw draw; - assert(index_bias == 0); - draw.ctx = ctx; - draw.mode = mode; - draw.start = start; - draw.count = count; - draw.index_size = index_size; - draw.index_buffer = index_buffer; -printf("index_size %d min %d max %d start %d count %d\n", index_size, min_index, max_index, start, count); - r600_draw_common(&draw); -} - -void r600_draw_elements(struct pipe_context *ctx, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, unsigned mode, - unsigned start, unsigned count) -{ - struct r600_draw draw; - assert(index_bias == 0); + assert(info->index_bias == 0); draw.ctx = ctx; - draw.mode = mode; - draw.start = start; - draw.count = count; - draw.index_size = index_size; - draw.index_buffer = index_buffer; - r600_draw_common(&draw); -} + draw.mode = info->mode; + draw.start = info->start; + draw.count = info->count; + if (info->indexed && rctx->index_buffer.buffer) { + draw.index_size = rctx->index_buffer.index_size; + draw.index_buffer = rctx->index_buffer.buffer; -void r600_draw_arrays(struct pipe_context *ctx, unsigned mode, - unsigned start, unsigned count) -{ - struct r600_draw draw; - - draw.ctx = ctx; - draw.mode = mode; - draw.start = start; - draw.count = count; - draw.index_size = 0; - draw.index_buffer = NULL; + assert(rctx->index_buffer.offset % + rctx->index_buffer.index_size == 0); + draw.start += rctx->index_buffer.offset / + rctx->index_buffer.index_size; + } + else { + draw.index_size = 0; + draw.index_buffer = NULL; + } r600_draw_common(&draw); } diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c index e3175b627aa..5e0e0aab570 100644 --- a/src/gallium/drivers/r600/r600_helper.c +++ b/src/gallium/drivers/r600/r600_helper.c @@ -27,95 +27,9 @@ #include <errno.h> #include <util/u_inlines.h> #include "r600_screen.h" +#include "r600_context.h" #include "r600d.h" -int r600_conv_pipe_format(unsigned pformat, unsigned *format) -{ - switch (pformat) { - case PIPE_FORMAT_R32G32B32_FLOAT: - *format = 0x30; - return 0; - case PIPE_FORMAT_R32G32B32A32_FLOAT: - *format = V_0280A0_COLOR_32_32_32_32_FLOAT; - return 0; - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_R8G8B8A8_UNORM: - case PIPE_FORMAT_R8G8B8X8_UNORM: - case PIPE_FORMAT_R8G8B8A8_USCALED: - case PIPE_FORMAT_R8G8B8A8_SNORM: - case PIPE_FORMAT_R8G8B8A8_SSCALED: - *format = V_0280A0_COLOR_8_8_8_8; - return 0; - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_I8_UNORM: - case PIPE_FORMAT_L16_UNORM: - case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_Z32_UNORM: - case PIPE_FORMAT_Z32_FLOAT: - case PIPE_FORMAT_R64_FLOAT: - case PIPE_FORMAT_R64G64_FLOAT: - case PIPE_FORMAT_R64G64B64_FLOAT: - case PIPE_FORMAT_R64G64B64A64_FLOAT: - case PIPE_FORMAT_R32_FLOAT: - case PIPE_FORMAT_R32G32_FLOAT: - case PIPE_FORMAT_R32_UNORM: - case PIPE_FORMAT_R32G32_UNORM: - case PIPE_FORMAT_R32G32B32_UNORM: - case PIPE_FORMAT_R32G32B32A32_UNORM: - case PIPE_FORMAT_R32_USCALED: - case PIPE_FORMAT_R32G32_USCALED: - case PIPE_FORMAT_R32G32B32_USCALED: - case PIPE_FORMAT_R32G32B32A32_USCALED: - case PIPE_FORMAT_R32_SNORM: - case PIPE_FORMAT_R32G32_SNORM: - case PIPE_FORMAT_R32G32B32_SNORM: - case PIPE_FORMAT_R32G32B32A32_SNORM: - case PIPE_FORMAT_R32_SSCALED: - case PIPE_FORMAT_R32G32_SSCALED: - case PIPE_FORMAT_R32G32B32_SSCALED: - case PIPE_FORMAT_R32G32B32A32_SSCALED: - case PIPE_FORMAT_R16_UNORM: - case PIPE_FORMAT_R16G16_UNORM: - case PIPE_FORMAT_R16G16B16_UNORM: - case PIPE_FORMAT_R16G16B16A16_UNORM: - case PIPE_FORMAT_R16_USCALED: - case PIPE_FORMAT_R16G16_USCALED: - case PIPE_FORMAT_R16G16B16_USCALED: - case PIPE_FORMAT_R16G16B16A16_USCALED: - case PIPE_FORMAT_R16_SNORM: - case PIPE_FORMAT_R16G16_SNORM: - case PIPE_FORMAT_R16G16B16_SNORM: - case PIPE_FORMAT_R16G16B16A16_SNORM: - case PIPE_FORMAT_R16_SSCALED: - case PIPE_FORMAT_R16G16_SSCALED: - case PIPE_FORMAT_R16G16B16_SSCALED: - case PIPE_FORMAT_R16G16B16A16_SSCALED: - case PIPE_FORMAT_R8_UNORM: - case PIPE_FORMAT_R8G8_UNORM: - case PIPE_FORMAT_R8G8B8_UNORM: - case PIPE_FORMAT_R8_USCALED: - case PIPE_FORMAT_R8G8_USCALED: - case PIPE_FORMAT_R8G8B8_USCALED: - case PIPE_FORMAT_R8_SNORM: - case PIPE_FORMAT_R8G8_SNORM: - case PIPE_FORMAT_R8G8B8_SNORM: - case PIPE_FORMAT_R8_SSCALED: - case PIPE_FORMAT_R8G8_SSCALED: - case PIPE_FORMAT_R8G8B8_SSCALED: - case PIPE_FORMAT_R32_FIXED: - case PIPE_FORMAT_R32G32_FIXED: - case PIPE_FORMAT_R32G32B32_FIXED: - case PIPE_FORMAT_R32G32B32A32_FIXED: - default: - fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pformat); - return -EINVAL; - } -} - int r600_conv_pipe_prim(unsigned pprim, unsigned *prim) { switch (pprim) { diff --git a/src/gallium/drivers/r600/r600_resource.c b/src/gallium/drivers/r600/r600_resource.c index d9aa1df04f0..8dc411ef409 100644 --- a/src/gallium/drivers/r600/r600_resource.c +++ b/src/gallium/drivers/r600/r600_resource.c @@ -24,45 +24,44 @@ #include "r600_context.h" #include "r600_resource.h" #include "r600_screen.h" -#include "r600_texture.h" -static struct pipe_resource * -r600_resource_create(struct pipe_screen *screen, - const struct pipe_resource *templ) +static struct pipe_resource *r600_resource_create(struct pipe_screen *screen, + const struct pipe_resource *templ) { - if (templ->target == PIPE_BUFFER) - return r600_buffer_create(screen, templ); - else - return r600_texture_create(screen, templ); + if (templ->target == PIPE_BUFFER) { + return r600_buffer_create(screen, templ); + } else { + return r600_texture_create(screen, templ); + } } -static struct pipe_resource * -r600_resource_from_handle(struct pipe_screen * screen, - const struct pipe_resource *templ, - struct winsys_handle *whandle) +static struct pipe_resource *r600_resource_from_handle(struct pipe_screen * screen, + const struct pipe_resource *templ, + struct winsys_handle *whandle) { - if (templ->target == PIPE_BUFFER) - return NULL; - else - return r600_texture_from_handle(screen, templ, whandle); + if (templ->target == PIPE_BUFFER) { + return NULL; + } else { + return r600_texture_from_handle(screen, templ, whandle); + } } void r600_init_context_resource_functions(struct r600_context *r600) { - r600->context.get_transfer = u_get_transfer_vtbl; - r600->context.transfer_map = u_transfer_map_vtbl; - r600->context.transfer_flush_region = u_transfer_flush_region_vtbl; - r600->context.transfer_unmap = u_transfer_unmap_vtbl; - r600->context.transfer_destroy = u_transfer_destroy_vtbl; - r600->context.transfer_inline_write = u_transfer_inline_write_vtbl; - r600->context.is_resource_referenced = u_is_resource_referenced_vtbl; + r600->context.get_transfer = u_get_transfer_vtbl; + r600->context.transfer_map = u_transfer_map_vtbl; + r600->context.transfer_flush_region = u_transfer_flush_region_vtbl; + r600->context.transfer_unmap = u_transfer_unmap_vtbl; + r600->context.transfer_destroy = u_transfer_destroy_vtbl; + r600->context.transfer_inline_write = u_transfer_inline_write_vtbl; + r600->context.is_resource_referenced = u_is_resource_referenced_vtbl; } void r600_init_screen_resource_functions(struct r600_screen *r600screen) { - r600screen->screen.resource_create = r600_resource_create; - r600screen->screen.resource_from_handle = r600_resource_from_handle; - r600screen->screen.resource_get_handle = u_resource_get_handle_vtbl; - r600screen->screen.resource_destroy = u_resource_destroy_vtbl; - r600screen->screen.user_buffer_create = r600_user_buffer_create; + r600screen->screen.resource_create = r600_resource_create; + r600screen->screen.resource_from_handle = r600_resource_from_handle; + r600screen->screen.resource_get_handle = u_resource_get_handle_vtbl; + r600screen->screen.resource_destroy = u_resource_destroy_vtbl; + r600screen->screen.user_buffer_create = r600_user_buffer_create; } diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index 95084a371bd..bb90e76fb78 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -20,14 +20,47 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #ifndef R600_RESOURCE_H #define R600_RESOURCE_H +#include "util/u_transfer.h" + struct r600_context; struct r600_screen; +/* This gets further specialized into either buffer or texture + * structures. Use the vtbl struct to choose between the two + * underlying implementations. + */ +struct r600_resource { + struct u_resource base; + struct radeon_bo *bo; + u32 domain; + u32 flink; + struct pb_buffer *pb; +}; + +struct r600_resource_texture { + struct r600_resource resource; + unsigned long offset[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long layer_size[PIPE_MAX_TEXTURE_LEVELS]; + unsigned long pitch_override; + unsigned long bpt; + unsigned long size; +}; + void r600_init_context_resource_functions(struct r600_context *r600); void r600_init_screen_resource_functions(struct r600_screen *r600screen); +/* r600_buffer */ +u32 r600_domain_from_usage(unsigned usage); + +/* r600_texture */ +struct pipe_resource *r600_texture_create(struct pipe_screen *screen, + const struct pipe_resource *templ); +struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, + const struct pipe_resource *base, + struct winsys_handle *whandle); + #endif diff --git a/src/gallium/drivers/r600/r600_screen.c b/src/gallium/drivers/r600/r600_screen.c index dec6fa8d272..cdaca9ed7db 100644 --- a/src/gallium/drivers/r600/r600_screen.c +++ b/src/gallium/drivers/r600/r600_screen.c @@ -24,15 +24,15 @@ * Jerome Glisse * Corbin Simpson */ -#include <util/u_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> -#include "r600_resource.h" +#include <stdio.h> +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_memory.h" #include "r600_screen.h" -#include "r600_texture.h" #include "r600_context.h" #include "r600_public.h" -#include <stdio.h> +#include "r600_resource.h" +#include "r600_state_inlines.h" static const char* r600_get_vendor(struct pipe_screen* pscreen) { @@ -53,61 +53,102 @@ static const char* r600_get_name(struct pipe_screen* pscreen) static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) { switch (param) { - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - case PIPE_CAP_MAX_COMBINED_SAMPLERS: - return 16; + /* Supported features (boolean caps). */ case PIPE_CAP_NPOT_TEXTURES: - return 1; case PIPE_CAP_TWO_SIDED_STENCIL: - return 1; case PIPE_CAP_GLSL: - return 1; case PIPE_CAP_DUAL_SOURCE_BLEND: - return 1; case PIPE_CAP_ANISOTROPIC_FILTER: - return 1; case PIPE_CAP_POINT_SPRITE: - return 1; - case PIPE_CAP_MAX_RENDER_TARGETS: - /* FIXME some r6xx are buggy and can only do 4 */ - return 8; case PIPE_CAP_OCCLUSION_QUERY: - return 1; case PIPE_CAP_TEXTURE_SHADOW_MAP: - return 1; - case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - /* FIXME not sure here */ - return 13; case PIPE_CAP_TEXTURE_MIRROR_CLAMP: - return 1; case PIPE_CAP_TEXTURE_MIRROR_REPEAT: - return 1; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - /* FIXME allow this once infrastructure is there */ - return 0; - case PIPE_CAP_TGSI_CONT_SUPPORTED: - return 0; case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 1; case PIPE_CAP_SM3: - return 1; + case PIPE_CAP_TEXTURE_SWIZZLE: case PIPE_CAP_INDEP_BLEND_ENABLE: - return 1; - case PIPE_CAP_INDEP_BLEND_FUNC: - /* FIXME allow this */ - return 0; case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: return 1; + + /* Unsupported features (boolean caps). */ + case PIPE_CAP_TIMER_QUERY: + case PIPE_CAP_TGSI_CONT_SUPPORTED: + case PIPE_CAP_STREAM_OUTPUT: + case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ + case PIPE_CAP_GEOMETRY_SHADER4: + case PIPE_CAP_DEPTH_CLAMP: /* FIXME allow this */ + return 0; + + /* Texturing. */ + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: + return 14; + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + /* FIXME allow this once infrastructure is there */ + return 0; + case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return 16; + + /* Render targets. */ + case PIPE_CAP_MAX_RENDER_TARGETS: + /* FIXME some r6xx are buggy and can only do 4 */ + return 8; + + /* Fragment coordinate conventions. */ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 1; case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: return 0; + + /* Shader limits. */ + case PIPE_CAP_MAX_VS_INSTRUCTIONS: + return 16384; //max native instructions, not greater than max instructions + case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS: + case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS: + return 16384; + case PIPE_CAP_MAX_FS_INSTRUCTIONS: + return 16384; //max program native instructions + case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS: + return 16384; //max program native ALU instructions + case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS: + return 16384; //max program native texture instructions + case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: + return 2048; //max program native texture indirections + case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH: + case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: + return 8; /* FIXME */ + case PIPE_CAP_MAX_VS_INPUTS: + return 16; //max native attributes + case PIPE_CAP_MAX_FS_INPUTS: + return 10; //max native attributes + case PIPE_CAP_MAX_VS_TEMPS: + return 256; //max native temporaries + case PIPE_CAP_MAX_FS_TEMPS: + return 256; //max native temporaries + case PIPE_CAP_MAX_VS_ADDRS: + case PIPE_CAP_MAX_FS_ADDRS: + return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */ + case PIPE_CAP_MAX_VS_CONSTS: + return 256; //max native parameters + case PIPE_CAP_MAX_FS_CONSTS: + return 256; //max program native parameters + case PIPE_CAP_MAX_CONST_BUFFERS: + return 1; + case PIPE_CAP_MAX_CONST_BUFFER_SIZE: /* in bytes */ + return 4096; + case PIPE_CAP_MAX_PREDICATE_REGISTERS: + case PIPE_CAP_MAX_VS_PREDS: + case PIPE_CAP_MAX_FS_PREDS: + return 0; /* FIXME */ + default: - debug_printf("r600: unknown param %d\n", param); + R600_ERR("r600: unknown param %d\n", param); return 0; } } @@ -125,7 +166,7 @@ static float r600_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 16.0f; default: - debug_printf("r600: unsupported paramf %d\n", param); + R600_ERR("r600: unsupported paramf %d\n", param); return 0.0f; } } @@ -134,108 +175,51 @@ static boolean r600_is_format_supported(struct pipe_screen* screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned bindings, + unsigned usage, unsigned geom_flags) { + unsigned retval = 0; if (target >= PIPE_MAX_TEXTURE_TYPES) { - debug_printf("r600: unsupported texture type %d\n", target); + R600_ERR("r600: unsupported texture type %d\n", target); return FALSE; } - switch (format) { - case PIPE_FORMAT_B4G4R4A4_UNORM: - case PIPE_FORMAT_B5G6R5_UNORM: - case PIPE_FORMAT_B5G5R5A1_UNORM: - case PIPE_FORMAT_A8_UNORM: - case PIPE_FORMAT_L8_UNORM: - case PIPE_FORMAT_A8R8G8B8_SRGB: - case PIPE_FORMAT_R8G8B8A8_SRGB: - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT5_RGBA: - case PIPE_FORMAT_UYVY: - case PIPE_FORMAT_L8_SRGB: - case PIPE_FORMAT_L8A8_SRGB: - case PIPE_FORMAT_L8A8_UNORM: - case PIPE_FORMAT_A8R8G8B8_UNORM: - case PIPE_FORMAT_X8R8G8B8_UNORM: - case PIPE_FORMAT_R8G8B8A8_UNORM: - case PIPE_FORMAT_R8G8B8X8_UNORM: - case PIPE_FORMAT_B8G8R8A8_UNORM: - case PIPE_FORMAT_B8G8R8X8_UNORM: - case PIPE_FORMAT_A8B8G8R8_SRGB: - case PIPE_FORMAT_B8G8R8A8_SRGB: - case PIPE_FORMAT_I8_UNORM: - case PIPE_FORMAT_Z16_UNORM: - case PIPE_FORMAT_X8Z24_UNORM: - case PIPE_FORMAT_S8_USCALED_Z24_UNORM: - case PIPE_FORMAT_Z32_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: - case PIPE_FORMAT_Z24X8_UNORM: - return TRUE; - default: - /* Unknown format... */ - break; - } - return FALSE; -} - -struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, - struct pipe_resource *texture, - struct pipe_subresource sr, - unsigned usage, - const struct pipe_box *box) -{ - struct r600_texture *rtex = (struct r600_texture*)texture; - struct r600_transfer *trans; - trans = CALLOC_STRUCT(r600_transfer); - if (trans == NULL) - return NULL; - pipe_resource_reference(&trans->transfer.resource, texture); - trans->transfer.sr = sr; - trans->transfer.usage = usage; - trans->transfer.box = *box; - trans->transfer.stride = rtex->stride[sr.level]; - trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face); - return &trans->transfer; -} - -void r600_texture_transfer_destroy(struct pipe_context *ctx, - struct pipe_transfer *trans) -{ - pipe_resource_reference(&trans->resource, NULL); - FREE(trans); -} + /* Multisample */ + if (sample_count > 1) + return FALSE; -void* r600_texture_transfer_map(struct pipe_context *ctx, - struct pipe_transfer* transfer) -{ - struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct r600_texture *rtex = (struct r600_texture*)transfer->resource; - char *map; - enum pipe_format format = rtex->b.b.format; + if ((usage & PIPE_BIND_SAMPLER_VIEW) && + r600_is_sampler_format_supported(format)) { + retval |= PIPE_BIND_SAMPLER_VIEW; + } - map = pipe_buffer_map(ctx, rtex->buffer, - transfer->usage, - &rtransfer->buffer_transfer); + if ((usage & (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED)) && + r600_is_colorbuffer_format_supported(format)) { + retval |= usage & + (PIPE_BIND_RENDER_TARGET | + PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_SCANOUT | + PIPE_BIND_SHARED); + } - if (!map) { - return NULL; + if ((usage & PIPE_BIND_DEPTH_STENCIL) && + r600_is_zs_format_supported(format)) { + retval |= PIPE_BIND_DEPTH_STENCIL; } - return map + rtransfer->offset + - transfer->box.y / util_format_get_blockheight(format) * transfer->stride + - transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); -} + if ((usage & PIPE_BIND_VERTEX_BUFFER) && + r600_is_vertex_format_supported(format)) + retval |= PIPE_BIND_VERTEX_BUFFER; -void r600_texture_transfer_unmap(struct pipe_context *ctx, - struct pipe_transfer* transfer) -{ - struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct r600_texture *rtex = (struct r600_texture*)transfer->resource; + if (usage & PIPE_BIND_TRANSFER_READ) + retval |= PIPE_BIND_TRANSFER_READ; + if (usage & PIPE_BIND_TRANSFER_WRITE) + retval |= PIPE_BIND_TRANSFER_WRITE; - pipe_buffer_unmap(ctx, rtex->buffer, rtransfer->buffer_transfer); + return retval == usage; } static void r600_destroy_screen(struct pipe_screen* pscreen) diff --git a/src/gallium/drivers/r600/r600_screen.h b/src/gallium/drivers/r600/r600_screen.h index 0a0286d96bc..53b560c617f 100644 --- a/src/gallium/drivers/r600/r600_screen.h +++ b/src/gallium/drivers/r600/r600_screen.h @@ -40,14 +40,6 @@ struct r600_transfer { unsigned offset; }; -struct r600_buffer { - struct u_resource b; - struct radeon_bo *bo; - u32 domain; - u32 flink; - struct pb_buffer *pb; -}; - struct r600_screen { struct pipe_screen screen; struct radeon *rw; @@ -88,17 +80,6 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, int r600_conv_pipe_format(unsigned pformat, unsigned *format); int r600_conv_pipe_prim(unsigned pprim, unsigned *prim); -union r600_float_to_u32_u { - u32 u; - float f; -}; - -static inline u32 r600_float_to_u32(float f) -{ - union r600_float_to_u32_u c; - - c.f = f; - return c.u; -} +void r600_init_screen_texture_functions(struct pipe_screen *screen); #endif diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index f7d6e106638..956c7e7930c 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -19,78 +19,190 @@ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jerome Glisse */ -#include <stdio.h> -#include <errno.h> -#include <util/u_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> -#include <tgsi/tgsi_dump.h> +#include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_scan.h" +#include "tgsi/tgsi_dump.h" +#include "util/u_format.h" #include "r600_screen.h" #include "r600_context.h" +#include "r600_shader.h" +#include "r600_asm.h" +#include "r600_sq.h" #include "r600d.h" +#include <stdio.h> +#include <errno.h> + + +struct r600_shader_tgsi_instruction; + +struct r600_shader_ctx { + struct tgsi_shader_info info; + struct tgsi_parse_context parse; + const struct tgsi_token *tokens; + unsigned type; + unsigned file_offset[TGSI_FILE_COUNT]; + unsigned temp_reg; + struct r600_shader_tgsi_instruction *inst_info; + struct r600_bc *bc; + struct r600_shader *shader; + u32 value[4]; +}; + +struct r600_shader_tgsi_instruction { + unsigned tgsi_opcode; + unsigned is_op3; + unsigned r600_opcode; + int (*process)(struct r600_shader_ctx *ctx); +}; + +static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[]; +static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader); + +static int r600_shader_update(struct pipe_context *ctx, struct r600_shader *shader) +{ + struct r600_context *rctx = r600_context(ctx); + const struct util_format_description *desc; + enum pipe_format resource_format[160]; + unsigned i, nresources = 0; + struct r600_bc *bc = &shader->bc; + struct r600_bc_cf *cf; + struct r600_bc_vtx *vtx; + + if (shader->processor_type != TGSI_PROCESSOR_VERTEX) + return 0; + for (i = 0; i < rctx->vertex_elements->count; i++) { + resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format; + } + LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { + switch (cf->inst) { + case V_SQ_CF_WORD1_SQ_CF_INST_VTX: + case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC: + LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) { + desc = util_format_description(resource_format[vtx->buffer_id]); + if (desc == NULL) { + R600_ERR("unknown format %d\n", resource_format[vtx->buffer_id]); + return -EINVAL; + } + vtx->dst_sel_x = desc->swizzle[0]; + vtx->dst_sel_y = desc->swizzle[1]; + vtx->dst_sel_z = desc->swizzle[2]; + vtx->dst_sel_w = desc->swizzle[3]; + } + break; + default: + break; + } + } + return r600_bc_build(&shader->bc); +} + +int r600_pipe_shader_create(struct pipe_context *ctx, + struct r600_context_state *rpshader, + const struct tgsi_token *tokens) +{ + struct r600_screen *rscreen = r600_screen(ctx->screen); + int r; + +fprintf(stderr, "--------------------------------------------------------------\n"); +tgsi_dump(tokens, 0); + if (rpshader == NULL) + return -ENOMEM; + rpshader->shader.family = radeon_get_family(rscreen->rw); + r = r600_shader_from_tgsi(tokens, &rpshader->shader); + if (r) { + R600_ERR("translation from TGSI failed !\n"); + return r; + } + r = r600_bc_build(&rpshader->shader.bc); + if (r) { + R600_ERR("building bytecode failed !\n"); + return r; + } +fprintf(stderr, "______________________________________________________________\n"); + return 0; +} -static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_context_state *rpshader) { struct r600_screen *rscreen = r600_screen(ctx->screen); struct r600_shader *rshader = &rpshader->shader; struct radeon_state *state; unsigned i, tmp; - rpshader->state = radeon_state_decref(rpshader->state); + rpshader->rstate = radeon_state_decref(rpshader->rstate); state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER); if (state == NULL) return -ENOMEM; - for (i = 0; i < rshader->noutput; i += 4) { - tmp = rshader->output[i].sid; - tmp |= rshader->output[i + 1].sid << 8; - tmp |= rshader->output[i + 2].sid << 16; - tmp |= rshader->output[i + 3].sid << 24; - state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] = tmp; - } - state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 1); - state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->ngpr); - rpshader->state = state; - rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); - rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo); - rpshader->state->nbo = 2; - rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT; + for (i = 0; i < 10; i++) { + state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i] = 0; + } + /* so far never got proper semantic id from tgsi */ + for (i = 0; i < 32; i++) { + tmp = i << ((i & 3) * 8); + state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] |= tmp; + } + state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2); + state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->bc.ngpr); + rpshader->rstate = state; + rpshader->rstate->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); + rpshader->rstate->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo); + rpshader->rstate->nbo = 2; + rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT; return radeon_state_pm4(state); } -static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_context_state *rpshader) { + const struct pipe_rasterizer_state *rasterizer; struct r600_screen *rscreen = r600_screen(ctx->screen); struct r600_shader *rshader = &rpshader->shader; + struct r600_context *rctx = r600_context(ctx); struct radeon_state *state; - unsigned i, tmp; + unsigned i, tmp, exports_ps, num_cout; - rpshader->state = radeon_state_decref(rpshader->state); + rasterizer = &rctx->rasterizer->state.rasterizer; + rpshader->rstate = radeon_state_decref(rpshader->rstate); state = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER); if (state == NULL) return -ENOMEM; for (i = 0; i < rshader->ninput; i++) { - tmp = S_028644_SEMANTIC(rshader->input[i].sid); + tmp = S_028644_SEMANTIC(i); tmp |= S_028644_SEL_CENTROID(1); - tmp |= S_028644_FLAT_SHADE(rshader->flat_shade); + if (rshader->input[i].name == TGSI_SEMANTIC_COLOR || + rshader->input[i].name == TGSI_SEMANTIC_BCOLOR) { + tmp |= S_028644_FLAT_SHADE(rshader->flat_shade); + } + if (rasterizer->sprite_coord_enable & (1 << i)) { + tmp |= S_028644_PT_SPRITE_TEX(1); + } state->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0 + i] = tmp; } + + exports_ps = 0; + num_cout = 0; + for (i = 0; i < rshader->noutput; i++) { + if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) + exports_ps |= 1; + else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) { + exports_ps |= (1 << (num_cout+1)); + num_cout++; + } + } state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) | S_0286CC_PERSP_GRADIENT_ENA(1); state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000; - state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->ngpr); - state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002; - rpshader->state = state; - rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); - rpshader->state->nbo = 1; - rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT; + state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->bc.ngpr); + state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = exports_ps; + rpshader->rstate = state; + rpshader->rstate->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo); + rpshader->rstate->nbo = 1; + rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT; return radeon_state_pm4(state); } -static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +static int r600_pipe_shader(struct pipe_context *ctx, struct r600_context_state *rpshader) { struct r600_screen *rscreen = r600_screen(ctx->screen); struct r600_context *rctx = r600_context(ctx); @@ -100,21 +212,21 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r /* copy new shader */ radeon_bo_decref(rscreen->rw, rpshader->bo); rpshader->bo = NULL; - rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->ndw * 4, + rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->bc.ndw * 4, 4096, NULL); if (rpshader->bo == NULL) { return -ENOMEM; } radeon_bo_map(rscreen->rw, rpshader->bo); - memcpy(rpshader->bo->data, rshader->bcode, rshader->ndw * 4); + memcpy(rpshader->bo->data, rshader->bc.bytecode, rshader->bc.ndw * 4); radeon_bo_unmap(rscreen->rw, rpshader->bo); /* build state */ rshader->flat_shade = rctx->flat_shade; - switch (rpshader->type) { - case C_PROGRAM_TYPE_VS: + switch (rshader->processor_type) { + case TGSI_PROCESSOR_VERTEX: r = r600_pipe_shader_vs(ctx, rpshader); break; - case C_PROGRAM_TYPE_FS: + case TGSI_PROCESSOR_FRAGMENT: r = r600_pipe_shader_ps(ctx, rpshader); break; default: @@ -124,104 +236,1129 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r return r; } -struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens) +int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_context_state *rpshader) { - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader); - struct r600_shader *rshader = &rpshader->shader; + struct r600_context *rctx = r600_context(ctx); int r; - enum radeon_family family; if (rpshader == NULL) - return NULL; - rpshader->type = type; - family = radeon_get_family(rscreen->rw); - rshader->r6xx_compile = (family >= CHIP_R600 && family < CHIP_RV770); - LIST_INITHEAD(&rshader->nodes); - fprintf(stderr, "<< %s\n", rshader->r6xx_compile ? "R600" : "R700"); - tgsi_dump(tokens, 0); - fprintf(stderr, "--------------------------------------------------------------\n"); - r = c_shader_from_tgsi(&rshader->cshader, type, tokens); - if (r) { - r600_pipe_shader_destroy(ctx, rpshader); - fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); - return NULL; + return -EINVAL; + /* there should be enough input */ + if (rctx->vertex_elements->count < rpshader->shader.bc.nresource) { + R600_ERR("%d resources provided, expecting %d\n", + rctx->vertex_elements->count, rpshader->shader.bc.nresource); + return -EINVAL; } - r = r600_shader_insert_fetch(&rshader->cshader); - if (r) { - r600_pipe_shader_destroy(ctx, rpshader); - fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); - return NULL; + r = r600_shader_update(ctx, &rpshader->shader); + if (r) + return r; + return r600_pipe_shader(ctx, rpshader); +} + +static int tgsi_is_supported(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *i = &ctx->parse.FullToken.FullInstruction; + int j; + + if (i->Instruction.NumDstRegs > 1) { + R600_ERR("too many dst (%d)\n", i->Instruction.NumDstRegs); + return -EINVAL; } - r = c_shader_build_dominator_tree(&rshader->cshader); - if (r) { - r600_pipe_shader_destroy(ctx, rpshader); - fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); - return NULL; + if (i->Instruction.Predicate) { + R600_ERR("predicate unsupported\n"); + return -EINVAL; } - r = r600_cshader_legalize(&rshader->cshader); - if (r) { - r600_pipe_shader_destroy(ctx, rpshader); - fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); - return NULL; + if (i->Instruction.Label) { + R600_ERR("label unsupported\n"); + return -EINVAL; } - c_shader_dump(&rshader->cshader); - r = r700_shader_translate(rshader); - if (r) { - r600_pipe_shader_destroy(ctx, rpshader); - fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__); - return NULL; + for (j = 0; j < i->Instruction.NumSrcRegs; j++) { + if (i->Src[j].Register.Indirect || + i->Src[j].Register.Dimension || + i->Src[j].Register.Absolute) { + R600_ERR("unsupported src (indirect|dimension|absolute)\n"); + return -EINVAL; + } } -#if 1 -#if 0 - fprintf(stderr, "--------------------------------------------------------------\n"); - for (int i = 0; i < rshader->ndw; i++) { - fprintf(stderr, "0x%08X\n", rshader->bcode[i]); + for (j = 0; j < i->Instruction.NumDstRegs; j++) { + if (i->Dst[j].Register.Indirect || i->Dst[j].Register.Dimension) { + R600_ERR("unsupported dst (indirect|dimension)\n"); + return -EINVAL; + } } -#endif - fprintf(stderr, ">>\n\n"); -#endif - return rpshader; + return 0; } -void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +static int tgsi_declaration(struct r600_shader_ctx *ctx) { - struct r600_screen *rscreen = r600_screen(ctx->screen); + struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration; + struct r600_bc_vtx vtx; + unsigned i; + int r; - if (rpshader == NULL) - return; - radeon_bo_decref(rscreen->rw, rpshader->bo); - rpshader->bo = NULL; - r600_shader_cleanup(&rpshader->shader); - FREE(rpshader); + switch (d->Declaration.File) { + case TGSI_FILE_INPUT: + i = ctx->shader->ninput++; + ctx->shader->input[i].name = d->Semantic.Name; + ctx->shader->input[i].sid = d->Semantic.Index; + ctx->shader->input[i].interpolate = d->Declaration.Interpolate; + ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + i; + if (ctx->type == TGSI_PROCESSOR_VERTEX) { + /* turn input into fetch */ + memset(&vtx, 0, sizeof(struct r600_bc_vtx)); + vtx.inst = 0; + vtx.fetch_type = 0; + vtx.buffer_id = i; + /* register containing the index into the buffer */ + vtx.src_gpr = 0; + vtx.src_sel_x = 0; + vtx.mega_fetch_count = 0x1F; + vtx.dst_gpr = ctx->shader->input[i].gpr; + vtx.dst_sel_x = 0; + vtx.dst_sel_y = 1; + vtx.dst_sel_z = 2; + vtx.dst_sel_w = 3; + r = r600_bc_add_vtx(ctx->bc, &vtx); + if (r) + return r; + } + break; + case TGSI_FILE_OUTPUT: + i = ctx->shader->noutput++; + ctx->shader->output[i].name = d->Semantic.Name; + ctx->shader->output[i].sid = d->Semantic.Index; + ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + i; + ctx->shader->output[i].interpolate = d->Declaration.Interpolate; + break; + case TGSI_FILE_CONSTANT: + case TGSI_FILE_TEMPORARY: + case TGSI_FILE_SAMPLER: + break; + default: + R600_ERR("unsupported file %d declaration\n", d->Declaration.File); + return -EINVAL; + } + return 0; } -int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader) +int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader) { - struct r600_context *rctx = r600_context(ctx); - struct r600_shader *rshader; - enum pipe_format resource_format[160]; - unsigned i, nresources = 0; - int r; + struct tgsi_full_immediate *immediate; + struct r600_shader_ctx ctx; + struct r600_bc_output output[32]; + unsigned output_done, noutput; + unsigned opcode; + int i, r = 0, pos0; - if (rpshader == NULL) - return -EINVAL; - rshader = &rpshader->shader; - switch (rpshader->type) { - case C_PROGRAM_TYPE_VS: - for (i = 0; i < rctx->vertex_elements->count; i++) { - resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format; + ctx.bc = &shader->bc; + ctx.shader = shader; + r = r600_bc_init(ctx.bc, shader->family); + if (r) + return r; + ctx.tokens = tokens; + tgsi_scan_shader(tokens, &ctx.info); + tgsi_parse_init(&ctx.parse, tokens); + ctx.type = ctx.parse.FullHeader.Processor.Processor; + shader->processor_type = ctx.type; + + /* register allocations */ + /* Values [0,127] correspond to GPR[0..127]. + * Values [256,511] correspond to cfile constants c[0..255]. + * Other special values are shown in the list below. + * 248 SQ_ALU_SRC_0: special constant 0.0. + * 249 SQ_ALU_SRC_1: special constant 1.0 float. + * 250 SQ_ALU_SRC_1_INT: special constant 1 integer. + * 251 SQ_ALU_SRC_M_1_INT: special constant -1 integer. + * 252 SQ_ALU_SRC_0_5: special constant 0.5 float. + * 253 SQ_ALU_SRC_LITERAL: literal constant. + * 254 SQ_ALU_SRC_PV: previous vector result. + * 255 SQ_ALU_SRC_PS: previous scalar result. + */ + for (i = 0; i < TGSI_FILE_COUNT; i++) { + ctx.file_offset[i] = 0; + } + if (ctx.type == TGSI_PROCESSOR_VERTEX) { + ctx.file_offset[TGSI_FILE_INPUT] = 1; + } + ctx.file_offset[TGSI_FILE_OUTPUT] = ctx.file_offset[TGSI_FILE_INPUT] + + ctx.info.file_count[TGSI_FILE_INPUT]; + ctx.file_offset[TGSI_FILE_TEMPORARY] = ctx.file_offset[TGSI_FILE_OUTPUT] + + ctx.info.file_count[TGSI_FILE_OUTPUT]; + ctx.file_offset[TGSI_FILE_CONSTANT] = 256; + ctx.file_offset[TGSI_FILE_IMMEDIATE] = 253; + ctx.temp_reg = ctx.file_offset[TGSI_FILE_TEMPORARY] + + ctx.info.file_count[TGSI_FILE_TEMPORARY]; + + while (!tgsi_parse_end_of_tokens(&ctx.parse)) { + tgsi_parse_token(&ctx.parse); + switch (ctx.parse.FullToken.Token.Type) { + case TGSI_TOKEN_TYPE_IMMEDIATE: + immediate = &ctx.parse.FullToken.FullImmediate; + ctx.value[0] = immediate->u[0].Uint; + ctx.value[1] = immediate->u[1].Uint; + ctx.value[2] = immediate->u[2].Uint; + ctx.value[3] = immediate->u[3].Uint; + break; + case TGSI_TOKEN_TYPE_DECLARATION: + r = tgsi_declaration(&ctx); + if (r) + goto out_err; + break; + case TGSI_TOKEN_TYPE_INSTRUCTION: + r = tgsi_is_supported(&ctx); + if (r) + goto out_err; + opcode = ctx.parse.FullToken.FullInstruction.Instruction.Opcode; + ctx.inst_info = &r600_shader_tgsi_instruction[opcode]; + r = ctx.inst_info->process(&ctx); + if (r) + goto out_err; + r = r600_bc_add_literal(ctx.bc, ctx.value); + if (r) + goto out_err; + break; + default: + R600_ERR("unsupported token type %d\n", ctx.parse.FullToken.Token.Type); + r = -EINVAL; + goto out_err; } - break; + } + /* export output */ + noutput = shader->noutput; + for (i = 0, pos0 = 0; i < noutput; i++) { + memset(&output[i], 0, sizeof(struct r600_bc_output)); + output[i].gpr = shader->output[i].gpr; + output[i].elem_size = 3; + output[i].swizzle_x = 0; + output[i].swizzle_y = 1; + output[i].swizzle_z = 2; + output[i].swizzle_w = 3; + output[i].barrier = 1; + output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM; + output[i].array_base = i - pos0; + output[i].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT; + switch (ctx.type) { + case TGSI_PROCESSOR_VERTEX: + if (shader->output[i].name == TGSI_SEMANTIC_POSITION) { + output[i].array_base = 60; + output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; + /* position doesn't count in array_base */ + pos0++; + } + if (shader->output[i].name == TGSI_SEMANTIC_PSIZE) { + output[i].array_base = 61; + output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS; + /* position doesn't count in array_base */ + pos0++; + } + break; + case TGSI_PROCESSOR_FRAGMENT: + if (shader->output[i].name == TGSI_SEMANTIC_COLOR) { + output[i].array_base = shader->output[i].sid; + output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + } else if (shader->output[i].name == TGSI_SEMANTIC_POSITION) { + output[i].array_base = 61; + output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL; + } else { + R600_ERR("unsupported fragment output name %d\n", shader->output[i].name); + r = -EINVAL; + goto out_err; + } + break; + default: + R600_ERR("unsupported processor type %d\n", ctx.type); + r = -EINVAL; + goto out_err; + } + } + /* add fake param output for vertex shader if no param is exported */ + if (ctx.type == TGSI_PROCESSOR_VERTEX) { + for (i = 0, pos0 = 0; i < noutput; i++) { + if (output[i].type == V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM) { + pos0 = 1; + break; + } + } + if (!pos0) { + memset(&output[i], 0, sizeof(struct r600_bc_output)); + output[i].gpr = 0; + output[i].elem_size = 3; + output[i].swizzle_x = 0; + output[i].swizzle_y = 1; + output[i].swizzle_z = 2; + output[i].swizzle_w = 3; + output[i].barrier = 1; + output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM; + output[i].array_base = 0; + output[i].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT; + noutput++; + } + } + /* add fake pixel export */ + if (ctx.type == TGSI_PROCESSOR_FRAGMENT && !noutput) { + memset(&output[0], 0, sizeof(struct r600_bc_output)); + output[0].gpr = 0; + output[0].elem_size = 3; + output[0].swizzle_x = 7; + output[0].swizzle_y = 7; + output[0].swizzle_z = 7; + output[0].swizzle_w = 7; + output[0].barrier = 1; + output[0].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM; + output[0].array_base = 0; + output[0].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT; + noutput++; + } + /* set export done on last export of each type */ + for (i = noutput - 1, output_done = 0; i >= 0; i--) { + if (i == (noutput - 1)) { + output[i].end_of_program = 1; + } + if (!(output_done & (1 << output[i].type))) { + output_done |= (1 << output[i].type); + output[i].inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE; + } + } + /* add output to bytecode */ + for (i = 0; i < noutput; i++) { + r = r600_bc_add_output(ctx.bc, &output[i]); + if (r) + goto out_err; + } + tgsi_parse_free(&ctx.parse); + return 0; +out_err: + tgsi_parse_free(&ctx.parse); + return r; +} + +static int tgsi_unsupported(struct r600_shader_ctx *ctx) +{ + R600_ERR("%d tgsi opcode unsupported\n", ctx->inst_info->tgsi_opcode); + return -EINVAL; +} + +static int tgsi_end(struct r600_shader_ctx *ctx) +{ + return 0; +} + +static int tgsi_src(struct r600_shader_ctx *ctx, + const struct tgsi_full_src_register *tgsi_src, + struct r600_bc_alu_src *r600_src) +{ + memset(r600_src, 0, sizeof(struct r600_bc_alu_src)); + r600_src->sel = tgsi_src->Register.Index; + if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) { + r600_src->sel = 0; + } + r600_src->neg = tgsi_src->Register.Negate; + r600_src->sel += ctx->file_offset[tgsi_src->Register.File]; + return 0; +} + +static int tgsi_dst(struct r600_shader_ctx *ctx, + const struct tgsi_full_dst_register *tgsi_dst, + unsigned swizzle, + struct r600_bc_alu_dst *r600_dst) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + + r600_dst->sel = tgsi_dst->Register.Index; + r600_dst->sel += ctx->file_offset[tgsi_dst->Register.File]; + r600_dst->chan = swizzle; + r600_dst->write = 1; + if (inst->Instruction.Saturate) { + r600_dst->clamp = 1; + } + return 0; +} + +static unsigned tgsi_chan(const struct tgsi_full_src_register *tgsi_src, unsigned swizzle) +{ + switch (swizzle) { + case 0: + return tgsi_src->Register.SwizzleX; + case 1: + return tgsi_src->Register.SwizzleY; + case 2: + return tgsi_src->Register.SwizzleZ; + case 3: + return tgsi_src->Register.SwizzleW; default: - break; + return 0; } - /* there should be enough input */ - if (nresources < rshader->nresource) - return -EINVAL; - /* FIXME compare resources */ - r = r600_shader_update(rshader, resource_format); +} + +static int tgsi_split_constant(struct r600_shader_ctx *ctx, struct r600_bc_alu_src r600_src[3]) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int i, j, k, nconst, r; + + for (i = 0, nconst = 0; i < inst->Instruction.NumSrcRegs; i++) { + if (inst->Src[i].Register.File == TGSI_FILE_CONSTANT) { + nconst++; + } + r = tgsi_src(ctx, &inst->Src[i], &r600_src[i]); + if (r) { + return r; + } + } + for (i = 0, j = nconst - 1; i < inst->Instruction.NumSrcRegs; i++) { + if (inst->Src[j].Register.File == TGSI_FILE_CONSTANT && j > 0) { + for (k = 0; k < 4; k++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.src[0].sel = r600_src[0].sel; + alu.src[0].chan = k; + alu.dst.sel = ctx->temp_reg + j; + alu.dst.chan = k; + alu.dst.write = 1; + if (k == 3) + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + r600_src[0].sel = ctx->temp_reg + j; + j--; + } + } + return 0; +} + +static int tgsi_op2(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu_src r600_src[3]; + struct r600_bc_alu alu; + int i, j, r; + + r = tgsi_split_constant(ctx, r600_src); if (r) return r; - return r600_pipe_shader(ctx, rpshader); + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + if (!(inst->Dst[0].Register.WriteMask & (1 << i))) { + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + alu.dst.chan = i; + } else { + alu.inst = ctx->inst_info->r600_opcode; + for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { + alu.src[j] = r600_src[j]; + alu.src[j].chan = tgsi_chan(&inst->Src[j], i); + } + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; + } + /* handle some special cases */ + switch (ctx->inst_info->tgsi_opcode) { + case TGSI_OPCODE_SUB: + alu.src[1].neg = 1; + break; + case TGSI_OPCODE_ABS: + alu.src[0].abs = 1; + break; + default: + break; + } + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; +} + +static int tgsi_kill(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int i, r; + + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = ctx->inst_info->r600_opcode; + alu.dst.chan = i; + alu.src[0].sel = 248; + r = tgsi_src(ctx, &inst->Src[0], &alu.src[1]); + if (r) + return r; + alu.src[1].chan = tgsi_chan(&inst->Src[0], i); + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; +} + +static int tgsi_slt(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu_src r600_src[3]; + struct r600_bc_alu alu; + int i, r; + + r = tgsi_split_constant(ctx, r600_src); + if (r) + return r; + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + if (!(inst->Dst[0].Register.WriteMask & (1 << i))) { + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + alu.dst.chan = i; + } else { + alu.inst = ctx->inst_info->r600_opcode; + alu.src[1] = r600_src[0]; + alu.src[1].chan = tgsi_chan(&inst->Src[0], i); + alu.src[0] = r600_src[1]; + alu.src[0].chan = tgsi_chan(&inst->Src[1], i); + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; + } + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; +} + +static int tgsi_lit(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int r; + + /* dst.x, <- 1.0 */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.src[0].sel = 249; /*1.0*/ + alu.src[0].chan = 0; + r = tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst); + if (r) + return r; + alu.dst.write = (inst->Dst[0].Register.WriteMask >> 0) & 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + /* dst.y = max(src.x, 0.0) */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX; + r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); + if (r) + return r; + alu.src[1].sel = 248; /*0.0*/ + alu.src[1].chan = tgsi_chan(&inst->Src[0], 0); + r = tgsi_dst(ctx, &inst->Dst[0], 1, &alu.dst); + if (r) + return r; + alu.dst.write = (inst->Dst[0].Register.WriteMask >> 1) & 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + /* dst.z = NOP - fill Z slot */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + alu.dst.chan = 2; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + /* dst.w, <- 1.0 */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.src[0].sel = 249; + alu.src[0].chan = 0; + r = tgsi_dst(ctx, &inst->Dst[0], 3, &alu.dst); + if (r) + return r; + alu.dst.write = (inst->Dst[0].Register.WriteMask >> 3) & 1; + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + if (inst->Dst[0].Register.WriteMask & (1 << 2)) + { + int chan; + int sel; + + /* dst.z = log(src.y) */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED; + r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); + if (r) + return r; + alu.src[0].chan = tgsi_chan(&inst->Src[0], 1); + r = tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst); + if (r) + return r; + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + chan = alu.dst.chan; + sel = alu.dst.sel; + + /* tmp.x = amd MUL_LIT(src.w, dst.z, src.x ) */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT; + r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); + if (r) + return r; + alu.src[0].chan = tgsi_chan(&inst->Src[0], 3); + alu.src[1].sel = sel; + alu.src[1].chan = chan; + r = tgsi_src(ctx, &inst->Src[0], &alu.src[2]); + if (r) + return r; + alu.src[2].chan = tgsi_chan(&inst->Src[0], 0); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 0; + alu.dst.write = 1; + alu.is_op3 = 1; + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + /* dst.z = exp(tmp.x) */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 0; + r = tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst); + if (r) + return r; + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; +} + +static int tgsi_trans(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int i, j, r; + + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + if (inst->Dst[0].Register.WriteMask & (1 << i)) { + alu.inst = ctx->inst_info->r600_opcode; + for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { + r = tgsi_src(ctx, &inst->Src[j], &alu.src[j]); + if (r) + return r; + alu.src[j].chan = tgsi_chan(&inst->Src[j], i); + } + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + } + return 0; +} + +static int tgsi_trans_srcx_replicate(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu alu; + int i, j, r; + + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = ctx->inst_info->r600_opcode; + for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { + r = tgsi_src(ctx, &inst->Src[j], &alu.src[j]); + if (r) + return r; + alu.src[j].chan = tgsi_chan(&inst->Src[j], 0); + } + alu.dst.sel = ctx->temp_reg; + alu.dst.write = 1; + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + /* replicate result */ + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.src[0].sel = ctx->temp_reg; + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.dst.chan = i; + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; + alu.dst.write = (inst->Dst[0].Register.WriteMask >> i) & 1; + if (i == 3) + alu.last = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; +} + +static int tgsi_helper_copy(struct r600_shader_ctx *ctx, struct tgsi_full_instruction *inst) +{ + struct r600_bc_alu alu; + int i, r; + + r = r600_bc_add_literal(ctx->bc, ctx->value); + if (r) + return r; + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + if (!(inst->Dst[0].Register.WriteMask & (1 << i))) { + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP; + alu.dst.chan = i; + } else { + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = i; + } + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return 0; +} + +static int tgsi_op3(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu_src r600_src[3]; + struct r600_bc_alu alu; + int i, j, r; + + r = tgsi_split_constant(ctx, r600_src); + if (r) + return r; + /* do it in 2 step as op3 doesn't support writemask */ + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = ctx->inst_info->r600_opcode; + for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { + alu.src[j] = r600_src[j]; + alu.src[j].chan = tgsi_chan(&inst->Src[j], i); + } + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = i; + alu.dst.write = 1; + alu.is_op3 = 1; + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return tgsi_helper_copy(ctx, inst); } + +static int tgsi_dp(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu_src r600_src[3]; + struct r600_bc_alu alu; + int i, j, r; + + r = tgsi_split_constant(ctx, r600_src); + if (r) + return r; + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = ctx->inst_info->r600_opcode; + for (j = 0; j < inst->Instruction.NumSrcRegs; j++) { + alu.src[j] = r600_src[j]; + alu.src[j].chan = tgsi_chan(&inst->Src[j], i); + } + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = i; + alu.dst.write = 1; + /* handle some special cases */ + switch (ctx->inst_info->tgsi_opcode) { + case TGSI_OPCODE_DP2: + if (i > 1) { + alu.src[0].sel = alu.src[1].sel = 248; + alu.src[0].chan = alu.src[1].chan = 0; + } + break; + case TGSI_OPCODE_DP3: + if (i > 2) { + alu.src[0].sel = alu.src[1].sel = 248; + alu.src[0].chan = alu.src[1].chan = 0; + } + break; + default: + break; + } + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return tgsi_helper_copy(ctx, inst); +} + +static int tgsi_tex(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_tex tex; + struct r600_bc_alu alu; + unsigned src_gpr; + int r; + + src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index; + + /* Add perspective divide */ + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE; + alu.src[0].sel = src_gpr; + alu.src[0].chan = tgsi_chan(&inst->Src[0], 3); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 3; + alu.last = 1; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; + alu.src[1].sel = src_gpr; + alu.src[1].chan = tgsi_chan(&inst->Src[0], 0); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 0; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; + alu.src[1].sel = src_gpr; + alu.src[1].chan = tgsi_chan(&inst->Src[0], 1); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 1; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; + alu.src[1].sel = src_gpr; + alu.src[1].chan = tgsi_chan(&inst->Src[0], 2); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 2; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.src[0].sel = 249; + alu.src[0].chan = 0; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 3; + alu.last = 1; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + src_gpr = ctx->temp_reg; + + /* TODO use temp if src_gpr is not a temporary reg (File != TEMPORARY) */ + memset(&tex, 0, sizeof(struct r600_bc_tex)); + tex.inst = ctx->inst_info->r600_opcode; + tex.resource_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index; + tex.sampler_id = tex.resource_id; + tex.src_gpr = src_gpr; + tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Dst[0].Register.Index; + tex.dst_sel_x = 0; + tex.dst_sel_y = 1; + tex.dst_sel_z = 2; + tex.dst_sel_w = 3; + tex.src_sel_x = 0; + tex.src_sel_y = 1; + tex.src_sel_z = 2; + tex.src_sel_w = 3; + + if (inst->Texture.Texture != TGSI_TEXTURE_RECT) { + tex.coord_type_x = 1; + tex.coord_type_y = 1; + tex.coord_type_z = 1; + tex.coord_type_w = 1; + } + return r600_bc_add_tex(ctx->bc, &tex); +} + +static int tgsi_lrp(struct r600_shader_ctx *ctx) +{ + struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + struct r600_bc_alu_src r600_src[3]; + struct r600_bc_alu alu; + unsigned i; + int r; + + r = tgsi_split_constant(ctx, r600_src); + if (r) + return r; + /* 1 - src0 */ + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD; + alu.src[0].sel = 249; + alu.src[0].chan = 0; + alu.src[1] = r600_src[0]; + alu.src[1].chan = tgsi_chan(&inst->Src[0], i); + alu.src[1].neg = 1; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = i; + if (i == 3) { + alu.last = 1; + } + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + r = r600_bc_add_literal(ctx->bc, ctx->value); + if (r) + return r; + + /* (1 - src0) * src2 */ + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = i; + alu.src[1] = r600_src[2]; + alu.src[1].chan = tgsi_chan(&inst->Src[2], i); + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = i; + if (i == 3) { + alu.last = 1; + } + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + r = r600_bc_add_literal(ctx->bc, ctx->value); + if (r) + return r; + + /* src0 * src1 + (1 - src0) * src2 */ + for (i = 0; i < 4; i++) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD; + alu.is_op3 = 1; + alu.src[0] = r600_src[0]; + alu.src[0].chan = tgsi_chan(&inst->Src[0], i); + alu.src[1] = r600_src[1]; + alu.src[1].chan = tgsi_chan(&inst->Src[1], i); + alu.src[2].sel = ctx->temp_reg; + alu.src[2].chan = i; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = i; + if (i == 3) { + alu.last = 1; + } + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + } + return tgsi_helper_copy(ctx, inst); +} + +static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { + {TGSI_OPCODE_ARL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MOV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2}, + {TGSI_OPCODE_LIT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_lit}, + {TGSI_OPCODE_RCP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, tgsi_trans_srcx_replicate}, + {TGSI_OPCODE_RSQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans_srcx_replicate}, + {TGSI_OPCODE_EXP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_LOG, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MUL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2}, + {TGSI_OPCODE_ADD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2}, + {TGSI_OPCODE_DP3, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp}, + {TGSI_OPCODE_DP4, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp}, + {TGSI_OPCODE_DST, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN, tgsi_op2}, + {TGSI_OPCODE_MAX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX, tgsi_op2}, + {TGSI_OPCODE_SLT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT, tgsi_slt}, + {TGSI_OPCODE_SGE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MAD, 1, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD, tgsi_op3}, + {TGSI_OPCODE_SUB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2}, + {TGSI_OPCODE_LRP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_lrp}, + {TGSI_OPCODE_CND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {20, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DP2A, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {22, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {23, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_FRC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CLAMP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_FLR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ROUND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_EX2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE, tgsi_trans_srcx_replicate}, + {TGSI_OPCODE_LG2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_POW, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_XPD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {32, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ABS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2}, + {TGSI_OPCODE_RCC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DPH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_COS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DDX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DDY, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_KILP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* predicated kill */ + {TGSI_OPCODE_PK2H, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_PK2US, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_PK4B, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_PK4UB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_RFL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SEQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SFL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SGT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SLE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SNE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_STR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TEX, 0, 0x10, tgsi_tex}, + {TGSI_OPCODE_TXD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXP, 0, 0x10, tgsi_tex}, + {TGSI_OPCODE_UP2H, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UP2US, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UP4B, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UP4UB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_X2D, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ARA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ARR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_BRA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CAL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_RET, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SSG, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* SGN */ + {TGSI_OPCODE_CMP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SCS, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_NRM, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DIV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DP2, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp}, + {TGSI_OPCODE_TXL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_BRK, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_IF, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {75, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {76, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ELSE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ENDIF, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {79, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {80, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_PUSHA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_POPA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CEIL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_I2F, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_NOT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TRUNC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SHL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {88, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_AND, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_OR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_MOD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_XOR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SAD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXF, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TXQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CONT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_EMIT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ENDPRIM, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_BGNLOOP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_BGNSUB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ENDLOOP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ENDSUB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {103, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {104, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {105, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {106, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_NOP, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + /* gap */ + {108, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {109, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {110, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {111, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_NRM4, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CALLNZ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_IFC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_BREAKC, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_KIL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT, tgsi_kill}, /* conditional kill */ + {TGSI_OPCODE_END, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_end}, /* aka HALT */ + /* gap */ + {118, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_F2I, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_IDIV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_IMAX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_IMIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_INEG, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ISGE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ISHR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ISLT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_F2U, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_U2F, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UADD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UDIV, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UMAD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UMAX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UMIN, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UMOD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_UMUL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_USEQ, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_USGE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_USHR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_USLT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_USNE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_SWITCH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_CASE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_DEFAULT, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ENDSWITCH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_LAST, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, +}; diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h index 40064ba8a99..2ee7780ead0 100644 --- a/src/gallium/drivers/r600/r600_shader.h +++ b/src/gallium/drivers/r600/r600_shader.h @@ -23,243 +23,25 @@ #ifndef R600_SHADER_H #define R600_SHADER_H -#include "r600_compiler.h" -#include "radeon.h" - -struct r600_shader_operand { - struct c_vector *vector; - unsigned sel; - unsigned chan; - unsigned neg; - unsigned abs; -}; - -struct r600_shader_vfetch { - struct list_head head; - unsigned cf_addr; - struct r600_shader_operand src[2]; - struct r600_shader_operand dst[4]; -}; - -struct r600_shader_inst { - unsigned is_op3; - unsigned opcode; - unsigned inst; - struct r600_shader_operand src[3]; - struct r600_shader_operand dst; - unsigned last; -}; - -struct r600_shader_alu { - struct list_head head; - unsigned nalu; - unsigned nliteral; - unsigned nconstant; - struct r600_shader_inst alu[5]; - u32 literal[4]; -}; - -struct r600_shader_node { - struct list_head head; - unsigned cf_id; /**< cf index (in dw) in byte code */ - unsigned cf_addr; /**< instructions index (in dw) in byte code */ - unsigned nslot; /**< number of slot (2 dw) needed by this node */ - unsigned nfetch; - struct c_node *node; /**< compiler node from which this node originate */ - struct list_head vfetch; /**< list of vfetch instructions */ - struct list_head alu; /**< list of alu instructions */ -}; +#include "r600_asm.h" struct r600_shader_io { - unsigned name; - unsigned gpr; - int sid; + unsigned name; + unsigned gpr; + unsigned done; + int sid; + unsigned interpolate; }; struct r600_shader { - unsigned stack_size; /**< stack size needed by this shader */ - unsigned ngpr; /**< number of GPR needed by this shader */ - unsigned nconstant; /**< number of constants used by this shader */ - unsigned nresource; /**< number of resources used by this shader */ - unsigned noutput; - unsigned ninput; - unsigned nvector; - unsigned ncf; /**< total number of cf clauses */ - unsigned nslot; /**< total number of slots (2 dw) */ - unsigned flat_shade; /**< are we flat shading */ - struct list_head nodes; /**< list of node */ - struct r600_shader_io input[32]; - struct r600_shader_io output[32]; - /* TODO replace GPR by some better register allocator */ - struct c_vector **gpr; - unsigned ndw; /**< bytes code size in dw */ - u32 *bcode; /**< bytes code */ - enum pipe_format resource_format[160]; /**< format of resource */ - struct c_shader cshader; - boolean r6xx_compile; + unsigned processor_type; + struct r600_bc bc; + boolean flat_shade; + unsigned ninput; + unsigned noutput; + struct r600_shader_io input[32]; + struct r600_shader_io output[32]; + enum radeon_family family; }; -void r600_shader_cleanup(struct r600_shader *rshader); -int r600_shader_register(struct r600_shader *rshader); -int r600_shader_node(struct r600_shader *shader); -void r600_shader_node_place(struct r600_shader *rshader); -int r600_shader_find_gpr(struct r600_shader *rshader, struct c_vector *v, unsigned swizzle, - struct r600_shader_operand *operand); -int r600_shader_vfetch_bytecode(struct r600_shader *rshader, - struct r600_shader_node *rnode, - struct r600_shader_vfetch *vfetch, - unsigned *cid); -int r600_shader_update(struct r600_shader *rshader, - enum pipe_format *resource_format); -int r600_shader_legalize(struct r600_shader *rshader); -int r600_cshader_legalize(struct c_shader *shader); - -int r700_shader_translate(struct r600_shader *rshader); - -int c_shader_from_tgsi(struct c_shader *shader, unsigned type, - const struct tgsi_token *tokens); -int r600_shader_register(struct r600_shader *rshader); -int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node); -int r700_shader_translate(struct r600_shader *rshader); -int r600_shader_insert_fetch(struct c_shader *shader); - -int r6xx_shader_alu_translate(struct r600_shader *rshader, - struct r600_shader_node *rnode, - unsigned *cid); - -enum r600_instruction { - INST_ADD = 0, - INST_MUL = 1, - INST_MUL_IEEE = 2, - INST_MAX = 3, - INST_MIN = 4, - INST_MAX_DX10 = 5, - INST_MIN_DX10 = 6, - INST_SETE = 7, - INST_SETGT = 8, - INST_SETGE = 9, - INST_SETNE = 10, - INST_SETE_DX10 = 11, - INST_SETGT_DX10 = 12, - INST_SETGE_DX10 = 13, - INST_SETNE_DX10 = 14, - INST_FRACT = 15, - INST_TRUNC = 16, - INST_CEIL = 17, - INST_RNDNE = 18, - INST_FLOOR = 19, - INST_MOVA = 20, - INST_MOVA_FLOOR = 21, - INST_MOVA_INT = 22, - INST_MOV = 23, - INST_NOP = 24, - INST_PRED_SETGT_UINT = 25, - INST_PRED_SETGE_UINT = 26, - INST_PRED_SETE = 27, - INST_PRED_SETGT = 28, - INST_PRED_SETGE = 29, - INST_PRED_SETNE = 30, - INST_PRED_SET_INV = 31, - INST_PRED_SET_POP = 32, - INST_PRED_SET_CLR = 33, - INST_PRED_SET_RESTORE = 34, - INST_PRED_SETE_PUSH = 35, - INST_PRED_SETGT_PUSH = 36, - INST_PRED_SETGE_PUSH = 37, - INST_PRED_SETNE_PUSH = 38, - INST_KILLE = 39, - INST_KILLGT = 40, - INST_KILLGE = 41, - INST_KILLNE = 42, - INST_AND_INT = 43, - INST_OR_INT = 44, - INST_XOR_INT = 45, - INST_NOT_INT = 46, - INST_ADD_INT = 47, - INST_SUB_INT = 48, - INST_MAX_INT = 49, - INST_MIN_INT = 50, - INST_MAX_UINT = 51, - INST_MIN_UINT = 52, - INST_SETE_INT = 53, - INST_SETGT_INT = 54, - INST_SETGE_INT = 55, - INST_SETNE_INT = 56, - INST_SETGT_UINT = 57, - INST_SETGE_UINT = 58, - INST_KILLGT_UINT = 59, - INST_KILLGE_UINT = 60, - INST_PRED_SETE_INT = 61, - INST_PRED_SETGT_INT = 62, - INST_PRED_SETGE_INT = 63, - INST_PRED_SETNE_INT = 64, - INST_KILLE_INT = 65, - INST_KILLGT_INT = 66, - INST_KILLGE_INT = 67, - INST_KILLNE_INT = 68, - INST_PRED_SETE_PUSH_INT = 69, - INST_PRED_SETGT_PUSH_INT = 70, - INST_PRED_SETGE_PUSH_INT = 71, - INST_PRED_SETNE_PUSH_INT = 72, - INST_PRED_SETLT_PUSH_INT = 73, - INST_PRED_SETLE_PUSH_INT = 74, - INST_DOT4 = 75, - INST_DOT4_IEEE = 76, - INST_CUBE = 77, - INST_MAX4 = 78, - INST_MOVA_GPR_INT = 79, - INST_EXP_IEEE = 80, - INST_LOG_CLAMPED = 81, - INST_LOG_IEEE = 82, - INST_RECIP_CLAMPED = 83, - INST_RECIP_FF = 84, - INST_RECIP_IEEE = 85, - INST_RECIPSQRT_CLAMPED = 86, - INST_RECIPSQRT_FF = 87, - INST_RECIPSQRT_IEEE = 88, - INST_SQRT_IEEE = 89, - INST_FLT_TO_INT = 90, - INST_INT_TO_FLT = 91, - INST_UINT_TO_FLT = 92, - INST_SIN = 93, - INST_COS = 94, - INST_ASHR_INT = 95, - INST_LSHR_INT = 96, - INST_LSHL_INT = 97, - INST_MULLO_INT = 98, - INST_MULHI_INT = 99, - INST_MULLO_UINT = 100, - INST_MULHI_UINT = 101, - INST_RECIP_INT = 102, - INST_RECIP_UINT = 103, - INST_FLT_TO_UINT = 104, - INST_MUL_LIT = 105, - INST_MUL_LIT_M2 = 106, - INST_MUL_LIT_M4 = 107, - INST_MUL_LIT_D2 = 108, - INST_MULADD = 109, - INST_MULADD_M2 = 110, - INST_MULADD_M4 = 111, - INST_MULADD_D2 = 112, - INST_MULADD_IEEE = 113, - INST_MULADD_IEEE_M2 = 114, - INST_MULADD_IEEE_M4 = 115, - INST_MULADD_IEEE_D2 = 116, - INST_CNDE = 117, - INST_CNDGT = 118, - INST_CNDGE = 119, - INST_CNDE_INT = 120, - INST_CNDGT_INT = 121, - INST_CNDGE_INT = 122, - INST_COUNT -}; - -struct r600_instruction_info { - enum r600_instruction instruction; - unsigned opcode; - unsigned is_trans; - unsigned is_op3; -}; - - #endif diff --git a/src/gallium/drivers/r600/r600_sq.h b/src/gallium/drivers/r600/r600_sq.h index 447ba98f004..002660c654a 100644 --- a/src/gallium/drivers/r600/r600_sq.h +++ b/src/gallium/drivers/r600/r600_sq.h @@ -87,9 +87,9 @@ #define G_SQ_CF_WORD1_BARRIER(x) (((x) >> 31) & 0x1) #define C_SQ_CF_WORD1_BARRIER 0x7FFFFFFF #define P_SQ_CF_ALU_WORD0 -#define S_SQ_CF_ALU_WORD0_ALU_ADDR(x) (((x) & 0x3FFFFF) << 0) -#define G_SQ_CF_ALU_WORD0_ALU_ADDR(x) (((x) >> 0) & 0x3FFFFF) -#define C_SQ_CF_ALU_WORD0_ALU_ADDR 0xFFC00000 +#define S_SQ_CF_ALU_WORD0_ADDR(x) (((x) & 0x3FFFFF) << 0) +#define G_SQ_CF_ALU_WORD0_ADDR(x) (((x) >> 0) & 0x3FFFFF) +#define C_SQ_CF_ALU_WORD0_ADDR 0xFFC00000 #define S_SQ_CF_ALU_WORD0_KCACHE_BANK0(x) (((x) & 0xF) << 22) #define G_SQ_CF_ALU_WORD0_KCACHE_BANK0(x) (((x) >> 22) & 0xF) #define C_SQ_CF_ALU_WORD0_KCACHE_BANK0 0xFC3FFFFF @@ -109,15 +109,15 @@ #define S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x) (((x) & 0xFF) << 10) #define G_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x) (((x) >> 10) & 0xFF) #define C_SQ_CF_ALU_WORD1_KCACHE_ADDR1 0xFFFC03FF -#define S_SQ_CF_ALU_WORD1_ALU_COUNT(x) (((x) & 0x7F) << 18) -#define G_SQ_CF_ALU_WORD1_ALU_COUNT(x) (((x) >> 18) & 0x7F) -#define C_SQ_CF_ALU_WORD1_ALU_COUNT 0xFE03FFFF +#define S_SQ_CF_ALU_WORD1_COUNT(x) (((x) & 0x7F) << 18) +#define G_SQ_CF_ALU_WORD1_COUNT(x) (((x) >> 18) & 0x7F) +#define C_SQ_CF_ALU_WORD1_COUNT 0xFE03FFFF #define S_SQ_CF_ALU_WORD1_USES_WATERFALL(x) (((x) & 0x1) << 25) #define G_SQ_CF_ALU_WORD1_USES_WATERFALL(x) (((x) >> 25) & 0x1) #define C_SQ_CF_ALU_WORD1_USES_WATERFALL 0xFDFFFFFF -#define S_SQ_CF_ALU_WORD1_CF_ALU_INST(x) (((x) & 0xF) << 26) -#define G_SQ_CF_ALU_WORD1_CF_ALU_INST(x) (((x) >> 26) & 0xF) -#define C_SQ_CF_ALU_WORD1_CF_ALU_INST 0xC3FFFFFF +#define S_SQ_CF_ALU_WORD1_CF_INST(x) (((x) & 0xF) << 26) +#define G_SQ_CF_ALU_WORD1_CF_INST(x) (((x) >> 26) & 0xF) +#define C_SQ_CF_ALU_WORD1_CF_INST 0xC3FFFFFF #define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU 0x00000008 #define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE 0x00000009 #define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER 0x0000000A @@ -546,6 +546,8 @@ #define S_SQ_TEX_WORD1_COORD_TYPE_X(x) (((x) & 0x1) << 28) #define G_SQ_TEX_WORD1_COORD_TYPE_X(x) (((x) >> 28) & 0x1) #define C_SQ_TEX_WORD1_COORD_TYPE_X 0xEFFFFFFF +#define V_SQ_TEX_WORD1_COORD_UNNORMALIZED 0x00000000 +#define V_SQ_TEX_WORD1_COORD_NORMALIZED 0x00000001 #define S_SQ_TEX_WORD1_COORD_TYPE_Y(x) (((x) & 0x1) << 29) #define G_SQ_TEX_WORD1_COORD_TYPE_Y(x) (((x) >> 29) & 0x1) #define C_SQ_TEX_WORD1_COORD_TYPE_Y 0xDFFFFFFF diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 4150f88785e..3efd409ae0d 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -24,36 +24,605 @@ * Jerome Glisse */ #include <stdio.h> -#include <util/u_inlines.h> -#include <util/u_format.h> -#include <util/u_memory.h> +#include <errno.h> +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_memory.h" #include "r600_screen.h" -#include "r600_texture.h" #include "r600_context.h" +#include "r600_resource.h" #include "r600d.h" +#include "r600_state_inlines.h" +static void *r600_create_blend_state(struct pipe_context *ctx, + const struct pipe_blend_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + + return r600_context_state(rctx, pipe_blend_type, state); +} + +static void *r600_create_dsa_state(struct pipe_context *ctx, + const struct pipe_depth_stencil_alpha_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + + return r600_context_state(rctx, pipe_dsa_type, state); +} + +static void *r600_create_rs_state(struct pipe_context *ctx, + const struct pipe_rasterizer_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + + return r600_context_state(rctx, pipe_rasterizer_type, state); +} + +static void *r600_create_sampler_state(struct pipe_context *ctx, + const struct pipe_sampler_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + + return r600_context_state(rctx, pipe_sampler_type, state); +} + +static void r600_sampler_view_destroy(struct pipe_context *ctx, + struct pipe_sampler_view *state) +{ + struct r600_context_state *rstate = (struct r600_context_state *)state; + + r600_context_state_decref(rstate); +} + +static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx, + struct pipe_resource *texture, + const struct pipe_sampler_view *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_sampler_type, state); + pipe_reference(NULL, &texture->reference); + rstate->state.sampler_view.texture = texture; + rstate->state.sampler_view.reference.count = 1; + rstate->state.sampler_view.context = ctx; + return &rstate->state.sampler_view; +} + +static void *r600_create_shader_state(struct pipe_context *ctx, + const struct pipe_shader_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + + return r600_context_state(rctx, pipe_shader_type, state); +} + +static void *r600_create_vertex_elements(struct pipe_context *ctx, + unsigned count, + const struct pipe_vertex_element *elements) +{ + struct r600_vertex_element *v = CALLOC_STRUCT(r600_vertex_element); + + assert(count < 32); + v->count = count; + memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element)); + v->refcount = 1; + return v; +} + +static void r600_bind_state(struct pipe_context *ctx, void *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate = (struct r600_context_state *)state; + + if (state == NULL) + return; + switch (rstate->type) { + case pipe_rasterizer_type: + rctx->rasterizer = r600_context_state_decref(rctx->rasterizer); + rctx->rasterizer = r600_context_state_incref(rstate); + break; + case pipe_poly_stipple_type: + rctx->poly_stipple = r600_context_state_decref(rctx->poly_stipple); + rctx->poly_stipple = r600_context_state_incref(rstate); + break; + case pipe_scissor_type: + rctx->scissor = r600_context_state_decref(rctx->scissor); + rctx->scissor = r600_context_state_incref(rstate); + break; + case pipe_clip_type: + rctx->clip = r600_context_state_decref(rctx->clip); + rctx->clip = r600_context_state_incref(rstate); + break; + case pipe_depth_type: + rctx->depth = r600_context_state_decref(rctx->depth); + rctx->depth = r600_context_state_incref(rstate); + break; + case pipe_stencil_type: + rctx->stencil = r600_context_state_decref(rctx->stencil); + rctx->stencil = r600_context_state_incref(rstate); + break; + case pipe_alpha_type: + rctx->alpha = r600_context_state_decref(rctx->alpha); + rctx->alpha = r600_context_state_incref(rstate); + break; + case pipe_dsa_type: + rctx->dsa = r600_context_state_decref(rctx->dsa); + rctx->dsa = r600_context_state_incref(rstate); + break; + case pipe_blend_type: + rctx->blend = r600_context_state_decref(rctx->blend); + rctx->blend = r600_context_state_incref(rstate); + break; + case pipe_framebuffer_type: + rctx->framebuffer = r600_context_state_decref(rctx->framebuffer); + rctx->framebuffer = r600_context_state_incref(rstate); + break; + case pipe_stencil_ref_type: + rctx->stencil_ref = r600_context_state_decref(rctx->stencil_ref); + rctx->stencil_ref = r600_context_state_incref(rstate); + break; + case pipe_viewport_type: + rctx->viewport = r600_context_state_decref(rctx->viewport); + rctx->viewport = r600_context_state_incref(rstate); + break; + case pipe_shader_type: + case pipe_sampler_type: + case pipe_sampler_view_type: + default: + R600_ERR("invalid type %d\n", rstate->type); + return; + } +} + +static void r600_bind_ps_shader(struct pipe_context *ctx, void *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate = (struct r600_context_state *)state; + + rctx->ps_shader = r600_context_state_decref(rctx->ps_shader); + rctx->ps_shader = r600_context_state_incref(rstate); +} + +static void r600_bind_vs_shader(struct pipe_context *ctx, void *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate = (struct r600_context_state *)state; + + rctx->vs_shader = r600_context_state_decref(rctx->vs_shader); + rctx->vs_shader = r600_context_state_incref(rstate); +} + +static void r600_delete_vertex_element(struct pipe_context *ctx, void *state) +{ + struct r600_vertex_element *v = (struct r600_vertex_element*)state; + + if (v == NULL) + return; + if (--v->refcount) + return; + free(v); +} + +static void r600_bind_vertex_elements(struct pipe_context *ctx, void *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_vertex_element *v = (struct r600_vertex_element*)state; + + r600_delete_vertex_element(ctx, rctx->vertex_elements); + rctx->vertex_elements = v; + if (v) { + v->refcount++; + } +} + +static void r600_bind_ps_sampler(struct pipe_context *ctx, + unsigned count, void **states) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + unsigned i; + + for (i = 0; i < rctx->ps_nsampler; i++) { + rctx->ps_sampler[i] = r600_context_state_decref(rctx->ps_sampler[i]); + } + for (i = 0; i < count; i++) { + rstate = (struct r600_context_state *)states[i]; + rctx->ps_sampler[i] = r600_context_state_incref(rstate); + } + rctx->ps_nsampler = count; +} + +static void r600_bind_vs_sampler(struct pipe_context *ctx, + unsigned count, void **states) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + unsigned i; + + for (i = 0; i < rctx->vs_nsampler; i++) { + rctx->vs_sampler[i] = r600_context_state_decref(rctx->vs_sampler[i]); + } + for (i = 0; i < count; i++) { + rstate = (struct r600_context_state *)states[i]; + rctx->vs_sampler[i] = r600_context_state_incref(rstate); + } + rctx->vs_nsampler = count; +} static void r600_delete_state(struct pipe_context *ctx, void *state) { - struct radeon_state *rstate = state; + struct r600_context_state *rstate = (struct r600_context_state *)state; - radeon_state_decref(rstate); + r600_context_state_decref(rstate); } -static void *r600_create_blend_state(struct pipe_context *ctx, - const struct pipe_blend_state *state) +static void r600_set_blend_color(struct pipe_context *ctx, + const struct pipe_blend_color *color) +{ + struct r600_context *rctx = r600_context(ctx); + + rctx->blend_color = *color; +} + +static void r600_set_clip_state(struct pipe_context *ctx, + const struct pipe_clip_state *state) +{ +} + +static void r600_set_constant_buffer(struct pipe_context *ctx, + uint shader, uint index, + struct pipe_resource *buffer) { struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_context *rctx = r600_context(ctx); + unsigned nconstant = 0, i, type, id; + struct radeon_state *rstate; + struct pipe_transfer *transfer; + u32 *ptr; + + switch (shader) { + case PIPE_SHADER_VERTEX: + id = R600_VS_CONSTANT; + type = R600_VS_CONSTANT_TYPE; + break; + case PIPE_SHADER_FRAGMENT: + id = R600_PS_CONSTANT; + type = R600_PS_CONSTANT_TYPE; + break; + default: + R600_ERR("unsupported %d\n", shader); + return; + } + if (buffer && buffer->width0 > 0) { + nconstant = buffer->width0 / 16; + ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer); + if (ptr == NULL) + return; + for (i = 0; i < nconstant; i++) { + rstate = radeon_state(rscreen->rw, type, id + i); + if (rstate == NULL) + return; + rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0]; + rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1]; + rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2]; + rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3]; + if (radeon_state_pm4(rstate)) + return; + if (radeon_draw_set_new(rctx->draw, rstate)) + return; + } + pipe_buffer_unmap(ctx, buffer, transfer); + } +} + +static void r600_set_ps_sampler_view(struct pipe_context *ctx, + unsigned count, + struct pipe_sampler_view **views) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + unsigned i; + + for (i = 0; i < rctx->ps_nsampler_view; i++) { + rctx->ps_sampler_view[i] = r600_context_state_decref(rctx->ps_sampler_view[i]); + } + for (i = 0; i < count; i++) { + rstate = (struct r600_context_state *)views[i]; + rctx->ps_sampler_view[i] = r600_context_state_incref(rstate); + } + rctx->ps_nsampler_view = count; +} + +static void r600_set_vs_sampler_view(struct pipe_context *ctx, + unsigned count, + struct pipe_sampler_view **views) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + unsigned i; + + for (i = 0; i < rctx->vs_nsampler_view; i++) { + rctx->vs_sampler_view[i] = r600_context_state_decref(rctx->vs_sampler_view[i]); + } + for (i = 0; i < count; i++) { + rstate = (struct r600_context_state *)views[i]; + rctx->vs_sampler_view[i] = r600_context_state_incref(rstate); + } + rctx->vs_nsampler_view = count; +} + +static void r600_set_framebuffer_state(struct pipe_context *ctx, + const struct pipe_framebuffer_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_framebuffer_type, state); + r600_bind_state(ctx, rstate); +} + +static void r600_set_polygon_stipple(struct pipe_context *ctx, + const struct pipe_poly_stipple *state) +{ +} + +static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) +{ +} + +static void r600_set_scissor_state(struct pipe_context *ctx, + const struct pipe_scissor_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_scissor_type, state); + r600_bind_state(ctx, rstate); + /* refcount is taken care of this */ + r600_delete_state(ctx, rstate); +} + +static void r600_set_stencil_ref(struct pipe_context *ctx, + const struct pipe_stencil_ref *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_stencil_ref_type, state); + r600_bind_state(ctx, rstate); + /* refcount is taken care of this */ + r600_delete_state(ctx, rstate); +} + +static void r600_set_vertex_buffers(struct pipe_context *ctx, + unsigned count, + const struct pipe_vertex_buffer *buffers) +{ + struct r600_context *rctx = r600_context(ctx); + unsigned i; + + for (i = 0; i < rctx->nvertex_buffer; i++) { + pipe_resource_reference(&rctx->vertex_buffer[i].buffer, NULL); + } + memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); + for (i = 0; i < count; i++) { + rctx->vertex_buffer[i].buffer = NULL; + pipe_resource_reference(&rctx->vertex_buffer[i].buffer, buffers[i].buffer); + } + rctx->nvertex_buffer = count; +} + +static void r600_set_index_buffer(struct pipe_context *ctx, + const struct pipe_index_buffer *ib) +{ + struct r600_context *rctx = r600_context(ctx); + + if (ib) { + pipe_resource_reference(&rctx->index_buffer.buffer, ib->buffer); + memcpy(&rctx->index_buffer, ib, sizeof(rctx->index_buffer)); + } else { + pipe_resource_reference(&rctx->index_buffer.buffer, NULL); + memset(&rctx->index_buffer, 0, sizeof(rctx->index_buffer)); + } + + /* TODO make this more like a state */ +} + +static void r600_set_viewport_state(struct pipe_context *ctx, + const struct pipe_viewport_state *state) +{ + struct r600_context *rctx = r600_context(ctx); + struct r600_context_state *rstate; + + rstate = r600_context_state(rctx, pipe_viewport_type, state); + r600_bind_state(ctx, rstate); + r600_delete_state(ctx, rstate); +} + +void r600_init_state_functions(struct r600_context *rctx) +{ + rctx->context.create_blend_state = r600_create_blend_state; + rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state; + rctx->context.create_fs_state = r600_create_shader_state; + rctx->context.create_rasterizer_state = r600_create_rs_state; + rctx->context.create_sampler_state = r600_create_sampler_state; + rctx->context.create_sampler_view = r600_create_sampler_view; + rctx->context.create_vertex_elements_state = r600_create_vertex_elements; + rctx->context.create_vs_state = r600_create_shader_state; + rctx->context.bind_blend_state = r600_bind_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; + rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler; + rctx->context.bind_fs_state = r600_bind_ps_shader; + rctx->context.bind_rasterizer_state = r600_bind_state; + rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements; + rctx->context.bind_vertex_sampler_states = r600_bind_vs_sampler; + rctx->context.bind_vs_state = r600_bind_vs_shader; + rctx->context.delete_blend_state = r600_delete_state; + rctx->context.delete_depth_stencil_alpha_state = r600_delete_state; + rctx->context.delete_fs_state = r600_delete_state; + rctx->context.delete_rasterizer_state = r600_delete_state; + rctx->context.delete_sampler_state = r600_delete_state; + rctx->context.delete_vertex_elements_state = r600_delete_vertex_element; + rctx->context.delete_vs_state = r600_delete_state; + rctx->context.set_blend_color = r600_set_blend_color; + rctx->context.set_clip_state = r600_set_clip_state; + rctx->context.set_constant_buffer = r600_set_constant_buffer; + rctx->context.set_fragment_sampler_views = r600_set_ps_sampler_view; + rctx->context.set_framebuffer_state = r600_set_framebuffer_state; + rctx->context.set_polygon_stipple = r600_set_polygon_stipple; + rctx->context.set_sample_mask = r600_set_sample_mask; + rctx->context.set_scissor_state = r600_set_scissor_state; + rctx->context.set_stencil_ref = r600_set_stencil_ref; + rctx->context.set_vertex_buffers = r600_set_vertex_buffers; + rctx->context.set_index_buffer = r600_set_index_buffer; + rctx->context.set_vertex_sampler_views = r600_set_vs_sampler_view; + rctx->context.set_viewport_state = r600_set_viewport_state; + rctx->context.sampler_view_destroy = r600_sampler_view_destroy; +} + +struct r600_context_state *r600_context_state_incref(struct r600_context_state *rstate) +{ + if (rstate == NULL) + return NULL; + rstate->refcount++; + return rstate; +} + +struct r600_context_state *r600_context_state_decref(struct r600_context_state *rstate) +{ + unsigned i; + + if (rstate == NULL) + return NULL; + if (--rstate->refcount) + return NULL; + switch (rstate->type) { + case pipe_sampler_view_type: + pipe_resource_reference(&rstate->state.sampler_view.texture, NULL); + break; + case pipe_framebuffer_type: + for (i = 0; i < rstate->state.framebuffer.nr_cbufs; i++) { + pipe_surface_reference(&rstate->state.framebuffer.cbufs[i], NULL); + } + pipe_surface_reference(&rstate->state.framebuffer.zsbuf, NULL); + break; + case pipe_viewport_type: + case pipe_depth_type: + case pipe_rasterizer_type: + case pipe_poly_stipple_type: + case pipe_scissor_type: + case pipe_clip_type: + case pipe_stencil_type: + case pipe_alpha_type: + case pipe_dsa_type: + case pipe_blend_type: + case pipe_stencil_ref_type: + case pipe_shader_type: + case pipe_sampler_type: + break; + default: + R600_ERR("invalid type %d\n", rstate->type); + return NULL; + } + radeon_state_decref(rstate->rstate); + FREE(rstate); + return NULL; +} + +struct r600_context_state *r600_context_state(struct r600_context *rctx, unsigned type, const void *state) +{ + struct r600_context_state *rstate = CALLOC_STRUCT(r600_context_state); + const union pipe_states *states = state; + unsigned i; + int r; + + if (rstate == NULL) + return NULL; + rstate->type = type; + rstate->refcount = 1; + + switch (rstate->type) { + case pipe_sampler_view_type: + rstate->state.sampler_view = (*states).sampler_view; + rstate->state.sampler_view.texture = NULL; + break; + case pipe_framebuffer_type: + rstate->state.framebuffer = (*states).framebuffer; + for (i = 0; i < rstate->state.framebuffer.nr_cbufs; i++) { + pipe_surface_reference(&rstate->state.framebuffer.cbufs[i], + (*states).framebuffer.cbufs[i]); + } + pipe_surface_reference(&rstate->state.framebuffer.zsbuf, + (*states).framebuffer.zsbuf); + break; + case pipe_viewport_type: + rstate->state.viewport = (*states).viewport; + break; + case pipe_depth_type: + rstate->state.depth = (*states).depth; + break; + case pipe_rasterizer_type: + rstate->state.rasterizer = (*states).rasterizer; + break; + case pipe_poly_stipple_type: + rstate->state.poly_stipple = (*states).poly_stipple; + break; + case pipe_scissor_type: + rstate->state.scissor = (*states).scissor; + break; + case pipe_clip_type: + rstate->state.clip = (*states).clip; + break; + case pipe_stencil_type: + rstate->state.stencil = (*states).stencil; + break; + case pipe_alpha_type: + rstate->state.alpha = (*states).alpha; + break; + case pipe_dsa_type: + rstate->state.dsa = (*states).dsa; + break; + case pipe_blend_type: + rstate->state.blend = (*states).blend; + break; + case pipe_stencil_ref_type: + rstate->state.stencil_ref = (*states).stencil_ref; + break; + case pipe_shader_type: + rstate->state.shader = (*states).shader; + r = r600_pipe_shader_create(&rctx->context, rstate, rstate->state.shader.tokens); + if (r) { + r600_context_state_decref(rstate); + return NULL; + } + break; + case pipe_sampler_type: + rstate->state.sampler = (*states).sampler; + break; + default: + R600_ERR("invalid type %d\n", rstate->type); + FREE(rstate); + return NULL; + } + return rstate; +} + +static struct radeon_state *r600_blend(struct r600_context *rctx) +{ + struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; + const struct pipe_blend_state *state = &rctx->blend->state.blend; + int i; rstate = radeon_state(rscreen->rw, R600_BLEND_TYPE, R600_BLEND); if (rstate == NULL) return NULL; - rstate->states[R600_BLEND__CB_BLEND_RED] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND_GREEN] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND_BLUE] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND_ALPHA] = 0x00000000; - rstate->states[R600_BLEND__CB_BLEND0_CONTROL] = 0x00010001; + rstate->states[R600_BLEND__CB_BLEND_RED] = fui(rctx->blend_color.color[0]); + rstate->states[R600_BLEND__CB_BLEND_GREEN] = fui(rctx->blend_color.color[1]); + rstate->states[R600_BLEND__CB_BLEND_BLUE] = fui(rctx->blend_color.color[2]); + rstate->states[R600_BLEND__CB_BLEND_ALPHA] = fui(rctx->blend_color.color[3]); + rstate->states[R600_BLEND__CB_BLEND0_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND1_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND2_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND3_CONTROL] = 0x00000000; @@ -62,6 +631,36 @@ static void *r600_create_blend_state(struct pipe_context *ctx, rstate->states[R600_BLEND__CB_BLEND6_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND7_CONTROL] = 0x00000000; rstate->states[R600_BLEND__CB_BLEND_CONTROL] = 0x00000000; + + for (i = 0; i < 8; i++) { + unsigned eqRGB = state->rt[i].rgb_func; + unsigned srcRGB = state->rt[i].rgb_src_factor; + unsigned dstRGB = state->rt[i].rgb_dst_factor; + + unsigned eqA = state->rt[i].alpha_func; + unsigned srcA = state->rt[i].alpha_src_factor; + unsigned dstA = state->rt[i].alpha_dst_factor; + uint32_t bc = 0; + + if (!state->rt[i].blend_enable) + continue; + + bc |= S_028804_COLOR_COMB_FCN(r600_translate_blend_function(eqRGB)); + bc |= S_028804_COLOR_SRCBLEND(r600_translate_blend_factor(srcRGB)); + bc |= S_028804_COLOR_DESTBLEND(r600_translate_blend_factor(dstRGB)); + + if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { + bc |= S_028804_SEPARATE_ALPHA_BLEND(1); + bc |= S_028804_ALPHA_COMB_FCN(r600_translate_blend_function(eqA)); + bc |= S_028804_ALPHA_SRCBLEND(r600_translate_blend_factor(srcA)); + bc |= S_028804_ALPHA_DESTBLEND(r600_translate_blend_factor(dstA)); + } + + rstate->states[R600_BLEND__CB_BLEND0_CONTROL + i] = bc; + if (i == 0) + rstate->states[R600_BLEND__CB_BLEND_CONTROL] = bc; + } + if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); return NULL; @@ -69,38 +668,24 @@ static void *r600_create_blend_state(struct pipe_context *ctx, return rstate; } -static void r600_bind_blend_state(struct pipe_context *ctx, void *state) -{ - struct r600_context *rctx = r600_context(ctx); - radeon_draw_set(rctx->draw, state); -} - -static void r600_set_blend_color(struct pipe_context *ctx, - const struct pipe_blend_color *color) +static struct radeon_state *r600_cb(struct r600_context *rctx, int cb) { -} - -static void r600_set_clip_state(struct pipe_context *ctx, - const struct pipe_clip_state *state) -{ -} - -static void r600_set_framebuffer_state(struct pipe_context *ctx, - const struct pipe_framebuffer_state *state) -{ - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_context *rctx = r600_context(ctx); - struct r600_texture *rtex; - struct r600_buffer *rbuffer; + struct r600_screen *rscreen = rctx->screen; + struct r600_resource_texture *rtex; + struct r600_resource *rbuffer; struct radeon_state *rstate; - unsigned level = state->cbufs[0]->level; + const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer; + unsigned level = state->cbufs[cb]->level; unsigned pitch, slice; + unsigned color_info; + unsigned format, swap, ntype; + const struct util_format_description *desc; - rstate = radeon_state(rscreen->rw, R600_CB0_TYPE, R600_CB0); + rstate = radeon_state(rscreen->rw, R600_CB0_TYPE + cb, R600_CB0 + cb); if (rstate == NULL) - return; - rtex = (struct r600_texture*)state->cbufs[0]->texture; - rbuffer = (struct r600_buffer*)rtex->buffer; + return NULL; + rtex = (struct r600_resource_texture*)state->cbufs[cb]->texture; + rbuffer = &rtex->resource; rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo); rstate->bo[2] = radeon_bo_incref(rscreen->rw, rbuffer->bo); @@ -108,10 +693,25 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, rstate->placement[2] = RADEON_GEM_DOMAIN_GTT; rstate->placement[4] = RADEON_GEM_DOMAIN_GTT; rstate->nbo = 3; - pitch = rtex->pitch[level] / 8 - 1; - slice = rtex->pitch[level] * state->cbufs[0]->height / 64 - 1; + pitch = (rtex->pitch[level] / rtex->bpt) / 8 - 1; + slice = (rtex->pitch[level] / rtex->bpt) * state->cbufs[cb]->height / 64 - 1; + + ntype = 0; + desc = util_format_description(rtex->resource.base.b.format); + if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) + ntype = V_0280A0_NUMBER_SRGB; + + format = r600_translate_colorformat(rtex->resource.base.b.format); + swap = r600_translate_colorswap(rtex->resource.base.b.format); + + color_info = S_0280A0_FORMAT(format) | + S_0280A0_COMP_SWAP(swap) | + S_0280A0_BLEND_CLAMP(1) | + S_0280A0_SOURCE_FORMAT(1) | + S_0280A0_NUMBER_TYPE(ntype); + rstate->states[R600_CB0__CB_COLOR0_BASE] = 0x00000000; - rstate->states[R600_CB0__CB_COLOR0_INFO] = 0x08110068; + rstate->states[R600_CB0__CB_COLOR0_INFO] = color_info; rstate->states[R600_CB0__CB_COLOR0_SIZE] = S_028060_PITCH_TILE_MAX(pitch) | S_028060_SLICE_TILE_MAX(slice); rstate->states[R600_CB0__CB_COLOR0_VIEW] = 0x00000000; @@ -120,83 +720,124 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, rstate->states[R600_CB0__CB_COLOR0_MASK] = 0x00000000; if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); - return; + return NULL; } - radeon_draw_set_new(rctx->draw, rstate); - rctx->db = radeon_state_decref(rctx->db); - if(state->zsbuf) { - rtex = (struct r600_texture*)state->zsbuf->texture; - rbuffer = (struct r600_buffer*)rtex->buffer; - rctx->db = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB); - if(rctx->db == NULL) - return; - rctx->db->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); - rctx->db->nbo = 1; - rctx->db->placement[0] = RADEON_GEM_DOMAIN_VRAM; - level = state->zsbuf->level; - pitch = rtex->pitch[level] / 8 - 1; - slice = rtex->pitch[level] * state->zsbuf->height / 64 - 1; - - rctx->db->states[R600_DB__DB_DEPTH_BASE] = 0x00000000; - rctx->db->states[R600_DB__DB_DEPTH_INFO] = 0x00010006; - rctx->db->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000; - rctx->db->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1; - rctx->db->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) | - S_028000_SLICE_TILE_MAX(slice); - } else - rctx->db = NULL; - rctx->fb_state = *state; -} - -static void *r600_create_fs_state(struct pipe_context *ctx, - const struct pipe_shader_state *shader) -{ - return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_FS, shader->tokens); -} - -static void r600_bind_fs_state(struct pipe_context *ctx, void *state) -{ - struct r600_context *rctx = r600_context(ctx); - - rctx->ps_shader = state; + return rstate; } -static void *r600_create_vs_state(struct pipe_context *ctx, - const struct pipe_shader_state *shader) +static struct radeon_state *r600_db(struct r600_context *rctx) { - return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_VS, shader->tokens); -} + struct r600_screen *rscreen = rctx->screen; + struct r600_resource_texture *rtex; + struct r600_resource *rbuffer; + struct radeon_state *rstate; + const struct pipe_framebuffer_state *state = &rctx->framebuffer->state.framebuffer; + unsigned level; + unsigned pitch, slice, format; -static void r600_bind_vs_state(struct pipe_context *ctx, void *state) -{ - struct r600_context *rctx = r600_context(ctx); + if (state->zsbuf == NULL) + return NULL; - rctx->vs_shader = state; -} + rstate = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB); + if (rstate == NULL) + return NULL; -static void r600_set_polygon_stipple(struct pipe_context *ctx, - const struct pipe_poly_stipple *state) -{ + rtex = (struct r600_resource_texture*)state->zsbuf->texture; + rbuffer = &rtex->resource; + rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); + rstate->nbo = 1; + rstate->placement[0] = RADEON_GEM_DOMAIN_VRAM; + level = state->zsbuf->level; + pitch = (rtex->pitch[level] / rtex->bpt) / 8 - 1; + slice = (rtex->pitch[level] / rtex->bpt) * state->zsbuf->height / 64 - 1; + format = r600_translate_dbformat(state->zsbuf->texture->format); + rstate->states[R600_DB__DB_DEPTH_BASE] = 0x00000000; + rstate->states[R600_DB__DB_DEPTH_INFO] = 0x00010000 | + S_028010_FORMAT(format); + rstate->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000; + rstate->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1; + rstate->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) | + S_028000_SLICE_TILE_MAX(slice); + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; } -static void *r600_create_rs_state(struct pipe_context *ctx, - const struct pipe_rasterizer_state *state) +static struct radeon_state *r600_rasterizer(struct r600_context *rctx) { - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_context *rctx = r600_context(ctx); + const struct pipe_rasterizer_state *state = &rctx->rasterizer->state.rasterizer; + const struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; + struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; + float offset_units = 0, offset_scale = 0; + char depth = 0; + unsigned offset_db_fmt_cntl = 0; + unsigned tmp; + unsigned prov_vtx = 1; + if (fb->zsbuf) { + offset_units = state->offset_units; + offset_scale = state->offset_scale * 12.0f; + switch (fb->zsbuf->texture->format) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + depth = -24; + offset_units *= 2.0f; + break; + case PIPE_FORMAT_Z32_FLOAT: + depth = -23; + offset_units *= 1.0f; + offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1); + break; + case PIPE_FORMAT_Z16_UNORM: + depth = -16; + offset_units *= 4.0f; + break; + default: + R600_ERR("unsupported %d\n", fb->zsbuf->texture->format); + return NULL; + } + } + offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth); + + if (state->flatshade_first) + prov_vtx = 0; rctx->flat_shade = state->flatshade; rstate = radeon_state(rscreen->rw, R600_RASTERIZER_TYPE, R600_RASTERIZER); if (rstate == NULL) return NULL; rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] = 0x00000001; + if (state->sprite_coord_enable) { + rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] |= + S_0286D4_PNT_SPRITE_ENA(1) | + S_0286D4_PNT_SPRITE_OVRD_X(2) | + S_0286D4_PNT_SPRITE_OVRD_Y(3) | + S_0286D4_PNT_SPRITE_OVRD_Z(0) | + S_0286D4_PNT_SPRITE_OVRD_W(1); + if (state->sprite_coord_mode != PIPE_SPRITE_COORD_UPPER_LEFT) { + rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] |= + S_0286D4_PNT_SPRITE_TOP_1(1); + } + } rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080000; - rstate->states[R600_RASTERIZER__PA_CL_VS_OUT_CNTL] = 0x00000000; + rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = + S_028814_PROVOKING_VTX_LAST(prov_vtx) | + S_028814_CULL_FRONT((state->cull_face & PIPE_FACE_FRONT) ? 1 : 0) | + S_028814_CULL_BACK((state->cull_face & PIPE_FACE_BACK) ? 1 : 0) | + S_028814_FACE(!state->front_ccw) | + S_028814_POLY_OFFSET_FRONT_ENABLE(state->offset_tri) | + S_028814_POLY_OFFSET_BACK_ENABLE(state->offset_tri) | + S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_tri); + rstate->states[R600_RASTERIZER__PA_CL_VS_OUT_CNTL] = + S_02881C_USE_VTX_POINT_SIZE(state->point_size_per_vertex) | + S_02881C_VS_OUT_MISC_VEC_ENA(state->point_size_per_vertex); rstate->states[R600_RASTERIZER__PA_CL_NANINF_CNTL] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_POINT_SIZE] = 0x00080008; - rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x00000000; + /* point size 12.4 fixed point */ + tmp = (unsigned)(state->point_size * 8.0 / 2.0); + rstate->states[R600_RASTERIZER__PA_SU_POINT_SIZE] = S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp); + rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x80000000; rstate->states[R600_RASTERIZER__PA_SU_LINE_CNTL] = 0x00000008; rstate->states[R600_RASTERIZER__PA_SC_LINE_STIPPLE] = 0x00000005; rstate->states[R600_RASTERIZER__PA_SC_MPASS_PS_CNTL] = 0x00000000; @@ -205,12 +846,12 @@ static void *r600_create_rs_state(struct pipe_context *ctx, rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_DISC_ADJ] = 0x3F800000; rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_CLIP_ADJ] = 0x3F800000; rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_DISC_ADJ] = 0x3F800000; - rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_DB_FMT_CNTL] = 0x00000000; + rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_DB_FMT_CNTL] = offset_db_fmt_cntl; rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_CLAMP] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_SCALE] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_OFFSET] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_SCALE] = 0x00000000; - rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_OFFSET] = 0x00000000; + rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_SCALE] = fui(offset_scale); + rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_OFFSET] = fui(offset_units); + rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_SCALE] = fui(offset_scale); + rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_OFFSET] = fui(offset_units); if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); return NULL; @@ -218,64 +859,31 @@ static void *r600_create_rs_state(struct pipe_context *ctx, return rstate; } -static void r600_bind_rs_state(struct pipe_context *ctx, void *state) +static struct radeon_state *r600_scissor(struct r600_context *rctx) { - struct r600_context *rctx = r600_context(ctx); - radeon_draw_set(rctx->draw, state); -} - -static void *r600_create_sampler_state(struct pipe_context *ctx, - const struct pipe_sampler_state *state) -{ - return NULL; -} - -static void r600_bind_sampler_states(struct pipe_context *ctx, - unsigned count, void **states) -{ -} - -static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx, - struct pipe_resource *texture, - const struct pipe_sampler_view *templ) -{ - struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); - - *view = *templ; - return view; -} - -static void r600_sampler_view_destroy(struct pipe_context *ctx, - struct pipe_sampler_view *view) -{ - FREE(view); -} - -static void r600_set_fragment_sampler_views(struct pipe_context *ctx, - unsigned count, - struct pipe_sampler_view **views) -{ -} - -static void r600_set_vertex_sampler_views(struct pipe_context *ctx, - unsigned count, - struct pipe_sampler_view **views) -{ -} - -static void r600_set_scissor_state(struct pipe_context *ctx, - const struct pipe_scissor_state *state) -{ - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_context *rctx = r600_context(ctx); + const struct pipe_scissor_state *state = &rctx->scissor->state.scissor; + const struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; + struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; + unsigned minx, maxx, miny, maxy; u32 tl, br; - tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | S_028240_WINDOW_OFFSET_DISABLE(1); - br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy); + if (state == NULL) { + minx = 0; + miny = 0; + maxx = fb->cbufs[0]->width; + maxy = fb->cbufs[0]->height; + } else { + minx = state->minx; + miny = state->miny; + maxx = state->maxx; + maxy = state->maxy; + } + tl = S_028240_TL_X(minx) | S_028240_TL_Y(miny) | S_028240_WINDOW_OFFSET_DISABLE(1); + br = S_028244_BR_X(maxx) | S_028244_BR_Y(maxy); rstate = radeon_state(rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR); if (rstate == NULL) - return; + return NULL; rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL] = tl; rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR] = br; rstate->states[R600_SCISSOR__PA_SC_WINDOW_OFFSET] = 0x00000000; @@ -297,97 +905,104 @@ static void r600_set_scissor_state(struct pipe_context *ctx, rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR] = br; if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); - return; + return NULL; } - radeon_draw_set_new(rctx->draw, rstate); + return rstate; } -static void r600_set_viewport_state(struct pipe_context *ctx, - const struct pipe_viewport_state *state) +static struct radeon_state *r600_viewport(struct r600_context *rctx) { - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_context *rctx = r600_context(ctx); + const struct pipe_viewport_state *state = &rctx->viewport->state.viewport; + struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; rstate = radeon_state(rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT); if (rstate == NULL) - return; + return NULL; rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMIN_0] = 0x00000000; rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMAX_0] = 0x3F800000; - rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = r600_float_to_u32(state->scale[0]); - rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = r600_float_to_u32(state->scale[1]); - rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = r600_float_to_u32(state->scale[2]); - rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = r600_float_to_u32(state->translate[0]); - rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = r600_float_to_u32(state->translate[1]); - rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = r600_float_to_u32(state->translate[2]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = fui(state->scale[0]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = fui(state->scale[1]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = fui(state->scale[2]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = fui(state->translate[0]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = fui(state->translate[1]); + rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = fui(state->translate[2]); rstate->states[R600_VIEWPORT__PA_CL_VTE_CNTL] = 0x0000043F; if (radeon_state_pm4(rstate)) { radeon_state_decref(rstate); - return; + return NULL; } - radeon_draw_set_new(rctx->draw, rstate); - rctx->viewport = *state; -} - -static void r600_set_vertex_buffers(struct pipe_context *ctx, - unsigned count, - const struct pipe_vertex_buffer *buffers) -{ - struct r600_context *rctx = r600_context(ctx); - - memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count); - rctx->nvertex_buffer = count; + return rstate; } - -static void *r600_create_vertex_elements_state(struct pipe_context *ctx, - unsigned count, - const struct pipe_vertex_element *elements) +static struct radeon_state *r600_dsa(struct r600_context *rctx) { - struct r600_vertex_elements_state *v = CALLOC_STRUCT(r600_vertex_elements_state); + const struct pipe_depth_stencil_alpha_state *state = &rctx->dsa->state.dsa; + const struct pipe_stencil_ref *stencil_ref = &rctx->stencil_ref->state.stencil_ref; + struct r600_screen *rscreen = rctx->screen; + unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; + unsigned stencil_ref_mask, stencil_ref_mask_bf; + struct r600_shader *rshader = &rctx->ps_shader->shader; + struct radeon_state *rstate; + int i; - assert(count < 32); - v->count = count; - memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element)); - return v; -} + rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA); + if (rstate == NULL) + return NULL; -static void r600_bind_vertex_elements_state(struct pipe_context *ctx, void *state) -{ - struct r600_context *rctx = r600_context(ctx); - struct r600_vertex_elements_state *v = (struct r600_vertex_elements_state*)state; + db_shader_control = 0x210; + for (i = 0; i < rshader->noutput; i++) { + if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) + db_shader_control |= 1; + } + stencil_ref_mask = 0; + stencil_ref_mask_bf = 0; + db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) | + S_028800_Z_WRITE_ENABLE(state->depth.writemask) | + S_028800_ZFUNC(state->depth.func); + /* set stencil enable */ - rctx->vertex_elements = v; -} + if (state->stencil[0].enabled) { + db_depth_control |= S_028800_STENCIL_ENABLE(1); + db_depth_control |= S_028800_STENCILFUNC(r600_translate_ds_func(state->stencil[0].func)); + db_depth_control |= S_028800_STENCILFAIL(r600_translate_stencil_op(state->stencil[0].fail_op)); + db_depth_control |= S_028800_STENCILZPASS(r600_translate_stencil_op(state->stencil[0].zpass_op)); + db_depth_control |= S_028800_STENCILZFAIL(r600_translate_stencil_op(state->stencil[0].zfail_op)); -static void r600_delete_vertex_elements_state(struct pipe_context *ctx, void *state) -{ - FREE(state); -} + stencil_ref_mask = S_028430_STENCILMASK(state->stencil[0].valuemask) | + S_028430_STENCILWRITEMASK(state->stencil[0].writemask); + stencil_ref_mask |= S_028430_STENCILREF(stencil_ref->ref_value[0]); + if (state->stencil[1].enabled) { + db_depth_control |= S_028800_BACKFACE_ENABLE(1); + db_depth_control |= S_028800_STENCILFUNC_BF(r600_translate_ds_func(state->stencil[1].func)); + db_depth_control |= S_028800_STENCILFAIL_BF(r600_translate_stencil_op(state->stencil[1].fail_op)); + db_depth_control |= S_028800_STENCILZPASS_BF(r600_translate_stencil_op(state->stencil[1].zpass_op)); + db_depth_control |= S_028800_STENCILZFAIL_BF(r600_translate_stencil_op(state->stencil[1].zfail_op)); + stencil_ref_mask_bf = S_028434_STENCILMASK_BF(state->stencil[1].valuemask) | + S_028434_STENCILWRITEMASK_BF(state->stencil[1].writemask); + stencil_ref_mask_bf |= S_028430_STENCILREF(stencil_ref->ref_value[1]); + } + } -static void *r600_create_dsa_state(struct pipe_context *ctx, - const struct pipe_depth_stencil_alpha_state *state) -{ - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct radeon_state *rstate; - unsigned db_depth_control; + alpha_test_control = 0; + alpha_ref = 0; + if (state->alpha.enabled) { + alpha_test_control = S_028410_ALPHA_FUNC(state->alpha.func); + alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); + alpha_ref = fui(state->alpha.ref_value); + } - rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA); - if (rstate == NULL) - return NULL; - db_depth_control = 0x00700700 | S_028800_Z_ENABLE(state->depth.enabled) | S_028800_Z_WRITE_ENABLE(state->depth.writemask) | S_028800_ZFUNC(state->depth.func); - rstate->states[R600_DSA__DB_STENCIL_CLEAR] = 0x00000000; rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000; - rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = 0x00000000; - rstate->states[R600_DSA__DB_STENCILREFMASK] = 0xFFFFFF00; - rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = 0xFFFFFF00; - rstate->states[R600_DSA__SX_ALPHA_REF] = 0x00000000; + rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = alpha_test_control; + rstate->states[R600_DSA__DB_STENCILREFMASK] = stencil_ref_mask; + rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = stencil_ref_mask_bf; + rstate->states[R600_DSA__SX_ALPHA_REF] = alpha_ref; rstate->states[R600_DSA__SPI_FOG_FUNC_SCALE] = 0x00000000; rstate->states[R600_DSA__SPI_FOG_FUNC_BIAS] = 0x00000000; rstate->states[R600_DSA__SPI_FOG_CNTL] = 0x00000000; rstate->states[R600_DSA__DB_DEPTH_CONTROL] = db_depth_control; - rstate->states[R600_DSA__DB_SHADER_CONTROL] = 0x00000210; + rstate->states[R600_DSA__DB_SHADER_CONTROL] = db_shader_control; rstate->states[R600_DSA__DB_RENDER_CONTROL] = 0x00000060; rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A; rstate->states[R600_DSA__DB_SRESULTS_COMPARE_STATE1] = 0x00000000; @@ -400,105 +1015,390 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, return rstate; } -static void r600_bind_dsa_state(struct pipe_context *ctx, void *state) +static inline unsigned r600_tex_wrap(unsigned wrap) { - struct r600_context *rctx = r600_context(ctx); - radeon_draw_set(rctx->draw, state); + switch (wrap) { + default: + case PIPE_TEX_WRAP_REPEAT: + return V_03C000_SQ_TEX_WRAP; + case PIPE_TEX_WRAP_CLAMP: + return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return V_03C000_SQ_TEX_CLAMP_HALF_BORDER; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return V_03C000_SQ_TEX_CLAMP_BORDER; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + return V_03C000_SQ_TEX_MIRROR; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER; + } } -static void r600_set_constant_buffer(struct pipe_context *ctx, - uint shader, uint index, - struct pipe_resource *buffer) +static inline unsigned r600_tex_filter(unsigned filter) { - struct r600_screen *rscreen = r600_screen(ctx->screen); - struct r600_context *rctx = r600_context(ctx); - unsigned nconstant = 0, i, type, id; + switch (filter) { + default: + case PIPE_TEX_FILTER_NEAREST: + return V_03C000_SQ_TEX_XY_FILTER_POINT; + case PIPE_TEX_FILTER_LINEAR: + return V_03C000_SQ_TEX_XY_FILTER_BILINEAR; + } +} + +static inline unsigned r600_tex_mipfilter(unsigned filter) +{ + switch (filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + return V_03C000_SQ_TEX_Z_FILTER_POINT; + case PIPE_TEX_MIPFILTER_LINEAR: + return V_03C000_SQ_TEX_Z_FILTER_LINEAR; + default: + case PIPE_TEX_MIPFILTER_NONE: + return V_03C000_SQ_TEX_Z_FILTER_NONE; + } +} + +static inline unsigned r600_tex_compare(unsigned compare) +{ + switch (compare) { + default: + case PIPE_FUNC_NEVER: + return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER; + case PIPE_FUNC_LESS: + return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS; + case PIPE_FUNC_EQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL; + case PIPE_FUNC_LEQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL; + case PIPE_FUNC_GREATER: + return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER; + case PIPE_FUNC_NOTEQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL; + case PIPE_FUNC_GEQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL; + case PIPE_FUNC_ALWAYS: + return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS; + } +} + +static INLINE u32 S_FIXED(float value, u32 frac_bits) +{ + return value * (1 << frac_bits); +} + +static struct radeon_state *r600_sampler(struct r600_context *rctx, + const struct pipe_sampler_state *state, + unsigned id) +{ + struct r600_screen *rscreen = rctx->screen; struct radeon_state *rstate; - struct pipe_transfer *transfer; - u32 *ptr; - switch (shader) { - case PIPE_SHADER_VERTEX: - id = R600_VS_CONSTANT; - type = R600_VS_CONSTANT_TYPE; - break; - case PIPE_SHADER_FRAGMENT: - id = R600_PS_CONSTANT; - type = R600_PS_CONSTANT_TYPE; - break; + rstate = radeon_state(rscreen->rw, R600_PS_SAMPLER_TYPE, id); + if (rstate == NULL) + return NULL; + rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD0_0] = + S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) | + S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | + S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) | + S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter)) | + S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter)) | + S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | + S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)); + /* FIXME LOD it depends on texture base level ... */ + rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD1_0] = + S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) | + S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) | + S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)); + rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD2_0] = S_03C008_TYPE(1); + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; +} + +static inline unsigned r600_tex_swizzle(unsigned swizzle) +{ + switch (swizzle) { + case PIPE_SWIZZLE_RED: + return V_038010_SQ_SEL_X; + case PIPE_SWIZZLE_GREEN: + return V_038010_SQ_SEL_Y; + case PIPE_SWIZZLE_BLUE: + return V_038010_SQ_SEL_Z; + case PIPE_SWIZZLE_ALPHA: + return V_038010_SQ_SEL_W; + case PIPE_SWIZZLE_ZERO: + return V_038010_SQ_SEL_0; default: - fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, shader); - return; + case PIPE_SWIZZLE_ONE: + return V_038010_SQ_SEL_1; } - if (buffer && buffer->width0 > 0) { - nconstant = buffer->width0 / 16; - ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer); - if (ptr == NULL) - return; - for (i = 0; i < nconstant; i++) { - rstate = radeon_state(rscreen->rw, type, id + i); - if (rstate == NULL) - return; - rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0]; - rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1]; - rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2]; - rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3]; - if (radeon_state_pm4(rstate)) - return; - if (radeon_draw_set_new(rctx->draw, rstate)) - return; - } - pipe_buffer_unmap(ctx, buffer, transfer); +} + +static inline unsigned r600_format_type(unsigned format_type) +{ + switch (format_type) { + default: + case UTIL_FORMAT_TYPE_UNSIGNED: + return V_038010_SQ_FORMAT_COMP_UNSIGNED; + case UTIL_FORMAT_TYPE_SIGNED: + return V_038010_SQ_FORMAT_COMP_SIGNED; + case UTIL_FORMAT_TYPE_FIXED: + return V_038010_SQ_FORMAT_COMP_UNSIGNED_BIASED; } } -static void r600_set_stencil_ref(struct pipe_context *ctx, - const struct pipe_stencil_ref *sr) +static inline unsigned r600_tex_dim(unsigned dim) { - struct r600_context *rctx = r600_context(ctx); - rctx->stencil_ref = *sr; + switch (dim) { + default: + case PIPE_TEXTURE_1D: + return V_038000_SQ_TEX_DIM_1D; + case PIPE_TEXTURE_2D: + return V_038000_SQ_TEX_DIM_2D; + case PIPE_TEXTURE_3D: + return V_038000_SQ_TEX_DIM_3D; + case PIPE_TEXTURE_CUBE: + return V_038000_SQ_TEX_DIM_CUBEMAP; + } } -static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask) +static struct radeon_state *r600_resource(struct r600_context *rctx, + const struct pipe_sampler_view *view, + unsigned id) { + struct r600_screen *rscreen = rctx->screen; + const struct util_format_description *desc; + struct r600_resource_texture *tmp; + struct r600_resource *rbuffer; + struct radeon_state *rstate; + unsigned format; + uint32_t word4 = 0, yuv_format = 0; + unsigned char swizzle[4]; + + swizzle[0] = view->swizzle_r; + swizzle[1] = view->swizzle_g; + swizzle[2] = view->swizzle_b; + swizzle[3] = view->swizzle_a; + format = r600_translate_texformat(view->texture->format, + swizzle, + &word4, &yuv_format); + if (format == ~0) + return NULL; + desc = util_format_description(view->texture->format); + if (desc == NULL) { + R600_ERR("unknow format %d\n", view->texture->format); + return NULL; + } + rstate = radeon_state(rscreen->rw, R600_PS_RESOURCE_TYPE, id); + if (rstate == NULL) { + return NULL; + } + tmp = (struct r600_resource_texture*)view->texture; + rbuffer = &tmp->resource; + rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); + rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo); + rstate->nbo = 2; + rstate->placement[0] = RADEON_GEM_DOMAIN_GTT; + rstate->placement[1] = RADEON_GEM_DOMAIN_GTT; + rstate->placement[2] = RADEON_GEM_DOMAIN_GTT; + rstate->placement[3] = RADEON_GEM_DOMAIN_GTT; + + /* FIXME properly handle first level != 0 */ + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD0] = + S_038000_DIM(r600_tex_dim(view->texture->target)) | + S_038000_PITCH(((tmp->pitch[0] / tmp->bpt) / 8) - 1) | + S_038000_TEX_WIDTH(view->texture->width0 - 1); + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD1] = + S_038004_TEX_HEIGHT(view->texture->height0 - 1) | + S_038004_TEX_DEPTH(view->texture->depth0 - 1) | + S_038004_DATA_FORMAT(format); + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = 0; + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = tmp->offset[1] >> 8; + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD4] = + word4 | + S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_NORM) | + S_038010_SRF_MODE_ALL(V_038010_SFR_MODE_NO_ZERO) | + S_038010_REQUEST_SIZE(1) | + S_038010_BASE_LEVEL(view->first_level); + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD5] = + S_038014_LAST_LEVEL(view->last_level) | + S_038014_BASE_ARRAY(0) | + S_038014_LAST_ARRAY(0); + rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD6] = + S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE); + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; } -void r600_init_state_functions(struct r600_context *rctx) +static struct radeon_state *r600_cb_cntl(struct r600_context *rctx) { - rctx->context.set_sample_mask = r600_set_sample_mask; - rctx->context.create_blend_state = r600_create_blend_state; - rctx->context.bind_blend_state = r600_bind_blend_state; - rctx->context.delete_blend_state = r600_delete_state; - rctx->context.set_blend_color = r600_set_blend_color; - rctx->context.set_clip_state = r600_set_clip_state; - rctx->context.set_constant_buffer = r600_set_constant_buffer; - rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state; - rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; - rctx->context.delete_depth_stencil_alpha_state = r600_delete_state; - rctx->context.set_framebuffer_state = r600_set_framebuffer_state; - rctx->context.create_fs_state = r600_create_fs_state; - rctx->context.bind_fs_state = r600_bind_fs_state; - rctx->context.delete_fs_state = r600_delete_state; - rctx->context.set_polygon_stipple = r600_set_polygon_stipple; - rctx->context.create_rasterizer_state = r600_create_rs_state; - rctx->context.bind_rasterizer_state = r600_bind_rs_state; - rctx->context.delete_rasterizer_state = r600_delete_state; - rctx->context.create_sampler_state = r600_create_sampler_state; - rctx->context.bind_fragment_sampler_states = r600_bind_sampler_states; - rctx->context.bind_vertex_sampler_states = r600_bind_sampler_states; - rctx->context.delete_sampler_state = r600_delete_state; - rctx->context.create_sampler_view = r600_create_sampler_view; - rctx->context.sampler_view_destroy = r600_sampler_view_destroy; - rctx->context.set_fragment_sampler_views = r600_set_fragment_sampler_views; - rctx->context.set_vertex_sampler_views = r600_set_vertex_sampler_views; - rctx->context.set_scissor_state = r600_set_scissor_state; - rctx->context.set_viewport_state = r600_set_viewport_state; - rctx->context.set_vertex_buffers = r600_set_vertex_buffers; - rctx->context.create_vertex_elements_state = r600_create_vertex_elements_state; - rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements_state; - rctx->context.delete_vertex_elements_state = r600_delete_vertex_elements_state; - rctx->context.create_vs_state = r600_create_vs_state; - rctx->context.bind_vs_state = r600_bind_vs_state; - rctx->context.delete_vs_state = r600_delete_state; - rctx->context.set_stencil_ref = r600_set_stencil_ref; + struct r600_screen *rscreen = rctx->screen; + struct radeon_state *rstate; + const struct pipe_blend_state *pbs = &rctx->blend->state.blend; + int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs; + uint32_t color_control, target_mask, shader_mask; + int i; + + target_mask = 0; + shader_mask = 0; + color_control = S_028808_PER_MRT_BLEND(1); + + for (i = 0; i < nr_cbufs; i++) { + shader_mask |= 0xf << (i * 4); + } + + if (pbs->logicop_enable) { + color_control |= (pbs->logicop_func) << 16; + } else { + color_control |= (0xcc << 16); + } + + if (pbs->independent_blend_enable) { + for (i = 0; i < nr_cbufs; i++) { + if (pbs->rt[i].blend_enable) { + color_control |= S_028808_TARGET_BLEND_ENABLE(1 << i); + } + target_mask |= (pbs->rt[i].colormask << (4 * i)); + } + } else { + for (i = 0; i < nr_cbufs; i++) { + if (pbs->rt[0].blend_enable) { + color_control |= S_028808_TARGET_BLEND_ENABLE(1 << i); + } + target_mask |= (pbs->rt[0].colormask << (4 * i)); + } + } + rstate = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL); + rstate->states[R600_CB_CNTL__CB_SHADER_MASK] = shader_mask; + rstate->states[R600_CB_CNTL__CB_TARGET_MASK] = target_mask; + rstate->states[R600_CB_CNTL__CB_COLOR_CONTROL] = color_control; + rstate->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000; + rstate->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000; + rstate->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000; + rstate->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000; + rstate->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000; + rstate->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF; + rstate->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF; + rstate->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF; + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; +} + +int r600_context_hw_states(struct r600_context *rctx) +{ + unsigned i; + int r; + int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs; + + /* free previous TODO determine what need to be updated, what + * doesn't + */ + //radeon_state_decref(rctx->hw_states.config); + rctx->hw_states.cb_cntl = radeon_state_decref(rctx->hw_states.cb_cntl); + rctx->hw_states.db = radeon_state_decref(rctx->hw_states.db); + rctx->hw_states.rasterizer = radeon_state_decref(rctx->hw_states.rasterizer); + rctx->hw_states.scissor = radeon_state_decref(rctx->hw_states.scissor); + rctx->hw_states.dsa = radeon_state_decref(rctx->hw_states.dsa); + rctx->hw_states.blend = radeon_state_decref(rctx->hw_states.blend); + rctx->hw_states.viewport = radeon_state_decref(rctx->hw_states.viewport); + for (i = 0; i < 8; i++) { + rctx->hw_states.cb[i] = radeon_state_decref(rctx->hw_states.cb[i]); + } + for (i = 0; i < rctx->hw_states.ps_nresource; i++) { + radeon_state_decref(rctx->hw_states.ps_resource[i]); + rctx->hw_states.ps_resource[i] = NULL; + } + rctx->hw_states.ps_nresource = 0; + for (i = 0; i < rctx->hw_states.ps_nsampler; i++) { + radeon_state_decref(rctx->hw_states.ps_sampler[i]); + rctx->hw_states.ps_sampler[i] = NULL; + } + rctx->hw_states.ps_nsampler = 0; + + /* build new states */ + rctx->hw_states.rasterizer = r600_rasterizer(rctx); + rctx->hw_states.scissor = r600_scissor(rctx); + rctx->hw_states.dsa = r600_dsa(rctx); + rctx->hw_states.blend = r600_blend(rctx); + rctx->hw_states.viewport = r600_viewport(rctx); + for (i = 0; i < nr_cbufs; i++) { + rctx->hw_states.cb[i] = r600_cb(rctx, i); + } + rctx->hw_states.db = r600_db(rctx); + rctx->hw_states.cb_cntl = r600_cb_cntl(rctx); + + for (i = 0; i < rctx->ps_nsampler; i++) { + if (rctx->ps_sampler[i]) { + rctx->hw_states.ps_sampler[i] = r600_sampler(rctx, + &rctx->ps_sampler[i]->state.sampler, + R600_PS_SAMPLER + i); + } + } + rctx->hw_states.ps_nsampler = rctx->ps_nsampler; + for (i = 0; i < rctx->ps_nsampler_view; i++) { + if (rctx->ps_sampler_view[i]) { + rctx->hw_states.ps_resource[i] = r600_resource(rctx, + &rctx->ps_sampler_view[i]->state.sampler_view, + R600_PS_RESOURCE + i); + } + } + rctx->hw_states.ps_nresource = rctx->ps_nsampler_view; + + /* bind states */ + r = radeon_draw_set(rctx->draw, rctx->hw_states.db); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.rasterizer); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.scissor); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.dsa); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.blend); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.viewport); + if (r) + return r; + for (i = 0; i < nr_cbufs; i++) { + r = radeon_draw_set(rctx->draw, rctx->hw_states.cb[i]); + if (r) + return r; + } + r = radeon_draw_set(rctx->draw, rctx->hw_states.config); + if (r) + return r; + r = radeon_draw_set(rctx->draw, rctx->hw_states.cb_cntl); + if (r) + return r; + for (i = 0; i < rctx->hw_states.ps_nresource; i++) { + if (rctx->hw_states.ps_resource[i]) { + r = radeon_draw_set(rctx->draw, rctx->hw_states.ps_resource[i]); + if (r) + return r; + } + } + for (i = 0; i < rctx->hw_states.ps_nsampler; i++) { + if (rctx->hw_states.ps_sampler[i]) { + r = radeon_draw_set(rctx->draw, rctx->hw_states.ps_sampler[i]); + if (r) + return r; + } + } + return 0; } diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h new file mode 100644 index 00000000000..f93c20da35e --- /dev/null +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -0,0 +1,311 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef R600_STATE_INLINES_H +#define R600_STATE_INLINES_H + +#include "util/u_format.h" +#include "r600d.h" + +static INLINE uint32_t r600_translate_blend_function(int blend_func) +{ + switch (blend_func) { + case PIPE_BLEND_ADD: + return V_028804_COMB_DST_PLUS_SRC; + case PIPE_BLEND_SUBTRACT: + return V_028804_COMB_SRC_MINUS_DST; + case PIPE_BLEND_REVERSE_SUBTRACT: + return V_028804_COMB_DST_MINUS_SRC; + case PIPE_BLEND_MIN: + return V_028804_COMB_MIN_DST_SRC; + case PIPE_BLEND_MAX: + return V_028804_COMB_MAX_DST_SRC; + default: + R600_ERR("Unknown blend function %d\n", blend_func); + assert(0); + break; + } + return 0; +} + +static INLINE uint32_t r600_translate_blend_factor(int blend_fact) +{ + switch (blend_fact) { + case PIPE_BLENDFACTOR_ONE: + return V_028804_BLEND_ONE; + case PIPE_BLENDFACTOR_SRC_COLOR: + return V_028804_BLEND_SRC_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA: + return V_028804_BLEND_SRC_ALPHA; + case PIPE_BLENDFACTOR_DST_ALPHA: + return V_028804_BLEND_DST_ALPHA; + case PIPE_BLENDFACTOR_DST_COLOR: + return V_028804_BLEND_DST_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: + return V_028804_BLEND_SRC_ALPHA_SATURATE; + case PIPE_BLENDFACTOR_CONST_COLOR: + return V_028804_BLEND_CONST_COLOR; + case PIPE_BLENDFACTOR_CONST_ALPHA: + return V_028804_BLEND_CONST_ALPHA; + case PIPE_BLENDFACTOR_ZERO: + return V_028804_BLEND_ZERO; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: + return V_028804_BLEND_ONE_MINUS_SRC_COLOR; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: + return V_028804_BLEND_ONE_MINUS_SRC_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: + return V_028804_BLEND_ONE_MINUS_DST_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_COLOR: + return V_028804_BLEND_ONE_MINUS_DST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: + return V_028804_BLEND_ONE_MINUS_CONST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: + return V_028804_BLEND_ONE_MINUS_CONST_ALPHA; + case PIPE_BLENDFACTOR_SRC1_COLOR: + return V_028804_BLEND_SRC1_COLOR; + case PIPE_BLENDFACTOR_SRC1_ALPHA: + return V_028804_BLEND_SRC1_ALPHA; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + return V_028804_BLEND_INV_SRC1_COLOR; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + return V_028804_BLEND_INV_SRC1_ALPHA; + default: + R600_ERR("Bad blend factor %d not supported!\n", blend_fact); + assert(0); + break; + } + return 0; +} + +static INLINE uint32_t r600_translate_stencil_op(int s_op) +{ + switch (s_op) { + case PIPE_STENCIL_OP_KEEP: + return V_028800_STENCIL_KEEP; + case PIPE_STENCIL_OP_ZERO: + return V_028800_STENCIL_ZERO; + case PIPE_STENCIL_OP_REPLACE: + return V_028800_STENCIL_REPLACE; + case PIPE_STENCIL_OP_INCR: + return V_028800_STENCIL_INCR; + case PIPE_STENCIL_OP_DECR: + return V_028800_STENCIL_DECR; + case PIPE_STENCIL_OP_INCR_WRAP: + return V_028800_STENCIL_INCR_WRAP; + case PIPE_STENCIL_OP_DECR_WRAP: + return V_028800_STENCIL_DECR_WRAP; + case PIPE_STENCIL_OP_INVERT: + return V_028800_STENCIL_INVERT; + default: + R600_ERR("Unknown stencil op %d", s_op); + assert(0); + break; + } + return 0; +} + +/* translates straight */ +static INLINE uint32_t r600_translate_ds_func(int func) +{ + return func; +} + +static uint32_t r600_translate_dbformat(enum pipe_format format) +{ + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + return V_028010_DEPTH_16; + case PIPE_FORMAT_Z24X8_UNORM: + return V_028010_DEPTH_X8_24; + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + return V_028010_DEPTH_8_24; + default: + return ~0; + } +} + +static uint32_t r600_translate_colorswap(enum pipe_format format) +{ + switch (format) { + /* 8-bit buffers. */ + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8_SNORM: + return V_0280A0_SWAP_STD; + + /* 16-bit buffers. */ + case PIPE_FORMAT_B5G6R5_UNORM: + return V_0280A0_SWAP_STD_REV; + + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_B5G5R5X1_UNORM: + return V_0280A0_SWAP_ALT; + + case PIPE_FORMAT_B4G4R4A4_UNORM: + case PIPE_FORMAT_B4G4R4X4_UNORM: + return V_0280A0_SWAP_ALT; + /* 32-bit buffers. */ + + case PIPE_FORMAT_A8B8G8R8_SRGB: + return V_0280A0_SWAP_STD_REV; + case PIPE_FORMAT_B8G8R8A8_SRGB: + return V_0280A0_SWAP_ALT; + + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8X8_UNORM: + return V_0280A0_SWAP_ALT; + + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_X8R8G8B8_UNORM: + return V_0280A0_SWAP_ALT_REV; + case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R8G8B8X8_UNORM: + return V_0280A0_SWAP_STD; + + case PIPE_FORMAT_A8B8G8R8_UNORM: + case PIPE_FORMAT_X8B8G8R8_UNORM: + // case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + return V_0280A0_SWAP_STD_REV; + + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + return V_0280A0_SWAP_STD; + + case PIPE_FORMAT_R10G10B10A2_UNORM: + case PIPE_FORMAT_R10G10B10X2_SNORM: + case PIPE_FORMAT_B10G10R10A2_UNORM: + case PIPE_FORMAT_R10SG10SB10SA2U_NORM: + return V_0280A0_SWAP_STD_REV; + + /* 64-bit buffers. */ + case PIPE_FORMAT_R16G16B16A16_UNORM: + case PIPE_FORMAT_R16G16B16A16_SNORM: + // return V_0280A0_COLOR_16_16_16_16; + case PIPE_FORMAT_R16G16B16A16_FLOAT: + // return V_0280A0_COLOR_16_16_16_16_FLOAT; + + /* 128-bit buffers. */ + case PIPE_FORMAT_R32G32B32A32_FLOAT: + // return V_0280A0_COLOR_32_32_32_32_FLOAT; + return 0; + default: + R600_ERR("unsupported colorswap format %d\n", format); + return ~0; + } + return ~0; +} + +static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) +{ + switch (format) { + /* 8-bit buffers. */ + case PIPE_FORMAT_A8_UNORM: + case PIPE_FORMAT_I8_UNORM: + case PIPE_FORMAT_L8_UNORM: + case PIPE_FORMAT_R8_UNORM: + case PIPE_FORMAT_R8_SNORM: + return V_0280A0_COLOR_8; + + /* 16-bit buffers. */ + case PIPE_FORMAT_B5G6R5_UNORM: + return V_0280A0_COLOR_5_6_5; + + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_B5G5R5X1_UNORM: + return V_0280A0_COLOR_1_5_5_5; + + case PIPE_FORMAT_B4G4R4A4_UNORM: + case PIPE_FORMAT_B4G4R4X4_UNORM: + return V_0280A0_COLOR_4_4_4_4; + + /* 32-bit buffers. */ + case PIPE_FORMAT_A8B8G8R8_SRGB: + case PIPE_FORMAT_A8B8G8R8_UNORM: + case PIPE_FORMAT_A8R8G8B8_UNORM: + case PIPE_FORMAT_B8G8R8A8_SRGB: + case PIPE_FORMAT_B8G8R8A8_UNORM: + case PIPE_FORMAT_B8G8R8X8_UNORM: + case PIPE_FORMAT_R8G8B8A8_SNORM: + case PIPE_FORMAT_R8G8B8A8_UNORM: + case PIPE_FORMAT_R8G8B8X8_UNORM: + case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + case PIPE_FORMAT_X8B8G8R8_UNORM: + case PIPE_FORMAT_X8R8G8B8_UNORM: + return V_0280A0_COLOR_8_8_8_8; + + case PIPE_FORMAT_R10G10B10A2_UNORM: + case PIPE_FORMAT_R10G10B10X2_SNORM: + case PIPE_FORMAT_B10G10R10A2_UNORM: + case PIPE_FORMAT_R10SG10SB10SA2U_NORM: + return V_0280A0_COLOR_10_10_10_2; + + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + return V_0280A0_COLOR_24_8; + + /* 64-bit buffers. */ + case PIPE_FORMAT_R16G16B16A16_UNORM: + case PIPE_FORMAT_R16G16B16A16_SNORM: + return V_0280A0_COLOR_16_16_16_16; + case PIPE_FORMAT_R16G16B16A16_FLOAT: + return V_0280A0_COLOR_16_16_16_16_FLOAT; + case PIPE_FORMAT_R32G32_FLOAT: + return V_0280A0_COLOR_32_32_FLOAT; + + /* 128-bit buffers. */ + case PIPE_FORMAT_R32G32B32_FLOAT: + case PIPE_FORMAT_R32G32B32A32_FLOAT: + return V_0280A0_COLOR_32_32_32_32_FLOAT; + + /* YUV buffers. */ + case PIPE_FORMAT_UYVY: + case PIPE_FORMAT_YUYV: + default: + R600_ERR("unsupported color format %d\n", format); + return ~0; /* Unsupported. */ + } +} + +static INLINE boolean r600_is_sampler_format_supported(enum pipe_format format) +{ + return r600_translate_texformat(format, NULL, NULL, NULL) != ~0; +} + +static INLINE boolean r600_is_colorbuffer_format_supported(enum pipe_format format) +{ + return r600_translate_colorformat(format) != ~0 && + r600_translate_colorswap(format) != ~0; +} + +static INLINE boolean r600_is_zs_format_supported(enum pipe_format format) +{ + return r600_translate_dbformat(format) != ~0; +} + +static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format) +{ + return r600_translate_colorformat(format) != ~0; +} + +#endif diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 903cfad80a8..30d79ebdd6f 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -31,15 +31,19 @@ #include <util/u_memory.h> #include "state_tracker/drm_driver.h" #include "r600_screen.h" -#include "r600_texture.h" +#include "r600_context.h" +#include "r600_resource.h" +#include "r600d.h" extern struct u_resource_vtbl r600_texture_vtbl; -unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face) +static unsigned long r600_texture_get_offset(struct r600_resource_texture *rtex, + unsigned level, unsigned zslice, + unsigned face) { unsigned long offset = rtex->offset[level]; - switch (rtex->b.b.target) { + switch (rtex->resource.base.b.target) { case PIPE_TEXTURE_3D: assert(face == 0); return offset + zslice * rtex->layer_size[level]; @@ -52,67 +56,68 @@ unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, } } -static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_texture *rtex) +static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_resource_texture *rtex) { - struct pipe_resource *ptex = &rtex->b.b; - unsigned long w, h, stride, size, layer_size, i, offset; + struct pipe_resource *ptex = &rtex->resource.base.b; + unsigned long w, h, pitch, size, layer_size, i, offset; + rtex->bpt = util_format_get_blocksize(ptex->format); for (i = 0, offset = 0; i <= ptex->last_level; i++) { w = u_minify(ptex->width0, i); h = u_minify(ptex->height0, i); - stride = align(util_format_get_stride(ptex->format, w), 32); - layer_size = stride * h; + pitch = util_format_get_stride(ptex->format, align(w, 64)); + layer_size = pitch * h; if (ptex->target == PIPE_TEXTURE_CUBE) size = layer_size * 6; else size = layer_size * u_minify(ptex->depth0, i); rtex->offset[i] = offset; rtex->layer_size[i] = layer_size; - rtex->pitch[i] = stride / util_format_get_blocksize(ptex->format); - rtex->stride[i] = stride; - offset += align(size, 32); + rtex->pitch[i] = pitch; + offset += size; } rtex->size = offset; } struct pipe_resource *r600_texture_create(struct pipe_screen *screen, - const struct pipe_resource *templ) + const struct pipe_resource *templ) { - struct r600_texture *rtex = CALLOC_STRUCT(r600_texture); + struct r600_resource_texture *rtex; + struct r600_resource *resource; struct r600_screen *rscreen = r600_screen(screen); - struct pipe_resource templ_buf; + rtex = CALLOC_STRUCT(r600_resource_texture); if (!rtex) { return NULL; } - rtex->b.b = *templ; - rtex->b.vtbl = &r600_texture_vtbl; - pipe_reference_init(&rtex->b.b.reference, 1); - rtex->b.b.screen = screen; + resource = &rtex->resource; + resource->base.b = *templ; + resource->base.vtbl = &r600_texture_vtbl; + pipe_reference_init(&resource->base.b.reference, 1); + resource->base.b.screen = screen; r600_setup_miptree(rscreen, rtex); - memset(&templ_buf, 0, sizeof(struct pipe_resource)); - templ_buf.target = PIPE_BUFFER; - templ_buf.format = PIPE_FORMAT_R8_UNORM; - templ_buf.usage = templ->usage; - templ_buf.bind = templ->bind; - templ_buf.width0 = rtex->size; - templ_buf.height0 = 1; - templ_buf.depth0 = 1; - - rtex->buffer = screen->resource_create(screen, &templ_buf); - if (!rtex->buffer) { + /* FIXME alignment 4096 enought ? too much ? */ + resource->domain = r600_domain_from_usage(resource->base.b.bind); + resource->bo = radeon_bo(rscreen->rw, 0, rtex->size, 4096, NULL); + if (resource->bo == NULL) { FREE(rtex); return NULL; } - return &rtex->b.b; + + return &resource->base.b; } static void r600_texture_destroy(struct pipe_screen *screen, struct pipe_resource *ptex) { - struct r600_texture *rtex = (struct r600_texture*)ptex; + struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex; + struct r600_resource *resource = &rtex->resource; + struct r600_screen *rscreen = r600_screen(screen); + if (resource->bo) { + radeon_bo_decref(rscreen->rw, resource->bo); + } FREE(rtex); } @@ -121,7 +126,7 @@ static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen, unsigned face, unsigned level, unsigned zslice, unsigned flags) { - struct r600_texture *rtex = (struct r600_texture*)texture; + struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); unsigned long offset; @@ -149,71 +154,115 @@ static void r600_tex_surface_destroy(struct pipe_surface *surface) } struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, - const struct pipe_resource *base, + const struct pipe_resource *templ, struct winsys_handle *whandle) { - struct pipe_resource *buffer; - struct r600_texture *rtex; + struct radeon *rw = (struct radeon*)screen->winsys; + struct r600_resource_texture *rtex; + struct r600_resource *resource; + struct radeon_bo *bo = NULL; - buffer = r600_buffer_from_handle(screen, whandle); - if (buffer == NULL) { + bo = radeon_bo(rw, whandle->handle, 0, 0, NULL); + if (bo == NULL) { return NULL; } /* Support only 2D textures without mipmaps */ - if (base->target != PIPE_TEXTURE_2D || base->depth0 != 1 || base->last_level != 0) + if (templ->target != PIPE_TEXTURE_2D || templ->depth0 != 1 || templ->last_level != 0) return NULL; - rtex = CALLOC_STRUCT(r600_texture); + rtex = CALLOC_STRUCT(r600_resource_texture); if (rtex == NULL) return NULL; - /* one ref already taken */ - rtex->buffer = buffer; - - rtex->b.b = *base; - rtex->b.vtbl = &r600_texture_vtbl; - pipe_reference_init(&rtex->b.b.reference, 1); - rtex->b.b.screen = screen; - rtex->stride_override = whandle->stride; - rtex->pitch[0] = whandle->stride / util_format_get_blocksize(base->format); - rtex->stride[0] = whandle->stride; + resource = &rtex->resource; + resource->base.b = *templ; + resource->base.vtbl = &r600_texture_vtbl; + pipe_reference_init(&resource->base.b.reference, 1); + resource->base.b.screen = screen; + resource->bo = bo; + rtex->pitch_override = whandle->stride; + rtex->bpt = util_format_get_blocksize(templ->format); + rtex->pitch[0] = whandle->stride; rtex->offset[0] = 0; - rtex->size = align(rtex->stride[0] * base->height0, 32); + rtex->size = align(rtex->pitch[0] * templ->height0, 64); - return &rtex->b.b; + return &resource->base.b; } -static boolean r600_texture_get_handle(struct pipe_screen* screen, - struct pipe_resource *texture, - struct winsys_handle *whandle) +static unsigned int r600_texture_is_referenced(struct pipe_context *context, + struct pipe_resource *texture, + unsigned face, unsigned level) { - struct r600_screen *rscreen = r600_screen(screen); - struct r600_texture* rtex = (struct r600_texture*)texture; + /* FIXME */ + return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; +} - if (!rtex) { - return FALSE; - } +struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, + struct pipe_resource *texture, + struct pipe_subresource sr, + unsigned usage, + const struct pipe_box *box) +{ + struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture; + struct r600_transfer *trans; - whandle->stride = rtex->stride[0]; + trans = CALLOC_STRUCT(r600_transfer); + if (trans == NULL) + return NULL; + pipe_resource_reference(&trans->transfer.resource, texture); + trans->transfer.sr = sr; + trans->transfer.usage = usage; + trans->transfer.box = *box; + trans->transfer.stride = rtex->pitch[sr.level]; + trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face); + return &trans->transfer; +} - r600_buffer_get_handle(rscreen->rw, rtex->buffer, whandle); +void r600_texture_transfer_destroy(struct pipe_context *ctx, + struct pipe_transfer *trans) +{ + pipe_resource_reference(&trans->resource, NULL); + FREE(trans); +} - return TRUE; +void* r600_texture_transfer_map(struct pipe_context *ctx, + struct pipe_transfer* transfer) +{ + struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; + struct r600_resource *resource; + enum pipe_format format = transfer->resource->format; + struct r600_screen *rscreen = r600_screen(ctx->screen); + char *map; + + r600_flush(ctx, 0, NULL); + + resource = (struct r600_resource *)transfer->resource; + if (radeon_bo_map(rscreen->rw, resource->bo)) { + return NULL; + } + radeon_bo_wait(rscreen->rw, resource->bo); + + map = resource->bo->data; + + return map + rtransfer->offset + + transfer->box.y / util_format_get_blockheight(format) * transfer->stride + + transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); } -static unsigned int r600_texture_is_referenced(struct pipe_context *context, - struct pipe_resource *texture, - unsigned face, unsigned level) +void r600_texture_transfer_unmap(struct pipe_context *ctx, + struct pipe_transfer* transfer) { - struct r600_texture *rtex = (struct r600_texture*)texture; + struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_resource *resource; - return r600_buffer_is_referenced_by_cs(context, rtex->buffer, face, level); + resource = (struct r600_resource *)transfer->resource; + radeon_bo_unmap(rscreen->rw, resource->bo); } struct u_resource_vtbl r600_texture_vtbl = { - r600_texture_get_handle, /* get_handle */ + u_default_resource_get_handle, /* get_handle */ r600_texture_destroy, /* resource_destroy */ r600_texture_is_referenced, /* is_resource_referenced */ r600_texture_get_transfer, /* get_transfer */ @@ -229,3 +278,250 @@ void r600_init_screen_texture_functions(struct pipe_screen *screen) screen->get_tex_surface = r600_get_tex_surface; screen->tex_surface_destroy = r600_tex_surface_destroy; } + +static unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format, + const unsigned char *swizzle_view) +{ + unsigned i; + unsigned char swizzle[4]; + unsigned result = 0; + const uint32_t swizzle_shift[4] = { + 16, 19, 22, 25, + }; + const uint32_t swizzle_bit[4] = { + 0, 1, 2, 3, + }; + + if (swizzle_view) { + /* Combine two sets of swizzles. */ + for (i = 0; i < 4; i++) { + swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ? + swizzle_format[swizzle_view[i]] : swizzle_view[i]; + } + } else { + memcpy(swizzle, swizzle_format, 4); + } + + /* Get swizzle. */ + for (i = 0; i < 4; i++) { + switch (swizzle[i]) { + case UTIL_FORMAT_SWIZZLE_Y: + result |= swizzle_bit[1] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_Z: + result |= swizzle_bit[2] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_W: + result |= swizzle_bit[3] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_0: + result |= V_038010_SQ_SEL_0 << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_1: + result |= V_038010_SQ_SEL_1 << swizzle_shift[i]; + break; + default: /* UTIL_FORMAT_SWIZZLE_X */ + result |= swizzle_bit[0] << swizzle_shift[i]; + } + } + return result; +} + +/* texture format translate */ +uint32_t r600_translate_texformat(enum pipe_format format, + const unsigned char *swizzle_view, + uint32_t *word4_p, uint32_t *yuv_format_p) +{ + uint32_t result = 0, word4 = 0, yuv_format = 0; + const struct util_format_description *desc; + boolean uniform = TRUE; + int i; + const uint32_t sign_bit[4] = { + S_038010_FORMAT_COMP_X(V_038010_SQ_FORMAT_COMP_SIGNED), + S_038010_FORMAT_COMP_Y(V_038010_SQ_FORMAT_COMP_SIGNED), + S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED), + S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED) + }; + desc = util_format_description(format); + + /* Colorspace (return non-RGB formats directly). */ + switch (desc->colorspace) { + /* Depth stencil formats */ + case UTIL_FORMAT_COLORSPACE_ZS: + switch (format) { + case PIPE_FORMAT_Z16_UNORM: + result = V_028010_DEPTH_16; + goto out_word4; + case PIPE_FORMAT_Z24X8_UNORM: + result = V_028010_DEPTH_X8_24; + goto out_word4; + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + result = V_028010_DEPTH_8_24; + goto out_word4; + default: + goto out_unknown; + } + + case UTIL_FORMAT_COLORSPACE_YUV: + yuv_format |= (1 << 30); + switch (format) { + case PIPE_FORMAT_UYVY: + case PIPE_FORMAT_YUYV: + default: + break; + } + goto out_unknown; /* TODO */ + + case UTIL_FORMAT_COLORSPACE_SRGB: + word4 |= S_038010_FORCE_DEGAMMA(1); + if (format == PIPE_FORMAT_L8A8_SRGB || format == PIPE_FORMAT_L8_SRGB) + goto out_unknown; /* fails for some reason - TODO */ + break; + + default: + break; + } + + word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view); + + /* S3TC formats. TODO */ + if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { + goto out_unknown; + } + + + for (i = 0; i < desc->nr_channels; i++) { + if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { + word4 |= sign_bit[i]; + } + } + + /* R8G8Bx_SNORM - TODO CxV8U8 */ + + /* RGTC - TODO */ + + /* See whether the components are of the same size. */ + for (i = 1; i < desc->nr_channels; i++) { + uniform = uniform && desc->channel[0].size == desc->channel[i].size; + } + + /* Non-uniform formats. */ + if (!uniform) { + switch(desc->nr_channels) { + case 3: + if (desc->channel[0].size == 5 && + desc->channel[1].size == 6 && + desc->channel[2].size == 5) { + result |= V_0280A0_COLOR_5_6_5; + goto out_word4; + } + goto out_unknown; + case 4: + if (desc->channel[0].size == 5 && + desc->channel[1].size == 5 && + desc->channel[2].size == 5 && + desc->channel[3].size == 1) { + result |= V_0280A0_COLOR_1_5_5_5; + goto out_word4; + } + if (desc->channel[0].size == 10 && + desc->channel[1].size == 10 && + desc->channel[2].size == 10 && + desc->channel[3].size == 2) { + result |= V_0280A0_COLOR_10_10_10_2; + goto out_word4; + } + goto out_unknown; + } + goto out_unknown; + } + + /* uniform formats */ + switch (desc->channel[0].type) { + case UTIL_FORMAT_TYPE_UNSIGNED: + case UTIL_FORMAT_TYPE_SIGNED: + if (!desc->channel[0].normalized && + desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) { + goto out_unknown; + } + + switch (desc->channel[0].size) { + case 4: + switch (desc->nr_channels) { + case 2: + result |= V_0280A0_COLOR_4_4; + goto out_word4; + case 4: + result |= V_0280A0_COLOR_4_4_4_4; + goto out_word4; + } + goto out_unknown; + case 8: + switch (desc->nr_channels) { + case 1: + result |= V_0280A0_COLOR_8; + goto out_word4; + case 2: + result |= V_0280A0_COLOR_8_8; + goto out_word4; + case 4: + result |= V_0280A0_COLOR_8_8_8_8; + goto out_word4; + } + goto out_unknown; + case 16: + switch (desc->nr_channels) { + case 1: + result |= V_0280A0_COLOR_16; + goto out_word4; + case 2: + result |= V_0280A0_COLOR_16_16; + goto out_word4; + case 4: + result |= V_0280A0_COLOR_16_16_16_16; + goto out_word4; + } + } + goto out_unknown; + + case UTIL_FORMAT_TYPE_FLOAT: + switch (desc->channel[0].size) { + case 16: + switch (desc->nr_channels) { + case 1: + result |= V_0280A0_COLOR_16_FLOAT; + goto out_word4; + case 2: + result |= V_0280A0_COLOR_16_16_FLOAT; + goto out_word4; + case 4: + result |= V_0280A0_COLOR_16_16_16_16_FLOAT; + goto out_word4; + } + goto out_unknown; + case 32: + switch (desc->nr_channels) { + case 1: + result |= V_0280A0_COLOR_32_FLOAT; + goto out_word4; + case 2: + result |= V_0280A0_COLOR_32_32_FLOAT; + goto out_word4; + case 4: + result |= V_0280A0_COLOR_32_32_32_32_FLOAT; + goto out_word4; + } + } + + } +out_word4: + if (word4_p) + *word4_p = word4; + if (yuv_format_p) + *yuv_format_p = yuv_format; +// fprintf(stderr,"returning %08x %08x %08x\n", result, word4, yuv_format); + return result; +out_unknown: +// R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); + return ~0; +} diff --git a/src/gallium/drivers/r600/r600_texture.h b/src/gallium/drivers/r600/r600_texture.h deleted file mode 100644 index 9bc08d6b040..00000000000 --- a/src/gallium/drivers/r600/r600_texture.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse <[email protected]> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef R600_TEXTURE_H -#define R600_TEXTURE_H - -#include <pipe/p_state.h> - -struct r600_texture { - struct u_resource b; - unsigned long offset[PIPE_MAX_TEXTURE_LEVELS]; - unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS]; - unsigned long stride[PIPE_MAX_TEXTURE_LEVELS]; - unsigned long layer_size[PIPE_MAX_TEXTURE_LEVELS]; - unsigned long stride_override; - unsigned long size; - struct pipe_resource *buffer; -}; - -struct pipe_resource *r600_texture_create(struct pipe_screen *screen, - const struct pipe_resource *templ); -unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face); -struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, - const struct pipe_resource *base, - struct winsys_handle *whandle); -void r600_init_screen_texture_functions(struct pipe_screen *screen); - -/* This should be implemented by winsys. */ -boolean r600_buffer_get_handle(struct radeon *rw, - struct pipe_resource *buf, - struct winsys_handle *whandle); - - -#endif diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 44834984c68..53388f822ea 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -26,6 +26,8 @@ #ifndef R600D_H #define R600D_H +#define R600_TEXEL_PITCH_ALIGNMENT_MASK 0x7 + #define PKT3_NOP 0x10 #define PKT3_INDIRECT_BUFFER_END 0x17 #define PKT3_SET_PREDICATION 0x20 @@ -207,12 +209,24 @@ #define S_0280A0_NUMBER_TYPE(x) (((x) & 0x7) << 12) #define G_0280A0_NUMBER_TYPE(x) (((x) >> 12) & 0x7) #define C_0280A0_NUMBER_TYPE 0xFFFF8FFF +#define V_0280A0_NUMBER_UNORM 0x00000000 +#define V_0280A0_NUMBER_SNORM 0x00000001 +#define V_0280A0_NUMBER_USCALED 0x00000002 +#define V_0280A0_NUMBER_SSCALED 0x00000003 +#define V_0280A0_NUMBER_UINT 0x00000004 +#define V_0280A0_NUMBER_SINT 0x00000005 +#define V_0280A0_NUMBER_SRGB 0x00000006 +#define V_0280A0_NUMBER_FLOAT 0x00000007 #define S_0280A0_READ_SIZE(x) (((x) & 0x1) << 15) #define G_0280A0_READ_SIZE(x) (((x) >> 15) & 0x1) #define C_0280A0_READ_SIZE 0xFFFF7FFF #define S_0280A0_COMP_SWAP(x) (((x) & 0x3) << 16) #define G_0280A0_COMP_SWAP(x) (((x) >> 16) & 0x3) #define C_0280A0_COMP_SWAP 0xFFFCFFFF +#define V_0280A0_SWAP_STD 0x00000000 +#define V_0280A0_SWAP_ALT 0x00000001 +#define V_0280A0_SWAP_STD_REV 0x00000002 +#define V_0280A0_SWAP_ALT_REV 0x00000003 #define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18) #define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3) #define C_0280A0_TILE_MODE 0xFFF3FFFF @@ -247,6 +261,16 @@ #define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10) #define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF) #define C_028060_SLICE_TILE_MAX 0xC00003FF +#define R_028410_SX_ALPHA_TEST_CONTROL 0x028410 +#define S_028410_ALPHA_FUNC(x) (((x) & 0x7) << 0) +#define G_028410_ALPHA_FUNC(x) (((x) >> 0) & 0x7) +#define C_028410_ALPHA_FUNC 0xFFFFFFF8 +#define S_028410_ALPHA_TEST_ENABLE(x) (((x) & 0x1) << 3) +#define G_028410_ALPHA_TEST_ENABLE(x) (((x) >> 3) & 0x1) +#define C_028410_ALPHA_TEST_ENABLE 0xFFFFFFF7 +#define S_028410_ALPHA_TEST_BYPASS(x) (((x) & 0x1) << 8) +#define G_028410_ALPHA_TEST_BYPASS(x) (((x) >> 8) & 0x1) +#define C_028410_ALPHA_TEST_BYPASS 0xFFFFFEFF #define R_028800_DB_DEPTH_CONTROL 0x028800 #define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0) #define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1) @@ -266,9 +290,25 @@ #define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8) #define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7) #define C_028800_STENCILFUNC 0xFFFFF8FF +#define V_028800_STENCILFUNC_NEVER 0x00000000 +#define V_028800_STENCILFUNC_LESS 0x00000001 +#define V_028800_STENCILFUNC_EQUAL 0x00000002 +#define V_028800_STENCILFUNC_LEQUAL 0x00000003 +#define V_028800_STENCILFUNC_GREATER 0x00000004 +#define V_028800_STENCILFUNC_NOTEQUAL 0x00000005 +#define V_028800_STENCILFUNC_GEQUAL 0x00000006 +#define V_028800_STENCILFUNC_ALWAYS 0x00000007 #define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11) #define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7) #define C_028800_STENCILFAIL 0xFFFFC7FF +#define V_028800_STENCIL_KEEP 0x00000000 +#define V_028800_STENCIL_ZERO 0x00000001 +#define V_028800_STENCIL_REPLACE 0x00000002 +#define V_028800_STENCIL_INCR 0x00000003 +#define V_028800_STENCIL_DECR 0x00000004 +#define V_028800_STENCIL_INVERT 0x00000005 +#define V_028800_STENCIL_INCR_WRAP 0x00000006 +#define V_028800_STENCIL_DECR_WRAP 0x00000007 #define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14) #define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7) #define C_028800_STENCILZPASS 0xFFFE3FFF @@ -287,6 +327,86 @@ #define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29) #define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7) #define C_028800_STENCILZFAIL_BF 0x1FFFFFFF +#define R_028808_CB_COLOR_CONTROL 0x028808 +#define S_028808_FOG_ENABLE(x) (((x) & 0x1) << 0) +#define G_028808_FOG_ENABLE(x) (((x) >> 0) & 0x1) +#define C_028808_FOG_ENABLE 0xFFFFFFFE +#define S_028808_MULTIWRITE_ENABLE(x) (((x) & 0x1) << 1) +#define G_028808_MULTIWRITE_ENABLE(x) (((x) >> 1) & 0x1) +#define C_028808_MULTIWRITE_ENABLE 0xFFFFFFFD +#define S_028808_DITHER_ENABLE(x) (((x) & 0x1) << 2) +#define G_028808_DITHER_ENABLE(x) (((x) >> 2) & 0x1) +#define C_028808_DITHER_ENABLE 0xFFFFFFFB +#define S_028808_DEGAMMA_ENABLE(x) (((x) & 0x1) << 3) +#define G_028808_DEGAMMA_ENABLE(x) (((x) >> 3) & 0x1) +#define C_028808_DEGAMMA_ENABLE 0xFFFFFFF7 +#define S_028808_SPECIAL_OP(x) (((x) & 0x7) << 4) +#define G_028808_SPECIAL_OP(x) (((x) >> 4) & 0x7) +#define C_028808_SPECIAL_OP 0xFFFFFF8F +#define S_028808_PER_MRT_BLEND(x) (((x) & 0x1) << 7) +#define G_028808_PER_MRT_BLEND(x) (((x) >> 7) & 0x1) +#define C_028808_PER_MRT_BLEND 0xFFFFFF7F +#define S_028808_TARGET_BLEND_ENABLE(x) (((x) & 0xFF) << 8) +#define G_028808_TARGET_BLEND_ENABLE(x) (((x) >> 8) & 0xFF) +#define C_028808_TARGET_BLEND_ENABLE 0xFFFF00FF +#define S_028808_ROP3(x) (((x) & 0xFF) << 16) +#define G_028808_ROP3(x) (((x) >> 16) & 0xFF) +#define C_028808_ROP3 0xFF00FFFF +#define R_028810_PA_CL_CLIP_CNTL 0x028810 +#define S_028810_UCP_ENA_0(x) (((x) & 0x1) << 0) +#define G_028810_UCP_ENA_0(x) (((x) >> 0) & 0x1) +#define C_028810_UCP_ENA_0 0xFFFFFFFE +#define S_028810_UCP_ENA_1(x) (((x) & 0x1) << 1) +#define G_028810_UCP_ENA_1(x) (((x) >> 1) & 0x1) +#define C_028810_UCP_ENA_1 0xFFFFFFFD +#define S_028810_UCP_ENA_2(x) (((x) & 0x1) << 2) +#define G_028810_UCP_ENA_2(x) (((x) >> 2) & 0x1) +#define C_028810_UCP_ENA_2 0xFFFFFFFB +#define S_028810_UCP_ENA_3(x) (((x) & 0x1) << 3) +#define G_028810_UCP_ENA_3(x) (((x) >> 3) & 0x1) +#define C_028810_UCP_ENA_3 0xFFFFFFF7 +#define S_028810_UCP_ENA_4(x) (((x) & 0x1) << 4) +#define G_028810_UCP_ENA_4(x) (((x) >> 4) & 0x1) +#define C_028810_UCP_ENA_4 0xFFFFFFEF +#define S_028810_UCP_ENA_5(x) (((x) & 0x1) << 5) +#define G_028810_UCP_ENA_5(x) (((x) >> 5) & 0x1) +#define C_028810_UCP_ENA_5 0xFFFFFFDF +#define S_028810_PS_UCP_Y_SCALE_NEG(x) (((x) & 0x1) << 13) +#define G_028810_PS_UCP_Y_SCALE_NEG(x) (((x) >> 13) & 0x1) +#define C_028810_PS_UCP_Y_SCALE_NEG 0xFFFFDFFF +#define S_028810_PS_UCP_MODE(x) (((x) & 0x3) << 14) +#define G_028810_PS_UCP_MODE(x) (((x) >> 14) & 0x3) +#define C_028810_PS_UCP_MODE 0xFFFF3FFF +#define S_028810_CLIP_DISABLE(x) (((x) & 0x1) << 16) +#define G_028810_CLIP_DISABLE(x) (((x) >> 16) & 0x1) +#define C_028810_CLIP_DISABLE 0xFFFEFFFF +#define S_028810_UCP_CULL_ONLY_ENA(x) (((x) & 0x1) << 17) +#define G_028810_UCP_CULL_ONLY_ENA(x) (((x) >> 17) & 0x1) +#define C_028810_UCP_CULL_ONLY_ENA 0xFFFDFFFF +#define S_028810_BOUNDARY_EDGE_FLAG_ENA(x) (((x) & 0x1) << 18) +#define G_028810_BOUNDARY_EDGE_FLAG_ENA(x) (((x) >> 18) & 0x1) +#define C_028810_BOUNDARY_EDGE_FLAG_ENA 0xFFFBFFFF +#define S_028810_DX_CLIP_SPACE_DEF(x) (((x) & 0x1) << 19) +#define G_028810_DX_CLIP_SPACE_DEF(x) (((x) >> 19) & 0x1) +#define C_028810_DX_CLIP_SPACE_DEF 0xFFF7FFFF +#define S_028810_DIS_CLIP_ERR_DETECT(x) (((x) & 0x1) << 20) +#define G_028810_DIS_CLIP_ERR_DETECT(x) (((x) >> 20) & 0x1) +#define C_028810_DIS_CLIP_ERR_DETECT 0xFFEFFFFF +#define S_028810_VTX_KILL_OR(x) (((x) & 0x1) << 21) +#define G_028810_VTX_KILL_OR(x) (((x) >> 21) & 0x1) +#define C_028810_VTX_KILL_OR 0xFFDFFFFF +#define S_028810_DX_LINEAR_ATTR_CLIP_ENA(x) (((x) & 0x1) << 24) +#define G_028810_DX_LINEAR_ATTR_CLIP_ENA(x) (((x) >> 24) & 0x1) +#define C_028810_DX_LINEAR_ATTR_CLIP_ENA 0xFEFFFFFF +#define S_028810_VTE_VPORT_PROVOKE_DISABLE(x) (((x) & 0x1) << 25) +#define G_028810_VTE_VPORT_PROVOKE_DISABLE(x) (((x) >> 25) & 0x1) +#define C_028810_VTE_VPORT_PROVOKE_DISABLE 0xFDFFFFFF +#define S_028810_ZCLIP_NEAR_DISABLE(x) (((x) & 0x1) << 26) +#define G_028810_ZCLIP_NEAR_DISABLE(x) (((x) >> 26) & 0x1) +#define C_028810_ZCLIP_NEAR_DISABLE 0xFBFFFFFF +#define S_028810_ZCLIP_FAR_DISABLE(x) (((x) & 0x1) << 27) +#define G_028810_ZCLIP_FAR_DISABLE(x) (((x) >> 27) & 0x1) +#define C_028810_ZCLIP_FAR_DISABLE 0xF7FFFFFF #define R_028010_DB_DEPTH_INFO 0x028010 #define S_028010_FORMAT(x) (((x) & 0x7) << 0) #define G_028010_FORMAT(x) (((x) >> 0) & 0x7) @@ -314,6 +434,117 @@ #define S_028010_ZRANGE_PRECISION(x) (((x) & 0x1) << 31) #define G_028010_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1) #define C_028010_ZRANGE_PRECISION 0x7FFFFFFF +#define R_028430_DB_STENCILREFMASK 0x028430 +#define S_028430_STENCILREF(x) (((x) & 0xFF) << 0) +#define G_028430_STENCILREF(x) (((x) >> 0) & 0xFF) +#define C_028430_STENCILREF 0xFFFFFF00 +#define S_028430_STENCILMASK(x) (((x) & 0xFF) << 8) +#define G_028430_STENCILMASK(x) (((x) >> 8) & 0xFF) +#define C_028430_STENCILMASK 0xFFFF00FF +#define S_028430_STENCILWRITEMASK(x) (((x) & 0xFF) << 16) +#define G_028430_STENCILWRITEMASK(x) (((x) >> 16) & 0xFF) +#define C_028430_STENCILWRITEMASK 0xFF00FFFF +#define R_028434_DB_STENCILREFMASK_BF 0x028434 +#define S_028434_STENCILREF_BF(x) (((x) & 0xFF) << 0) +#define G_028434_STENCILREF_BF(x) (((x) >> 0) & 0xFF) +#define C_028434_STENCILREF_BF 0xFFFFFF00 +#define S_028434_STENCILMASK_BF(x) (((x) & 0xFF) << 8) +#define G_028434_STENCILMASK_BF(x) (((x) >> 8) & 0xFF) +#define C_028434_STENCILMASK_BF 0xFFFF00FF +#define S_028434_STENCILWRITEMASK_BF(x) (((x) & 0xFF) << 16) +#define G_028434_STENCILWRITEMASK_BF(x) (((x) >> 16) & 0xFF) +#define C_028434_STENCILWRITEMASK_BF 0xFF00FFFF +#define R_028804_CB_BLEND_CONTROL 0x028804 +#define S_028804_COLOR_SRCBLEND(x) (((x) & 0x1F) << 0) +#define G_028804_COLOR_SRCBLEND(x) (((x) >> 0) & 0x1F) +#define C_028804_COLOR_SRCBLEND 0xFFFFFFE0 +#define V_028804_BLEND_ZERO 0x00000000 +#define V_028804_BLEND_ONE 0x00000001 +#define V_028804_BLEND_SRC_COLOR 0x00000002 +#define V_028804_BLEND_ONE_MINUS_SRC_COLOR 0x00000003 +#define V_028804_BLEND_SRC_ALPHA 0x00000004 +#define V_028804_BLEND_ONE_MINUS_SRC_ALPHA 0x00000005 +#define V_028804_BLEND_DST_ALPHA 0x00000006 +#define V_028804_BLEND_ONE_MINUS_DST_ALPHA 0x00000007 +#define V_028804_BLEND_DST_COLOR 0x00000008 +#define V_028804_BLEND_ONE_MINUS_DST_COLOR 0x00000009 +#define V_028804_BLEND_SRC_ALPHA_SATURATE 0x0000000A +#define V_028804_BLEND_BOTH_SRC_ALPHA 0x0000000B +#define V_028804_BLEND_BOTH_INV_SRC_ALPHA 0x0000000C +#define V_028804_BLEND_CONST_COLOR 0x0000000D +#define V_028804_BLEND_ONE_MINUS_CONST_COLOR 0x0000000E +#define V_028804_BLEND_SRC1_COLOR 0x0000000F +#define V_028804_BLEND_INV_SRC1_COLOR 0x00000010 +#define V_028804_BLEND_SRC1_ALPHA 0x00000011 +#define V_028804_BLEND_INV_SRC1_ALPHA 0x00000012 +#define V_028804_BLEND_CONST_ALPHA 0x00000013 +#define V_028804_BLEND_ONE_MINUS_CONST_ALPHA 0x00000014 +#define S_028804_COLOR_COMB_FCN(x) (((x) & 0x7) << 5) +#define G_028804_COLOR_COMB_FCN(x) (((x) >> 5) & 0x7) +#define C_028804_COLOR_COMB_FCN 0xFFFFFF1F +#define V_028804_COMB_DST_PLUS_SRC 0x00000000 +#define V_028804_COMB_SRC_MINUS_DST 0x00000001 +#define V_028804_COMB_MIN_DST_SRC 0x00000002 +#define V_028804_COMB_MAX_DST_SRC 0x00000003 +#define V_028804_COMB_DST_MINUS_SRC 0x00000004 +#define S_028804_COLOR_DESTBLEND(x) (((x) & 0x1F) << 8) +#define G_028804_COLOR_DESTBLEND(x) (((x) >> 8) & 0x1F) +#define C_028804_COLOR_DESTBLEND 0xFFFFE0FF +#define S_028804_OPACITY_WEIGHT(x) (((x) & 0x1) << 13) +#define G_028804_OPACITY_WEIGHT(x) (((x) >> 13) & 0x1) +#define C_028804_OPACITY_WEIGHT 0xFFFFDFFF +#define S_028804_ALPHA_SRCBLEND(x) (((x) & 0x1F) << 16) +#define G_028804_ALPHA_SRCBLEND(x) (((x) >> 16) & 0x1F) +#define C_028804_ALPHA_SRCBLEND 0xFFE0FFFF +#define S_028804_ALPHA_COMB_FCN(x) (((x) & 0x7) << 21) +#define G_028804_ALPHA_COMB_FCN(x) (((x) >> 21) & 0x7) +#define C_028804_ALPHA_COMB_FCN 0xFF1FFFFF +#define S_028804_ALPHA_DESTBLEND(x) (((x) & 0x1F) << 24) +#define G_028804_ALPHA_DESTBLEND(x) (((x) >> 24) & 0x1F) +#define C_028804_ALPHA_DESTBLEND 0xE0FFFFFF +#define S_028804_SEPARATE_ALPHA_BLEND(x) (((x) & 0x1) << 29) +#define G_028804_SEPARATE_ALPHA_BLEND(x) (((x) >> 29) & 0x1) +#define C_028804_SEPARATE_ALPHA_BLEND 0xDFFFFFFF +#define R_028814_PA_SU_SC_MODE_CNTL 0x028814 +#define S_028814_CULL_FRONT(x) (((x) & 0x1) << 0) +#define G_028814_CULL_FRONT(x) (((x) >> 0) & 0x1) +#define C_028814_CULL_FRONT 0xFFFFFFFE +#define S_028814_CULL_BACK(x) (((x) & 0x1) << 1) +#define G_028814_CULL_BACK(x) (((x) >> 1) & 0x1) +#define C_028814_CULL_BACK 0xFFFFFFFD +#define S_028814_FACE(x) (((x) & 0x1) << 2) +#define G_028814_FACE(x) (((x) >> 2) & 0x1) +#define C_028814_FACE 0xFFFFFFFB +#define S_028814_POLY_MODE(x) (((x) & 0x3) << 3) +#define G_028814_POLY_MODE(x) (((x) >> 3) & 0x3) +#define C_028814_POLY_MODE 0xFFFFFFE7 +#define S_028814_POLYMODE_FRONT_PTYPE(x) (((x) & 0x7) << 5) +#define G_028814_POLYMODE_FRONT_PTYPE(x) (((x) >> 5) & 0x7) +#define C_028814_POLYMODE_FRONT_PTYPE 0xFFFFFF1F +#define S_028814_POLYMODE_BACK_PTYPE(x) (((x) & 0x7) << 8) +#define G_028814_POLYMODE_BACK_PTYPE(x) (((x) >> 8) & 0x7) +#define C_028814_POLYMODE_BACK_PTYPE 0xFFFFF8FF +#define S_028814_POLY_OFFSET_FRONT_ENABLE(x) (((x) & 0x1) << 11) +#define G_028814_POLY_OFFSET_FRONT_ENABLE(x) (((x) >> 11) & 0x1) +#define C_028814_POLY_OFFSET_FRONT_ENABLE 0xFFFFF7FF +#define S_028814_POLY_OFFSET_BACK_ENABLE(x) (((x) & 0x1) << 12) +#define G_028814_POLY_OFFSET_BACK_ENABLE(x) (((x) >> 12) & 0x1) +#define C_028814_POLY_OFFSET_BACK_ENABLE 0xFFFFEFFF +#define S_028814_POLY_OFFSET_PARA_ENABLE(x) (((x) & 0x1) << 13) +#define G_028814_POLY_OFFSET_PARA_ENABLE(x) (((x) >> 13) & 0x1) +#define C_028814_POLY_OFFSET_PARA_ENABLE 0xFFFFDFFF +#define S_028814_VTX_WINDOW_OFFSET_ENABLE(x) (((x) & 0x1) << 16) +#define G_028814_VTX_WINDOW_OFFSET_ENABLE(x) (((x) >> 16) & 0x1) +#define C_028814_VTX_WINDOW_OFFSET_ENABLE 0xFFFEFFFF +#define S_028814_PROVOKING_VTX_LAST(x) (((x) & 0x1) << 19) +#define G_028814_PROVOKING_VTX_LAST(x) (((x) >> 19) & 0x1) +#define C_028814_PROVOKING_VTX_LAST 0xFFF7FFFF +#define S_028814_PERSP_CORR_DIS(x) (((x) & 0x1) << 20) +#define G_028814_PERSP_CORR_DIS(x) (((x) >> 20) & 0x1) +#define C_028814_PERSP_CORR_DIS 0xFFEFFFFF +#define S_028814_MULTI_PRIM_IB_ENA(x) (((x) & 0x1) << 21) +#define G_028814_MULTI_PRIM_IB_ENA(x) (((x) >> 21) & 0x1) +#define C_028814_MULTI_PRIM_IB_ENA 0xFFDFFFFF #define R_028000_DB_DEPTH_SIZE 0x028000 #define S_028000_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0) #define G_028000_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF) @@ -400,6 +631,36 @@ #define S_028D10_IGNORE_SC_ZRANGE(x) (((x) & 0x1) << 17) #define G_028D10_IGNORE_SC_ZRANGE(x) (((x) >> 17) & 0x1) #define C_028D10_IGNORE_SC_ZRANGE 0xFFFDFFFF +#define R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL 0x028DF8 +#define S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(x) (((x) & 0xFF) << 0) +#define G_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(x) (((x) >> 0) & 0xFF) +#define C_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS 0xFFFFFF00 +#define S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(x) (((x) & 0x1) << 8) +#define G_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(x) (((x) >> 8) & 0x1) +#define C_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT 0xFFFFFEFF +#define R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE 0x028E00 +#define S_028E00_SCALE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_028E00_SCALE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_028E00_SCALE 0x00000000 +#define R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET 0x028E04 +#define S_028E04_OFFSET(x) (((x) & 0xFFFFFFFF) << 0) +#define G_028E04_OFFSET(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_028E04_OFFSET 0x00000000 +#define R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE 0x028E08 +#define S_028E08_SCALE(x) (((x) & 0xFFFFFFFF) << 0) +#define G_028E08_SCALE(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_028E08_SCALE 0x00000000 +#define R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET 0x028E0C +#define S_028E0C_OFFSET(x) (((x) & 0xFFFFFFFF) << 0) +#define G_028E0C_OFFSET(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_028E0C_OFFSET 0x00000000 +#define R_028A00_PA_SU_POINT_SIZE 0x028A00 +#define S_028A00_HEIGHT(x) (((x) & 0xFFFF) << 0) +#define G_028A00_HEIGHT(x) (((x) >> 0) & 0xFFFF) +#define C_028A00_HEIGHT 0xFFFF0000 +#define S_028A00_WIDTH(x) (((x) & 0xFFFF) << 16) +#define G_028A00_WIDTH(x) (((x) >> 16) & 0xFFFF) +#define C_028A00_WIDTH 0x0000FFFF #define R_028A40_VGT_GS_MODE 0x028A40 #define S_028A40_MODE(x) (((x) & 0x3) << 0) #define G_028A40_MODE(x) (((x) >> 0) & 0x3) @@ -574,6 +835,132 @@ #define S_0287F0_USE_OPAQUE(x) (((x) & 0x1) << 6) #define G_0287F0_USE_OPAQUE(x) (((x) >> 6) & 0x1) #define C_0287F0_USE_OPAQUE 0xFFFFFFBF +#define R_038000_SQ_TEX_RESOURCE_WORD0_0 0x038000 +#define S_038000_DIM(x) (((x) & 0x7) << 0) +#define G_038000_DIM(x) (((x) >> 0) & 0x7) +#define C_038000_DIM 0xFFFFFFF8 +#define V_038000_SQ_TEX_DIM_1D 0x00000000 +#define V_038000_SQ_TEX_DIM_2D 0x00000001 +#define V_038000_SQ_TEX_DIM_3D 0x00000002 +#define V_038000_SQ_TEX_DIM_CUBEMAP 0x00000003 +#define V_038000_SQ_TEX_DIM_1D_ARRAY 0x00000004 +#define V_038000_SQ_TEX_DIM_2D_ARRAY 0x00000005 +#define V_038000_SQ_TEX_DIM_2D_MSAA 0x00000006 +#define V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA 0x00000007 +#define S_038000_TILE_MODE(x) (((x) & 0xF) << 3) +#define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF) +#define C_038000_TILE_MODE 0xFFFFFF87 +#define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7) +#define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1) +#define C_038000_TILE_TYPE 0xFFFFFF7F +#define S_038000_PITCH(x) (((x) & 0x7FF) << 8) +#define G_038000_PITCH(x) (((x) >> 8) & 0x7FF) +#define C_038000_PITCH 0xFFF800FF +#define S_038000_TEX_WIDTH(x) (((x) & 0x1FFF) << 19) +#define G_038000_TEX_WIDTH(x) (((x) >> 19) & 0x1FFF) +#define C_038000_TEX_WIDTH 0x0007FFFF +#define R_038004_SQ_TEX_RESOURCE_WORD1_0 0x038004 +#define S_038004_TEX_HEIGHT(x) (((x) & 0x1FFF) << 0) +#define G_038004_TEX_HEIGHT(x) (((x) >> 0) & 0x1FFF) +#define C_038004_TEX_HEIGHT 0xFFFFE000 +#define S_038004_TEX_DEPTH(x) (((x) & 0x1FFF) << 13) +#define G_038004_TEX_DEPTH(x) (((x) >> 13) & 0x1FFF) +#define C_038004_TEX_DEPTH 0xFC001FFF +#define S_038004_DATA_FORMAT(x) (((x) & 0x3F) << 26) +#define G_038004_DATA_FORMAT(x) (((x) >> 26) & 0x3F) +#define C_038004_DATA_FORMAT 0x03FFFFFF +#define R_038008_SQ_TEX_RESOURCE_WORD2_0 0x038008 +#define S_038008_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) +#define G_038008_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_038008_BASE_ADDRESS 0x00000000 +#define R_03800C_SQ_TEX_RESOURCE_WORD3_0 0x03800C +#define S_03800C_MIP_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) +#define G_03800C_MIP_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_03800C_MIP_ADDRESS 0x00000000 +#define R_038010_SQ_TEX_RESOURCE_WORD4_0 0x038010 +#define S_038010_FORMAT_COMP_X(x) (((x) & 0x3) << 0) +#define G_038010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3) +#define C_038010_FORMAT_COMP_X 0xFFFFFFFC +#define V_038010_SQ_FORMAT_COMP_UNSIGNED 0x00000000 +#define V_038010_SQ_FORMAT_COMP_SIGNED 0x00000001 +#define V_038010_SQ_FORMAT_COMP_UNSIGNED_BIASED 0x00000002 +#define S_038010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2) +#define G_038010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3) +#define C_038010_FORMAT_COMP_Y 0xFFFFFFF3 +#define S_038010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4) +#define G_038010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3) +#define C_038010_FORMAT_COMP_Z 0xFFFFFFCF +#define S_038010_FORMAT_COMP_W(x) (((x) & 0x3) << 6) +#define G_038010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3) +#define C_038010_FORMAT_COMP_W 0xFFFFFF3F +#define S_038010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8) +#define G_038010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3) +#define C_038010_NUM_FORMAT_ALL 0xFFFFFCFF +#define V_038010_SQ_NUM_FORMAT_NORM 0x00000000 +#define V_038010_SQ_NUM_FORMAT_INT 0x00000001 +#define V_038010_SQ_NUM_FORMAT_SCALED 0x00000002 +#define S_038010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) +#define G_038010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) +#define C_038010_SRF_MODE_ALL 0xFFFFFBFF +#define V_038010_SFR_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 +#define V_038010_SFR_MODE_NO_ZERO 0x00000001 +#define S_038010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) +#define G_038010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) +#define C_038010_FORCE_DEGAMMA 0xFFFFF7FF +#define S_038010_ENDIAN_SWAP(x) (((x) & 0x3) << 12) +#define G_038010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3) +#define C_038010_ENDIAN_SWAP 0xFFFFCFFF +#define S_038010_REQUEST_SIZE(x) (((x) & 0x3) << 14) +#define G_038010_REQUEST_SIZE(x) (((x) >> 14) & 0x3) +#define C_038010_REQUEST_SIZE 0xFFFF3FFF +#define S_038010_DST_SEL_X(x) (((x) & 0x7) << 16) +#define G_038010_DST_SEL_X(x) (((x) >> 16) & 0x7) +#define C_038010_DST_SEL_X 0xFFF8FFFF +#define V_038010_SQ_SEL_X 0x00000000 +#define V_038010_SQ_SEL_Y 0x00000001 +#define V_038010_SQ_SEL_Z 0x00000002 +#define V_038010_SQ_SEL_W 0x00000003 +#define V_038010_SQ_SEL_0 0x00000004 +#define V_038010_SQ_SEL_1 0x00000005 +#define S_038010_DST_SEL_Y(x) (((x) & 0x7) << 19) +#define G_038010_DST_SEL_Y(x) (((x) >> 19) & 0x7) +#define C_038010_DST_SEL_Y 0xFFC7FFFF +#define S_038010_DST_SEL_Z(x) (((x) & 0x7) << 22) +#define G_038010_DST_SEL_Z(x) (((x) >> 22) & 0x7) +#define C_038010_DST_SEL_Z 0xFE3FFFFF +#define S_038010_DST_SEL_W(x) (((x) & 0x7) << 25) +#define G_038010_DST_SEL_W(x) (((x) >> 25) & 0x7) +#define C_038010_DST_SEL_W 0xF1FFFFFF +#define S_038010_BASE_LEVEL(x) (((x) & 0xF) << 28) +#define G_038010_BASE_LEVEL(x) (((x) >> 28) & 0xF) +#define C_038010_BASE_LEVEL 0x0FFFFFFF +#define R_038014_SQ_TEX_RESOURCE_WORD5_0 0x038014 +#define S_038014_LAST_LEVEL(x) (((x) & 0xF) << 0) +#define G_038014_LAST_LEVEL(x) (((x) >> 0) & 0xF) +#define C_038014_LAST_LEVEL 0xFFFFFFF0 +#define S_038014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4) +#define G_038014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF) +#define C_038014_BASE_ARRAY 0xFFFE000F +#define S_038014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17) +#define G_038014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF) +#define C_038014_LAST_ARRAY 0xC001FFFF +#define R_038018_SQ_TEX_RESOURCE_WORD6_0 0x038018 +#define S_038018_MPEG_CLAMP(x) (((x) & 0x3) << 0) +#define G_038018_MPEG_CLAMP(x) (((x) >> 0) & 0x3) +#define C_038018_MPEG_CLAMP 0xFFFFFFFC +#define S_038018_PERF_MODULATION(x) (((x) & 0x7) << 5) +#define G_038018_PERF_MODULATION(x) (((x) >> 5) & 0x7) +#define C_038018_PERF_MODULATION 0xFFFFFF1F +#define S_038018_INTERLACED(x) (((x) & 0x1) << 8) +#define G_038018_INTERLACED(x) (((x) >> 8) & 0x1) +#define C_038018_INTERLACED 0xFFFFFEFF +#define S_038018_TYPE(x) (((x) & 0x3) << 30) +#define G_038018_TYPE(x) (((x) >> 30) & 0x3) +#define C_038018_TYPE 0x3FFFFFFF +#define V_038010_SQ_TEX_VTX_INVALID_TEXTURE 0x00000000 +#define V_038010_SQ_TEX_VTX_INVALID_BUFFER 0x00000001 +#define V_038010_SQ_TEX_VTX_VALID_TEXTURE 0x00000002 +#define V_038010_SQ_TEX_VTX_VALID_BUFFER 0x00000003 #define R_038008_SQ_VTX_CONSTANT_WORD2_0 0x038008 #define S_038008_BASE_ADDRESS_HI(x) (((x) & 0xFF) << 0) #define G_038008_BASE_ADDRESS_HI(x) (((x) >> 0) & 0xFF) @@ -633,6 +1020,113 @@ #define S_038008_ENDIAN_SWAP(x) (((x) & 0x3) << 30) #define G_038008_ENDIAN_SWAP(x) (((x) >> 30) & 0x3) #define C_038008_ENDIAN_SWAP 0x3FFFFFFF +#define R_03C000_SQ_TEX_SAMPLER_WORD0_0 0x03C000 +#define S_03C000_CLAMP_X(x) (((x) & 0x7) << 0) +#define G_03C000_CLAMP_X(x) (((x) >> 0) & 0x7) +#define C_03C000_CLAMP_X 0xFFFFFFF8 +#define V_03C000_SQ_TEX_WRAP 0x00000000 +#define V_03C000_SQ_TEX_MIRROR 0x00000001 +#define V_03C000_SQ_TEX_CLAMP_LAST_TEXEL 0x00000002 +#define V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL 0x00000003 +#define V_03C000_SQ_TEX_CLAMP_HALF_BORDER 0x00000004 +#define V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER 0x00000005 +#define V_03C000_SQ_TEX_CLAMP_BORDER 0x00000006 +#define V_03C000_SQ_TEX_MIRROR_ONCE_BORDER 0x00000007 +#define S_03C000_CLAMP_Y(x) (((x) & 0x7) << 3) +#define G_03C000_CLAMP_Y(x) (((x) >> 3) & 0x7) +#define C_03C000_CLAMP_Y 0xFFFFFFC7 +#define S_03C000_CLAMP_Z(x) (((x) & 0x7) << 6) +#define G_03C000_CLAMP_Z(x) (((x) >> 6) & 0x7) +#define C_03C000_CLAMP_Z 0xFFFFFE3F +#define S_03C000_XY_MAG_FILTER(x) (((x) & 0x7) << 9) +#define G_03C000_XY_MAG_FILTER(x) (((x) >> 9) & 0x7) +#define C_03C000_XY_MAG_FILTER 0xFFFFF1FF +#define V_03C000_SQ_TEX_XY_FILTER_POINT 0x00000000 +#define V_03C000_SQ_TEX_XY_FILTER_BILINEAR 0x00000001 +#define V_03C000_SQ_TEX_XY_FILTER_BICUBIC 0x00000002 +#define S_03C000_XY_MIN_FILTER(x) (((x) & 0x7) << 12) +#define G_03C000_XY_MIN_FILTER(x) (((x) >> 12) & 0x7) +#define C_03C000_XY_MIN_FILTER 0xFFFF8FFF +#define S_03C000_Z_FILTER(x) (((x) & 0x3) << 15) +#define G_03C000_Z_FILTER(x) (((x) >> 15) & 0x3) +#define C_03C000_Z_FILTER 0xFFFE7FFF +#define V_03C000_SQ_TEX_Z_FILTER_NONE 0x00000000 +#define V_03C000_SQ_TEX_Z_FILTER_POINT 0x00000001 +#define V_03C000_SQ_TEX_Z_FILTER_LINEAR 0x00000002 +#define S_03C000_MIP_FILTER(x) (((x) & 0x3) << 17) +#define G_03C000_MIP_FILTER(x) (((x) >> 17) & 0x3) +#define C_03C000_MIP_FILTER 0xFFF9FFFF +#define S_03C000_BORDER_COLOR_TYPE(x) (((x) & 0x3) << 22) +#define G_03C000_BORDER_COLOR_TYPE(x) (((x) >> 22) & 0x3) +#define C_03C000_BORDER_COLOR_TYPE 0xFF3FFFFF +#define V_03C000_SQ_TEX_BORDER_COLOR_TRANS_BLACK 0x00000000 +#define V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK 0x00000001 +#define V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE 0x00000002 +#define V_03C000_SQ_TEX_BORDER_COLOR_REGISTER 0x00000003 +#define S_03C000_POINT_SAMPLING_CLAMP(x) (((x) & 0x1) << 24) +#define G_03C000_POINT_SAMPLING_CLAMP(x) (((x) >> 24) & 0x1) +#define C_03C000_POINT_SAMPLING_CLAMP 0xFEFFFFFF +#define S_03C000_TEX_ARRAY_OVERRIDE(x) (((x) & 0x1) << 25) +#define G_03C000_TEX_ARRAY_OVERRIDE(x) (((x) >> 25) & 0x1) +#define C_03C000_TEX_ARRAY_OVERRIDE 0xFDFFFFFF +#define S_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) & 0x7) << 26) +#define G_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) >> 26) & 0x7) +#define C_03C000_DEPTH_COMPARE_FUNCTION 0xE3FFFFFF +#define V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER 0x00000000 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_LESS 0x00000001 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL 0x00000002 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL 0x00000003 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER 0x00000004 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL 0x00000005 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL 0x00000006 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS 0x00000007 +#define S_03C000_CHROMA_KEY(x) (((x) & 0x3) << 29) +#define G_03C000_CHROMA_KEY(x) (((x) >> 29) & 0x3) +#define C_03C000_CHROMA_KEY 0x9FFFFFFF +#define V_03C000_SQ_TEX_CHROMA_KEY_DISABLE 0x00000000 +#define V_03C000_SQ_TEX_CHROMA_KEY_KILL 0x00000001 +#define V_03C000_SQ_TEX_CHROMA_KEY_BLEND 0x00000002 +#define S_03C000_LOD_USES_MINOR_AXIS(x) (((x) & 0x1) << 31) +#define G_03C000_LOD_USES_MINOR_AXIS(x) (((x) >> 31) & 0x1) +#define C_03C000_LOD_USES_MINOR_AXIS 0x7FFFFFFF +#define R_03C004_SQ_TEX_SAMPLER_WORD1_0 0x03C004 +#define S_03C004_MIN_LOD(x) (((x) & 0x3FF) << 0) +#define G_03C004_MIN_LOD(x) (((x) >> 0) & 0x3FF) +#define C_03C004_MIN_LOD 0xFFFFFC00 +#define S_03C004_MAX_LOD(x) (((x) & 0x3FF) << 10) +#define G_03C004_MAX_LOD(x) (((x) >> 10) & 0x3FF) +#define C_03C004_MAX_LOD 0xFFF003FF +#define S_03C004_LOD_BIAS(x) (((x) & 0xFFF) << 20) +#define G_03C004_LOD_BIAS(x) (((x) >> 20) & 0xFFF) +#define C_03C004_LOD_BIAS 0x000FFFFF +#define R_03C008_SQ_TEX_SAMPLER_WORD2_0 0x03C008 +#define S_03C008_LOD_BIAS_SEC(x) (((x) & 0xFFF) << 0) +#define G_03C008_LOD_BIAS_SEC(x) (((x) >> 0) & 0xFFF) +#define C_03C008_LOD_BIAS_SEC 0xFFFFF000 +#define S_03C008_MC_COORD_TRUNCATE(x) (((x) & 0x1) << 12) +#define G_03C008_MC_COORD_TRUNCATE(x) (((x) >> 12) & 0x1) +#define C_03C008_MC_COORD_TRUNCATE 0xFFFFEFFF +#define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 13) +#define G_03C008_FORCE_DEGAMMA(x) (((x) >> 13) & 0x1) +#define C_03C008_FORCE_DEGAMMA 0xFFFFDFFF +#define S_03C008_HIGH_PRECISION_FILTER(x) (((x) & 0x1) << 14) +#define G_03C008_HIGH_PRECISION_FILTER(x) (((x) >> 14) & 0x1) +#define C_03C008_HIGH_PRECISION_FILTER 0xFFFFBFFF +#define S_03C008_PERF_MIP(x) (((x) & 0x7) << 15) +#define G_03C008_PERF_MIP(x) (((x) >> 15) & 0x7) +#define C_03C008_PERF_MIP 0xFFFC7FFF +#define S_03C008_PERF_Z(x) (((x) & 0x3) << 18) +#define G_03C008_PERF_Z(x) (((x) >> 18) & 0x3) +#define C_03C008_PERF_Z 0xFFF3FFFF +#define S_03C008_FETCH_4(x) (((x) & 0x1) << 26) +#define G_03C008_FETCH_4(x) (((x) >> 26) & 0x1) +#define C_03C008_FETCH_4 0xFBFFFFFF +#define S_03C008_SAMPLE_IS_PCF(x) (((x) & 0x1) << 27) +#define G_03C008_SAMPLE_IS_PCF(x) (((x) >> 27) & 0x1) +#define C_03C008_SAMPLE_IS_PCF 0xF7FFFFFF +#define S_03C008_TYPE(x) (((x) & 0x1) << 31) +#define G_03C008_TYPE(x) (((x) >> 31) & 0x1) +#define C_03C008_TYPE 0x7FFFFFFF #define R_008958_VGT_PRIMITIVE_TYPE 0x008958 #define S_008958_PRIM_TYPE(x) (((x) & 0x3F) << 0) #define G_008958_PRIM_TYPE(x) (((x) >> 0) & 0x3F) @@ -666,6 +1160,79 @@ #define V_008958_DI_PT_2D_FILL_RECT_LIST 0x0000001A #define V_008958_DI_PT_2D_LINE_STRIP 0x0000001B #define V_008958_DI_PT_2D_TRI_STRIP 0x0000001C +#define R_02881C_PA_CL_VS_OUT_CNTL 0x02881C +#define S_02881C_CLIP_DIST_ENA_0(x) (((x) & 0x1) << 0) +#define G_02881C_CLIP_DIST_ENA_0(x) (((x) >> 0) & 0x1) +#define C_02881C_CLIP_DIST_ENA_0 0xFFFFFFFE +#define S_02881C_CLIP_DIST_ENA_1(x) (((x) & 0x1) << 1) +#define G_02881C_CLIP_DIST_ENA_1(x) (((x) >> 1) & 0x1) +#define C_02881C_CLIP_DIST_ENA_1 0xFFFFFFFD +#define S_02881C_CLIP_DIST_ENA_2(x) (((x) & 0x1) << 2) +#define G_02881C_CLIP_DIST_ENA_2(x) (((x) >> 2) & 0x1) +#define C_02881C_CLIP_DIST_ENA_2 0xFFFFFFFB +#define S_02881C_CLIP_DIST_ENA_3(x) (((x) & 0x1) << 3) +#define G_02881C_CLIP_DIST_ENA_3(x) (((x) >> 3) & 0x1) +#define C_02881C_CLIP_DIST_ENA_3 0xFFFFFFF7 +#define S_02881C_CLIP_DIST_ENA_4(x) (((x) & 0x1) << 4) +#define G_02881C_CLIP_DIST_ENA_4(x) (((x) >> 4) & 0x1) +#define C_02881C_CLIP_DIST_ENA_4 0xFFFFFFEF +#define S_02881C_CLIP_DIST_ENA_5(x) (((x) & 0x1) << 5) +#define G_02881C_CLIP_DIST_ENA_5(x) (((x) >> 5) & 0x1) +#define C_02881C_CLIP_DIST_ENA_5 0xFFFFFFDF +#define S_02881C_CLIP_DIST_ENA_6(x) (((x) & 0x1) << 6) +#define G_02881C_CLIP_DIST_ENA_6(x) (((x) >> 6) & 0x1) +#define C_02881C_CLIP_DIST_ENA_6 0xFFFFFFBF +#define S_02881C_CLIP_DIST_ENA_7(x) (((x) & 0x1) << 7) +#define G_02881C_CLIP_DIST_ENA_7(x) (((x) >> 7) & 0x1) +#define C_02881C_CLIP_DIST_ENA_7 0xFFFFFF7F +#define S_02881C_CULL_DIST_ENA_0(x) (((x) & 0x1) << 8) +#define G_02881C_CULL_DIST_ENA_0(x) (((x) >> 8) & 0x1) +#define C_02881C_CULL_DIST_ENA_0 0xFFFFFEFF +#define S_02881C_CULL_DIST_ENA_1(x) (((x) & 0x1) << 9) +#define G_02881C_CULL_DIST_ENA_1(x) (((x) >> 9) & 0x1) +#define C_02881C_CULL_DIST_ENA_1 0xFFFFFDFF +#define S_02881C_CULL_DIST_ENA_2(x) (((x) & 0x1) << 10) +#define G_02881C_CULL_DIST_ENA_2(x) (((x) >> 10) & 0x1) +#define C_02881C_CULL_DIST_ENA_2 0xFFFFFBFF +#define S_02881C_CULL_DIST_ENA_3(x) (((x) & 0x1) << 11) +#define G_02881C_CULL_DIST_ENA_3(x) (((x) >> 11) & 0x1) +#define C_02881C_CULL_DIST_ENA_3 0xFFFFF7FF +#define S_02881C_CULL_DIST_ENA_4(x) (((x) & 0x1) << 12) +#define G_02881C_CULL_DIST_ENA_4(x) (((x) >> 12) & 0x1) +#define C_02881C_CULL_DIST_ENA_4 0xFFFFEFFF +#define S_02881C_CULL_DIST_ENA_5(x) (((x) & 0x1) << 13) +#define G_02881C_CULL_DIST_ENA_5(x) (((x) >> 13) & 0x1) +#define C_02881C_CULL_DIST_ENA_5 0xFFFFDFFF +#define S_02881C_CULL_DIST_ENA_6(x) (((x) & 0x1) << 14) +#define G_02881C_CULL_DIST_ENA_6(x) (((x) >> 14) & 0x1) +#define C_02881C_CULL_DIST_ENA_6 0xFFFFBFFF +#define S_02881C_CULL_DIST_ENA_7(x) (((x) & 0x1) << 15) +#define G_02881C_CULL_DIST_ENA_7(x) (((x) >> 15) & 0x1) +#define C_02881C_CULL_DIST_ENA_7 0xFFFF7FFF +#define S_02881C_USE_VTX_POINT_SIZE(x) (((x) & 0x1) << 16) +#define G_02881C_USE_VTX_POINT_SIZE(x) (((x) >> 16) & 0x1) +#define C_02881C_USE_VTX_POINT_SIZE 0xFFFEFFFF +#define S_02881C_USE_VTX_EDGE_FLAG(x) (((x) & 0x1) << 17) +#define G_02881C_USE_VTX_EDGE_FLAG(x) (((x) >> 17) & 0x1) +#define C_02881C_USE_VTX_EDGE_FLAG 0xFFFDFFFF +#define S_02881C_USE_VTX_RENDER_TARGET_INDX(x) (((x) & 0x1) << 18) +#define G_02881C_USE_VTX_RENDER_TARGET_INDX(x) (((x) >> 18) & 0x1) +#define C_02881C_USE_VTX_RENDER_TARGET_INDX 0xFFFBFFFF +#define S_02881C_USE_VTX_VIEWPORT_INDX(x) (((x) & 0x1) << 19) +#define G_02881C_USE_VTX_VIEWPORT_INDX(x) (((x) >> 19) & 0x1) +#define C_02881C_USE_VTX_VIEWPORT_INDX 0xFFF7FFFF +#define S_02881C_USE_VTX_KILL_FLAG(x) (((x) & 0x1) << 20) +#define G_02881C_USE_VTX_KILL_FLAG(x) (((x) >> 20) & 0x1) +#define C_02881C_USE_VTX_KILL_FLAG 0xFFEFFFFF +#define S_02881C_VS_OUT_MISC_VEC_ENA(x) (((x) & 0x1) << 21) +#define G_02881C_VS_OUT_MISC_VEC_ENA(x) (((x) >> 21) & 0x1) +#define C_02881C_VS_OUT_MISC_VEC_ENA 0xFFDFFFFF +#define S_02881C_VS_OUT_CCDIST0_VEC_ENA(x) (((x) & 0x1) << 22) +#define G_02881C_VS_OUT_CCDIST0_VEC_ENA(x) (((x) >> 22) & 0x1) +#define C_02881C_VS_OUT_CCDIST0_VEC_ENA 0xFFBFFFFF +#define S_02881C_VS_OUT_CCDIST1_VEC_ENA(x) (((x) & 0x1) << 23) +#define G_02881C_VS_OUT_CCDIST1_VEC_ENA(x) (((x) >> 23) & 0x1) +#define C_02881C_VS_OUT_CCDIST1_VEC_ENA 0xFF7FFFFF #define R_028868_SQ_PGM_RESOURCES_VS 0x028868 #define S_028868_NUM_GPRS(x) (((x) & 0xFF) << 0) #define G_028868_NUM_GPRS(x) (((x) >> 0) & 0xFF) diff --git a/src/gallium/drivers/r600/r700_asm.c b/src/gallium/drivers/r600/r700_asm.c new file mode 100644 index 00000000000..1ebe20d6ab0 --- /dev/null +++ b/src/gallium/drivers/r600/r700_asm.c @@ -0,0 +1,69 @@ +/* + * Copyright 2010 Jerome Glisse <[email protected]> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#include "r600_asm.h" +#include "r600_context.h" +#include "util/u_memory.h" +#include "r700_sq.h" +#include <stdio.h> + +int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id) +{ + unsigned i; + + /* don't replace gpr by pv or ps for destination register */ + if (alu->is_op3) { + bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) | + S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) | + S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) | + S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) | + S_SQ_ALU_WORD0_LAST(alu->last); + bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | + S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | + S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) | + S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) | + S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) | + S_SQ_ALU_WORD1_OP3_ALU_INST(alu->inst) | + S_SQ_ALU_WORD1_BANK_SWIZZLE(0); + } else { + bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) | + S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) | + S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) | + S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) | + S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) | + S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) | + S_SQ_ALU_WORD0_LAST(alu->last); + bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) | + S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) | + S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) | + S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) | + S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) | + S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) | + S_SQ_ALU_WORD1_BANK_SWIZZLE(0); + } + if (alu->last) { + for (i = 0; i < alu->nliteral; i++) { + bc->bytecode[id++] = alu->value[i]; + } + } + return 0; +} diff --git a/src/gallium/drivers/r600/radeon.h b/src/gallium/drivers/r600/radeon.h index 3a8405f9b40..8f00a4895a0 100644 --- a/src/gallium/drivers/r600/radeon.h +++ b/src/gallium/drivers/r600/radeon.h @@ -157,11 +157,42 @@ int radeon_ctx_submit(struct radeon_ctx *ctx); void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file); /* + * radeon context functions + */ +#pragma pack(1) +struct radeon_cs_reloc { + uint32_t handle; + uint32_t read_domain; + uint32_t write_domain; + uint32_t flags; +}; +#pragma pack() + +struct radeon_ctx { + int refcount; + struct radeon *radeon; + u32 *pm4; + u32 cpm4; + u32 draw_cpm4; + unsigned id; + unsigned next_id; + unsigned nreloc; + struct radeon_cs_reloc *reloc; + unsigned nbo; + struct radeon_bo **bo; + unsigned ndraw; + struct radeon_draw *cdraw; + struct radeon_draw **draw; + unsigned nstate; + struct radeon_state **state; +}; + +/* * R600/R700 */ -#define R600_NSTATE 1273 -#define R600_NTYPE 25 +#define R600_NSTATE 1280 +#define R600_NTYPE 32 #define R600_CONFIG 0 #define R600_CONFIG_TYPE 0 @@ -207,12 +238,26 @@ void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file); #define R600_GS_SAMPLER_BORDER_TYPE 20 #define R600_CB0 1269 #define R600_CB0_TYPE 21 -#define R600_DB 1270 -#define R600_DB_TYPE 22 -#define R600_VGT 1271 -#define R600_VGT_TYPE 23 -#define R600_DRAW 1272 -#define R600_DRAW_TYPE 24 +#define R600_CB1 1270 +#define R600_CB1_TYPE 22 +#define R600_CB2 1271 +#define R600_CB2_TYPE 23 +#define R600_CB3 1272 +#define R600_CB3_TYPE 24 +#define R600_CB4 1273 +#define R600_CB4_TYPE 25 +#define R600_CB5 1274 +#define R600_CB5_TYPE 26 +#define R600_CB6 1275 +#define R600_CB6_TYPE 27 +#define R600_CB7 1276 +#define R600_CB7_TYPE 28 +#define R600_DB 1277 +#define R600_DB_TYPE 29 +#define R600_VGT 1278 +#define R600_VGT_TYPE 30 +#define R600_DRAW 1279 +#define R600_DRAW_TYPE 31 /* R600_CONFIG */ #define R600_CONFIG__SQ_CONFIG 0 #define R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1 1 diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c index e0dd5cf8c2b..3ffda87520f 100644 --- a/src/gallium/drivers/rbug/rbug_context.c +++ b/src/gallium/drivers/rbug/rbug_context.c @@ -103,10 +103,7 @@ rbug_draw_block_locked(struct rbug_context *rb_pipe, int flag) } static void -rbug_draw_arrays(struct pipe_context *_pipe, - unsigned prim, - unsigned start, - unsigned count) +rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; @@ -114,72 +111,7 @@ rbug_draw_arrays(struct pipe_context *_pipe, pipe_mutex_lock(rb_pipe->draw_mutex); rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); - pipe->draw_arrays(pipe, - prim, - start, - count); - - rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); - pipe_mutex_unlock(rb_pipe->draw_mutex); -} - -static void -rbug_draw_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned prim, - unsigned start, - unsigned count) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_resource *rb_resource = rbug_resource(_indexResource); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_resource *indexResource = rb_resource->resource; - - pipe_mutex_lock(rb_pipe->draw_mutex); - rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); - - pipe->draw_elements(pipe, - indexResource, - indexSize, - indexBias, - prim, - start, - count); - - rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); - pipe_mutex_unlock(rb_pipe->draw_mutex); -} - -static void -rbug_draw_range_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexResource, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_resource *rb_resource = rbug_resource(_indexResource); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_resource *indexResource = rb_resource->resource; - - pipe_mutex_lock(rb_pipe->draw_mutex); - rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); - - pipe->draw_range_elements(pipe, - indexResource, - indexSize, - indexBias, - minIndex, - maxIndex, - mode, - start, - count); + pipe->draw_vbo(pipe, info); rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); pipe_mutex_unlock(rb_pipe->draw_mutex); @@ -745,6 +677,23 @@ rbug_set_vertex_buffers(struct pipe_context *_pipe, } static void +rbug_set_index_buffer(struct pipe_context *_pipe, + const struct pipe_index_buffer *_ib) +{ + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct pipe_context *pipe = rb_pipe->pipe; + struct pipe_index_buffer unwrapped_ib, *ib = NULL; + + if (_ib) { + unwrapped_ib = *_ib; + unwrapped_ib.buffer = rbug_resource_unwrap(_ib->buffer); + ib = &unwrapped_ib; + } + + pipe->set_index_buffer(pipe, ib); +} + +static void rbug_set_sample_mask(struct pipe_context *_pipe, unsigned sample_mask) { @@ -1040,9 +989,7 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) rb_pipe->base.draw = NULL; rb_pipe->base.destroy = rbug_destroy; - rb_pipe->base.draw_arrays = rbug_draw_arrays; - rb_pipe->base.draw_elements = rbug_draw_elements; - rb_pipe->base.draw_range_elements = rbug_draw_range_elements; + rb_pipe->base.draw_vbo = rbug_draw_vbo; rb_pipe->base.create_query = rbug_create_query; rb_pipe->base.destroy_query = rbug_destroy_query; rb_pipe->base.begin_query = rbug_begin_query; @@ -1084,6 +1031,7 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) rb_pipe->base.set_fragment_sampler_views = rbug_set_fragment_sampler_views; rb_pipe->base.set_vertex_sampler_views = rbug_set_vertex_sampler_views; rb_pipe->base.set_vertex_buffers = rbug_set_vertex_buffers; + rb_pipe->base.set_index_buffer = rbug_set_index_buffer; rb_pipe->base.set_sample_mask = rbug_set_sample_mask; rb_pipe->base.resource_copy_region = rbug_resource_copy_region; rb_pipe->base.clear = rbug_clear; diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 12ef98aac75..a7c9959b3e1 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -282,12 +282,9 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.set_viewport_state = softpipe_set_viewport_state; softpipe->pipe.set_stream_output_buffers = softpipe_set_stream_output_buffers; softpipe->pipe.set_vertex_buffers = softpipe_set_vertex_buffers; + softpipe->pipe.set_index_buffer = softpipe_set_index_buffer; - softpipe->pipe.draw_arrays = softpipe_draw_arrays; - softpipe->pipe.draw_elements = softpipe_draw_elements; - softpipe->pipe.draw_range_elements = softpipe_draw_range_elements; - softpipe->pipe.draw_arrays_instanced = softpipe_draw_arrays_instanced; - softpipe->pipe.draw_elements_instanced = softpipe_draw_elements_instanced; + softpipe->pipe.draw_vbo = softpipe_draw_vbo; softpipe->pipe.draw_stream_output = softpipe_draw_stream_output; softpipe->pipe.clear = softpipe_clear; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 53115a827d0..9361a3df09e 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -82,6 +82,7 @@ struct softpipe_context { struct pipe_sampler_view *geometry_sampler_views[PIPE_MAX_GEOMETRY_SAMPLERS]; struct pipe_viewport_state viewport; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + struct pipe_index_buffer index_buffer; struct { struct softpipe_resource *buffer[PIPE_MAX_SO_BUFFERS]; int offset[PIPE_MAX_SO_BUFFERS]; @@ -111,6 +112,7 @@ struct softpipe_context { /** Mapped constant buffers */ const void *mapped_constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; + unsigned const_buffer_size[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; /** Vertex format */ struct vertex_info vertex_info; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index 9e727c93811..386c8acb8ce 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -111,27 +111,19 @@ softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode) * When the min/max element indexes aren't known, minIndex should be 0 * and maxIndex should be ~0. */ -static void -softpipe_draw_range_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) +void +softpipe_draw_vbo(struct pipe_context *pipe, + const struct pipe_draw_info *info) { struct softpipe_context *sp = softpipe_context(pipe); struct draw_context *draw = sp->draw; + void *mapped_indices = NULL; unsigned i; if (!softpipe_check_render_cond(sp)) return; - sp->reduced_api_prim = u_reduced_prim(mode); + sp->reduced_api_prim = u_reduced_prim(info->mode); if (sp->dirty) { softpipe_update_derived(sp); @@ -146,31 +138,27 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe, } /* Map index buffer, if present */ - if (indexBuffer) { - void *mapped_indexes = softpipe_resource(indexBuffer)->data; - draw_set_mapped_element_buffer_range(draw, - indexSize, - indexBias, - minIndex, - maxIndex, - mapped_indexes); - } else { - /* no index/element buffer */ - draw_set_mapped_element_buffer_range(draw, - 0, 0, - start, - start + count - 1, - NULL); + if (info->indexed && sp->index_buffer.buffer) { + char *indices = (char *) softpipe_resource(sp->index_buffer.buffer)->data; + mapped_indices = (void *) (indices + sp->index_buffer.offset); } + draw_set_mapped_element_buffer_range(draw, (mapped_indices) ? + sp->index_buffer.index_size : 0, + info->index_bias, + info->min_index, + info->max_index, + mapped_indices); + /* draw! */ - draw_arrays_instanced(draw, mode, start, count, startInstance, instanceCount); + draw_arrays_instanced(draw, info->mode, info->start, info->count, + info->start_instance, info->instance_count); /* unmap vertex/index buffers - will cause draw module to flush */ for (i = 0; i < sp->num_vertex_buffers; i++) { draw_set_mapped_vertex_buffer(draw, i, NULL); } - if (indexBuffer) { + if (mapped_indices) { draw_set_mapped_element_buffer(draw, 0, 0, NULL); } @@ -184,109 +172,3 @@ softpipe_draw_range_elements_instanced(struct pipe_context *pipe, /* Note: leave drawing surfaces mapped */ sp->dirty_render_cache = TRUE; } - - -void -softpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned min_index, - unsigned max_index, - unsigned mode, unsigned start, unsigned count) -{ - softpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, - indexBias, - min_index, - max_index, - mode, - start, - count, - 0, - 1); -} - - -void -softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count) -{ - softpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, - indexBias, - 0, - 0xffffffff, - mode, - start, - count, - 0, - 1); -} - -void -softpipe_draw_arrays_instanced(struct pipe_context *pipe, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) -{ - softpipe_draw_range_elements_instanced(pipe, - NULL, - 0, - 0, - 0, - 0xffffffff, - mode, - start, - count, - startInstance, - instanceCount); -} - -void -softpipe_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount) -{ - softpipe_draw_range_elements_instanced(pipe, - indexBuffer, - indexSize, - indexBias, - 0, - 0xffffffff, - mode, - start, - count, - startInstance, - instanceCount); -} - -void -softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count) -{ - softpipe_draw_range_elements_instanced(pipe, - NULL, - 0, - 0, - 0, - 0xffffffff, - mode, - start, - count, - 0, - 1); -} - diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c index d240bcbf3bb..90f4787d599 100644 --- a/src/gallium/drivers/softpipe/sp_quad_fs.c +++ b/src/gallium/drivers/softpipe/sp_quad_fs.c @@ -111,9 +111,10 @@ shade_quads(struct quad_stage *qs, struct tgsi_exec_machine *machine = softpipe->fs_machine; unsigned i, nr_quads = 0; - for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { - machine->Consts[i] = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT][i]; - } + tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, + softpipe->mapped_constants[PIPE_SHADER_FRAGMENT], + softpipe->const_buffer_size[PIPE_SHADER_FRAGMENT]); + machine->InterpCoefs = quads[0]->coef; for (i = 0; i < nr; i++) { diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index 7d6b86dce04..39d204de8a9 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -221,44 +221,16 @@ void softpipe_set_vertex_buffers(struct pipe_context *, unsigned count, const struct pipe_vertex_buffer *); - -void softpipe_update_derived( struct softpipe_context *softpipe ); +void softpipe_set_index_buffer(struct pipe_context *, + const struct pipe_index_buffer *); -void softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode, - unsigned start, unsigned count); - -void softpipe_draw_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count); -void -softpipe_draw_range_elements(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned min_index, - unsigned max_index, - unsigned mode, unsigned start, unsigned count); +void softpipe_update_derived( struct softpipe_context *softpipe ); -void -softpipe_draw_arrays_instanced(struct pipe_context *pipe, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount); void -softpipe_draw_elements_instanced(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount); +softpipe_draw_vbo(struct pipe_context *pipe, + const struct pipe_draw_info *info); void softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode); diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c index 3fbf1f25781..ded242d3dc5 100644 --- a/src/gallium/drivers/softpipe/sp_state_fs.c +++ b/src/gallium/drivers/softpipe/sp_state_fs.c @@ -195,6 +195,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe, } softpipe->mapped_constants[shader][index] = data; + softpipe->const_buffer_size[shader][index] = size; + softpipe->dirty |= SP_NEW_CONSTANTS; } diff --git a/src/gallium/drivers/softpipe/sp_state_vertex.c b/src/gallium/drivers/softpipe/sp_state_vertex.c index 462f4d2655e..880a7c7cd26 100644 --- a/src/gallium/drivers/softpipe/sp_state_vertex.c +++ b/src/gallium/drivers/softpipe/sp_state_vertex.c @@ -88,3 +88,17 @@ softpipe_set_vertex_buffers(struct pipe_context *pipe, draw_set_vertex_buffers(softpipe->draw, count, buffers); } + +void +softpipe_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + if (ib) + memcpy(&softpipe->index_buffer, ib, sizeof(softpipe->index_buffer)); + else + memset(&softpipe->index_buffer, 0, sizeof(softpipe->index_buffer)); + + /* TODO make this more like a state */ +} diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index 9a46de643fd..67a7614c8af 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -190,6 +190,7 @@ struct svga_state struct svga_vertex_shader *vs; struct pipe_vertex_buffer vb[PIPE_MAX_ATTRIBS]; + struct pipe_index_buffer ib; struct pipe_resource *cb[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index 58e930d9835..de08bc5e562 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -227,31 +227,30 @@ svga_draw_range_elements( struct pipe_context *pipe, static void -svga_draw_elements( struct pipe_context *pipe, - struct pipe_resource *index_buffer, - unsigned index_size, int index_bias, - unsigned prim, unsigned start, unsigned count) +svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { - svga_draw_range_elements( pipe, index_buffer, - index_size, index_bias, - 0, 0xffffffff, - prim, start, count ); -} + struct svga_context *svga = svga_context(pipe); -static void -svga_draw_arrays( struct pipe_context *pipe, - unsigned prim, unsigned start, unsigned count) -{ - svga_draw_range_elements(pipe, NULL, 0, 0, - start, start + count - 1, - prim, - start, count); + if (info->indexed && svga->curr.ib.buffer) { + unsigned offset; + + assert(svga->curr.ib.offset % svga->curr.ib.index_size == 0); + offset = svga->curr.ib.offset / svga->curr.ib.index_size; + + svga_draw_range_elements(pipe, svga->curr.ib.buffer, + svga->curr.ib.index_size, info->index_bias, + info->min_index, info->max_index, + info->mode, info->start + offset, info->count); + } + else { + svga_draw_range_elements(pipe, NULL, 0, 0, + info->min_index, info->max_index, + info->mode, info->start, info->count); + } } void svga_init_draw_functions( struct svga_context *svga ) { - svga->pipe.draw_arrays = svga_draw_arrays; - svga->pipe.draw_elements = svga_draw_elements; - svga->pipe.draw_range_elements = svga_draw_range_elements; + svga->pipe.draw_vbo = svga_draw_vbo; } diff --git a/src/gallium/drivers/svga/svga_pipe_vertex.c b/src/gallium/drivers/svga/svga_pipe_vertex.c index 23808ad08e0..86c79459f3e 100644 --- a/src/gallium/drivers/svga/svga_pipe_vertex.c +++ b/src/gallium/drivers/svga/svga_pipe_vertex.c @@ -66,6 +66,24 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe, } +static void svga_set_index_buffer(struct pipe_context *pipe, + const struct pipe_index_buffer *ib) +{ + struct svga_context *svga = svga_context(pipe); + + if (ib) { + pipe_resource_reference(&svga->curr.ib.buffer, ib->buffer); + memcpy(&svga->curr.ib, ib, sizeof(svga->curr.ib)); + } + else { + pipe_resource_reference(&svga->curr.ib.buffer, NULL); + memset(&svga->curr.ib, 0, sizeof(svga->curr.ib)); + } + + /* TODO make this more like a state */ +} + + static void * svga_create_vertex_elements_state(struct pipe_context *pipe, unsigned count, @@ -109,6 +127,7 @@ void svga_cleanup_vertex_state( struct svga_context *svga ) void svga_init_vertex_functions( struct svga_context *svga ) { svga->pipe.set_vertex_buffers = svga_set_vertex_buffers; + svga->pipe.set_index_buffer = svga_set_index_buffer; svga->pipe.create_vertex_elements_state = svga_create_vertex_elements_state; svga->pipe.bind_vertex_elements_state = svga_bind_vertex_elements_state; svga->pipe.delete_vertex_elements_state = svga_delete_vertex_elements_state; diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 55dd6cf8837..84e5a6a8242 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -83,85 +83,26 @@ trace_surface_unwrap(struct trace_context *tr_ctx, static INLINE void -trace_context_draw_arrays(struct pipe_context *_pipe, - unsigned mode, unsigned start, unsigned count) +trace_context_draw_vbo(struct pipe_context *_pipe, + const struct pipe_draw_info *info) { struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - trace_dump_call_begin("pipe_context", "draw_arrays"); + trace_dump_call_begin("pipe_context", "draw_vbo"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, mode); - trace_dump_arg(uint, start); - trace_dump_arg(uint, count); - - pipe->draw_arrays(pipe, mode, start, count); - - trace_dump_call_end(); -} - - -static INLINE void -trace_context_draw_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_resource *tr_buf = trace_resource(_indexBuffer); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_resource *indexBuffer = tr_buf->resource; - - trace_dump_call_begin("pipe_context", "draw_elements"); - - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, indexBuffer); - trace_dump_arg(uint, indexSize); - trace_dump_arg(int, indexBias); - trace_dump_arg(uint, mode); - trace_dump_arg(uint, start); - trace_dump_arg(uint, count); - - pipe->draw_elements(pipe, indexBuffer, indexSize, indexBias, - mode, start, count); - - trace_dump_call_end(); -} - - -static INLINE void -trace_context_draw_range_elements(struct pipe_context *_pipe, - struct pipe_resource *_indexBuffer, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_resource *tr_buf = trace_resource(_indexBuffer); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_resource *indexBuffer = tr_buf->resource; - - trace_dump_call_begin("pipe_context", "draw_range_elements"); + trace_dump_arg(ptr, pipe); + trace_dump_arg(bool, info->indexed); + trace_dump_arg(uint, info->mode); + trace_dump_arg(uint, info->start); + trace_dump_arg(uint, info->count); + trace_dump_arg(uint, info->start_instance); + trace_dump_arg(uint, info->instance_count); + trace_dump_arg(int, info->index_bias); + trace_dump_arg(uint, info->min_index); + trace_dump_arg(uint, info->max_index); - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, indexBuffer); - trace_dump_arg(uint, indexSize); - trace_dump_arg(int, indexBias); - trace_dump_arg(uint, minIndex); - trace_dump_arg(uint, maxIndex); - trace_dump_arg(uint, mode); - trace_dump_arg(uint, start); - trace_dump_arg(uint, count); - - pipe->draw_range_elements(pipe, - indexBuffer, indexSize, indexBias, - minIndex, maxIndex, - mode, start, count); + pipe->draw_vbo(pipe, info); trace_dump_call_end(); } @@ -1045,6 +986,30 @@ trace_context_set_vertex_buffers(struct pipe_context *_pipe, static INLINE void +trace_context_set_index_buffer(struct pipe_context *_pipe, + const struct pipe_index_buffer *_ib) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + struct pipe_index_buffer unwrapped_ib, *ib = NULL; + + if (_ib) { + unwrapped_ib = *_ib; + unwrapped_ib.buffer = trace_resource_unwrap(tr_ctx, _ib->buffer); + ib = &unwrapped_ib; + } + + trace_dump_call_begin("pipe_context", "set_index_buffer"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(index_buffer, ib); + + pipe->set_index_buffer(pipe, ib); + + trace_dump_call_end(); +} + +static INLINE void trace_context_resource_copy_region(struct pipe_context *_pipe, struct pipe_resource *dst, struct pipe_subresource subdst, @@ -1433,9 +1398,7 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.screen = &tr_scr->base; tr_ctx->base.destroy = trace_context_destroy; - tr_ctx->base.draw_arrays = trace_context_draw_arrays; - tr_ctx->base.draw_elements = trace_context_draw_elements; - tr_ctx->base.draw_range_elements = trace_context_draw_range_elements; + tr_ctx->base.draw_vbo = trace_context_draw_vbo; tr_ctx->base.create_query = trace_context_create_query; tr_ctx->base.destroy_query = trace_context_destroy_query; tr_ctx->base.begin_query = trace_context_begin_query; @@ -1477,6 +1440,7 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.create_sampler_view = trace_create_sampler_view; tr_ctx->base.sampler_view_destroy = trace_sampler_view_destroy; tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers; + tr_ctx->base.set_index_buffer = trace_context_set_index_buffer; tr_ctx->base.resource_copy_region = trace_context_resource_copy_region; tr_ctx->base.clear = trace_context_clear; tr_ctx->base.clear_render_target = trace_context_clear_render_target; diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index 1727c2a0206..bd9a9bfaf16 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -533,6 +533,26 @@ void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state) } +void trace_dump_index_buffer(const struct pipe_index_buffer *state) +{ + if (!trace_dumping_enabled_locked()) + return; + + if(!state) { + trace_dump_null(); + return; + } + + trace_dump_struct_begin("pipe_index_buffer"); + + trace_dump_member(uint, state, index_size); + trace_dump_member(uint, state, offset); + trace_dump_member(resource_ptr, state, buffer); + + trace_dump_struct_end(); +} + + void trace_dump_vertex_element(const struct pipe_vertex_element *state) { if (!trace_dumping_enabled_locked()) diff --git a/src/gallium/drivers/trace/tr_dump_state.h b/src/gallium/drivers/trace/tr_dump_state.h index e614e8355e3..2e70f4e1c74 100644 --- a/src/gallium/drivers/trace/tr_dump_state.h +++ b/src/gallium/drivers/trace/tr_dump_state.h @@ -75,6 +75,8 @@ void trace_dump_transfer(const struct pipe_transfer *state); void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state); +void trace_dump_index_buffer(const struct pipe_index_buffer *state); + void trace_dump_vertex_element(const struct pipe_vertex_element *state); diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h index 0358c14e24b..1fa3ec8300a 100644 --- a/src/gallium/include/pipe/p_compiler.h +++ b/src/gallium/include/pipe/p_compiler.h @@ -102,6 +102,16 @@ typedef unsigned char boolean; # endif #endif +/* Forced function inlining */ +#ifndef ALWAYS_INLINE +# ifdef __GNUC__ +# define ALWAYS_INLINE inline __attribute__((always_inline)) +# elif defined(_MSC_VER) +# define ALWAYS_INLINE __forceinline +# else +# define ALWAYS_INLINE INLINE +# endif +#endif /* Function visibility */ #ifndef PUBLIC diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 7ec3d63a3fd..0579962ec69 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -61,46 +61,8 @@ struct pipe_context { * VBO drawing */ /*@{*/ - void (*draw_arrays)( struct pipe_context *pipe, - unsigned mode, unsigned start, unsigned count); - - void (*draw_elements)( struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, unsigned start, unsigned count); - - void (*draw_arrays_instanced)(struct pipe_context *pipe, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount); - - void (*draw_elements_instanced)(struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned mode, - unsigned start, - unsigned count, - unsigned startInstance, - unsigned instanceCount); - - /* XXX: this is (probably) a temporary entrypoint, as the range - * information should be available from the vertex_buffer state. - * Using this to quickly evaluate a specialized path in the draw - * module. - */ - void (*draw_range_elements)( struct pipe_context *pipe, - struct pipe_resource *indexBuffer, - unsigned indexSize, - int indexBias, - unsigned minIndex, - unsigned maxIndex, - unsigned mode, - unsigned start, - unsigned count); + void (*draw_vbo)( struct pipe_context *pipe, + const struct pipe_draw_info *info ); /** * Draw the stream output buffer at index 0 @@ -249,6 +211,9 @@ struct pipe_context { unsigned num_buffers, const struct pipe_vertex_buffer * ); + void (*set_index_buffer)( struct pipe_context *pipe, + const struct pipe_index_buffer * ); + void (*set_stream_output_buffers)(struct pipe_context *, struct pipe_resource **buffers, int *offsets, /*array of offsets diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 301fe2b74f0..0f1a44cde42 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -426,6 +426,41 @@ struct pipe_vertex_element }; +/** + * An index buffer. When an index buffer is bound, all indices to vertices + * will be looked up in the buffer. + */ +struct pipe_index_buffer +{ + unsigned index_size; /**< size of an index, in bytes */ + unsigned offset; /**< offset to start of data in buffer, in bytes */ + struct pipe_resource *buffer; /**< the actual buffer */ +}; + + +/** + * Information to describe a draw_vbo call. + */ +struct pipe_draw_info +{ + boolean indexed; /**< use index buffer */ + + unsigned mode; /**< the mode of the primitive */ + unsigned start; /**< the index of the first vertex */ + unsigned count; /**< number of vertices */ + + unsigned start_instance; /**< first instance id */ + unsigned instance_count; /**< number of instances */ + + /** + * For indexed drawing, these fields apply after index lookup. + */ + int index_bias; /**< a bias to be added to each index */ + unsigned min_index; /**< the min index */ + unsigned max_index; /**< the max index */ +}; + + #ifdef __cplusplus } #endif diff --git a/src/gallium/state_trackers/dri/common/dri1_helper.c b/src/gallium/state_trackers/dri/common/dri1_helper.c deleted file mode 100644 index ad6c7d37504..00000000000 --- a/src/gallium/state_trackers/dri/common/dri1_helper.c +++ /dev/null @@ -1,129 +0,0 @@ -/************************************************************************** - * - * Copyright 2009, VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ -/* - * Management of pipe objects (surface / pipe / fences) used by DRI1 and DRISW. - * - * Author: Keith Whitwell <[email protected]> - * Author: Jakob Bornecrantz <[email protected]> - */ - -#include "util/u_inlines.h" -#include "pipe/p_context.h" - -#include "dri_screen.h" -#include "dri_context.h" -#include "dri_drawable.h" -#include "dri1_helper.h" - -struct pipe_fence_handle * -dri1_swap_fences_pop_front(struct dri_drawable *draw) -{ - struct pipe_screen *screen = dri_screen(draw->sPriv)->base.screen; - struct pipe_fence_handle *fence = NULL; - - if (draw->cur_fences >= draw->desired_fences) { - screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]); - screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL); - --draw->cur_fences; - draw->tail &= DRI_SWAP_FENCES_MASK; - } - return fence; -} - -void -dri1_swap_fences_push_back(struct dri_drawable *draw, - struct pipe_fence_handle *fence) -{ - struct pipe_screen *screen = dri_screen(draw->sPriv)->base.screen; - - if (!fence) - return; - - if (draw->cur_fences < DRI_SWAP_FENCES_MAX) { - draw->cur_fences++; - screen->fence_reference(screen, &draw->swap_fences[draw->head++], - fence); - draw->head &= DRI_SWAP_FENCES_MASK; - } -} - -void -dri1_swap_fences_clear(struct dri_drawable *drawable) -{ - struct pipe_screen *screen = dri_screen(drawable->sPriv)->base.screen; - struct pipe_fence_handle *fence; - - while (drawable->cur_fences) { - fence = dri1_swap_fences_pop_front(drawable); - screen->fence_reference(screen, &fence, NULL); - } -} - -struct pipe_surface * -dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_resource *ptex) -{ - struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->base.screen; - struct pipe_surface *psurf = drawable->dri1_surface; - - if (!psurf || psurf->texture != ptex) { - pipe_surface_reference(&drawable->dri1_surface, NULL); - - drawable->dri1_surface = pipe_screen->get_tex_surface(pipe_screen, - ptex, 0, 0, 0, 0/* no bind flag???*/); - - psurf = drawable->dri1_surface; - } - - return psurf; -} - -void -dri1_destroy_pipe_surface(struct dri_drawable *drawable) -{ - pipe_surface_reference(&drawable->dri1_surface, NULL); -} - -struct pipe_context * -dri1_get_pipe_context(struct dri_screen *screen) -{ - struct pipe_context *pipe = screen->dri1_pipe; - - if (!pipe) { - screen->dri1_pipe = - screen->base.screen->context_create(screen->base.screen, NULL); - pipe = screen->dri1_pipe; - } - - return pipe; -} - -void -dri1_destroy_pipe_context(struct dri_screen *screen) -{ - if (screen->dri1_pipe) - screen->dri1_pipe->destroy(screen->dri1_pipe); -} diff --git a/src/gallium/state_trackers/dri/common/dri1_helper.h b/src/gallium/state_trackers/dri/common/dri1_helper.h deleted file mode 100644 index c98adf2df22..00000000000 --- a/src/gallium/state_trackers/dri/common/dri1_helper.h +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************** - * - * Copyright 2009, VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ -/* - * Author: Keith Whitwell <[email protected]> - * Author: Jakob Bornecrantz <[email protected]> - */ - -#ifndef DRI1_HELPER_H -#define DRI1_HELPER_H - -#include "dri_screen.h" -#include "dri_context.h" -#include "dri_drawable.h" - -struct pipe_fence_handle * -dri1_swap_fences_pop_front(struct dri_drawable *draw); - -void -dri1_swap_fences_push_back(struct dri_drawable *draw, - struct pipe_fence_handle *fence); - -void -dri1_swap_fences_clear(struct dri_drawable *drawable); - -struct pipe_surface * -dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_resource *ptex); - -void -dri1_destroy_pipe_surface(struct dri_drawable *drawable); - -struct pipe_context * -dri1_get_pipe_context(struct dri_screen *screen); - -void -dri1_destroy_pipe_context(struct dri_screen *screen); - -#endif /* DRI1_HELPER_H */ diff --git a/src/gallium/state_trackers/dri/common/dri_context.h b/src/gallium/state_trackers/dri/common/dri_context.h index b29e8533837..692c49d7cd5 100644 --- a/src/gallium/state_trackers/dri/common/dri_context.h +++ b/src/gallium/state_trackers/dri/common/dri_context.h @@ -60,6 +60,9 @@ struct dri_context /* gallium */ struct st_context_iface *st; + + /* hooks filled in by dri2 & drisw */ + __DRIimage * (*lookup_egl_image)(struct dri_context *ctx, void *handle); }; static INLINE struct dri_context * diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c index 2bc0faffeff..1bdfdccf439 100644 --- a/src/gallium/state_trackers/dri/common/dri_drawable.c +++ b/src/gallium/state_trackers/dri/common/dri_drawable.c @@ -32,7 +32,6 @@ #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" -#include "dri1_helper.h" #include "pipe/p_screen.h" #include "util/u_format.h" @@ -68,10 +67,10 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi, new_stamp = (drawable->texture_stamp != drawable->dPriv->lastStamp); if (new_stamp || new_mask || screen->broken_invalidate) { - if (new_stamp && screen->update_drawable_info) - screen->update_drawable_info(drawable); + if (new_stamp && drawable->update_drawable_info) + drawable->update_drawable_info(drawable); - screen->allocate_textures(drawable, statts, count); + drawable->allocate_textures(drawable, statts, count); /* add existing textures */ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { @@ -100,10 +99,9 @@ dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, { struct dri_drawable *drawable = (struct dri_drawable *) stfbi->st_manager_private; - struct dri_screen *screen = dri_screen(drawable->sPriv); /* XXX remove this and just set the correct one on the framebuffer */ - screen->flush_frontbuffer(drawable, statt); + drawable->flush_frontbuffer(drawable, statt); return TRUE; } @@ -138,8 +136,6 @@ dri_create_buffer(__DRIscreen * sPriv, drawable->dPriv = dPriv; dPriv->driverPrivate = (void *)drawable; - drawable->desired_fences = 2; - return GL_TRUE; fail: FREE(drawable); @@ -152,23 +148,19 @@ dri_destroy_buffer(__DRIdrawable * dPriv) struct dri_drawable *drawable = dri_drawable(dPriv); int i; - dri1_swap_fences_clear(drawable); - - dri1_destroy_pipe_surface(drawable); + pipe_surface_reference(&drawable->drisw_surface, NULL); for (i = 0; i < ST_ATTACHMENT_COUNT; i++) pipe_resource_reference(&drawable->textures[i], NULL); - drawable->desired_fences = 0; - FREE(drawable); } /** * Validate the texture at an attachment. Allocate the texture if it does not - * exist. + * exist. Used by the TFP extension. */ -void +static void dri_drawable_validate_att(struct dri_drawable *drawable, enum st_attachment_type statt) { @@ -189,11 +181,61 @@ dri_drawable_validate_att(struct dri_drawable *drawable, drawable->texture_stamp = drawable->dPriv->lastStamp - 1; - /* this calles into the manager */ drawable->base.validate(&drawable->base, statts, count, NULL); } /** + * These are used for GLX_EXT_texture_from_pixmap + */ +static void +dri_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target, + GLint format, __DRIdrawable *dPriv) +{ + struct dri_context *ctx = dri_context(pDRICtx); + struct dri_drawable *drawable = dri_drawable(dPriv); + struct pipe_resource *pt; + + dri_drawable_validate_att(drawable, ST_ATTACHMENT_FRONT_LEFT); + + pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; + + if (pt) { + enum pipe_format internal_format = pt->format; + + if (format == __DRI_TEXTURE_FORMAT_RGB) { + /* only need to cover the formats recognized by dri_fill_st_visual */ + switch (internal_format) { + case PIPE_FORMAT_B8G8R8A8_UNORM: + internal_format = PIPE_FORMAT_B8G8R8X8_UNORM; + break; + case PIPE_FORMAT_A8R8G8B8_UNORM: + internal_format = PIPE_FORMAT_X8R8G8B8_UNORM; + break; + default: + break; + } + } + + ctx->st->teximage(ctx->st, + (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT, + 0, internal_format, pt, FALSE); + } +} + +static void +dri_set_tex_buffer(__DRIcontext *pDRICtx, GLint target, + __DRIdrawable *dPriv) +{ + dri_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv); +} + +const __DRItexBufferExtension driTexBufferExtension = { + { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, + dri_set_tex_buffer, + dri_set_tex_buffer2, +}; + +/** * Get the format and binding of an attachment. */ void diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h index 5fd650ac88e..74e662d36c4 100644 --- a/src/gallium/state_trackers/dri/common/dri_drawable.h +++ b/src/gallium/state_trackers/dri/common/dri_drawable.h @@ -33,13 +33,9 @@ #include "state_tracker/st_api.h" struct pipe_surface; -struct pipe_fence_handle; struct st_framebuffer; struct dri_context; -#define DRI_SWAP_FENCES_MAX 8 -#define DRI_SWAP_FENCES_MASK 7 - struct dri_drawable { struct st_framebuffer_iface base; @@ -57,14 +53,18 @@ struct dri_drawable struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; unsigned int texture_mask, texture_stamp; - struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX]; - unsigned int head; - unsigned int tail; - unsigned int desired_fences; - unsigned int cur_fences; + /* used only by DRISW */ + struct pipe_surface *drisw_surface; + + /* hooks filled in by dri2 & drisw */ + void (*allocate_textures)(struct dri_drawable *drawable, + const enum st_attachment_type *statts, + unsigned count); - /* used only by DRI1 */ - struct pipe_surface *dri1_surface; + void (*update_drawable_info)(struct dri_drawable *drawable); + + void (*flush_frontbuffer)(struct dri_drawable *drawable, + enum st_attachment_type statt); }; static INLINE struct dri_drawable * @@ -89,9 +89,7 @@ dri_drawable_get_format(struct dri_drawable *drawable, enum pipe_format *format, unsigned *bind); -void -dri_drawable_validate_att(struct dri_drawable *drawable, - enum st_attachment_type statt); +extern const __DRItexBufferExtension driTexBufferExtension; #endif diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c index 25cad8d46c4..6ad2c7da4d6 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.c +++ b/src/gallium/state_trackers/dri/common/dri_screen.c @@ -30,20 +30,10 @@ */ #include "utils.h" -#ifndef __NOT_HAVE_DRM_H -#include "vblank.h" -#endif #include "xmlpool.h" #include "dri_screen.h" #include "dri_context.h" -#include "dri_drawable.h" -#include "dri1_helper.h" -#ifndef __NOT_HAVE_DRM_H -#include "dri2.h" -#else -#include "drisw.h" -#endif #include "util/u_inlines.h" #include "pipe/p_screen.h" @@ -303,11 +293,10 @@ dri_get_egl_image(struct st_manager *smapi, { struct dri_context *ctx = (struct dri_context *)stctxi->st_manager_private; - struct dri_screen *screen = dri_screen(ctx->sPriv); __DRIimage *img = NULL; - if (screen->lookup_egl_image) { - img = screen->lookup_egl_image(ctx, egl_image); + if (ctx->lookup_egl_image) { + img = ctx->lookup_egl_image(ctx, egl_image); } if (!img) @@ -355,8 +344,6 @@ dri_destroy_option_cache(struct dri_screen * screen) void dri_destroy_screen_helper(struct dri_screen * screen) { - dri1_destroy_pipe_context(screen); - if (screen->st_api && screen->st_api->destroy) screen->st_api->destroy(screen->st_api); @@ -366,7 +353,7 @@ dri_destroy_screen_helper(struct dri_screen * screen) dri_destroy_option_cache(screen); } -static void +void dri_destroy_screen(__DRIscreen * sPriv) { struct dri_screen *screen = dri_screen(sPriv); @@ -402,38 +389,4 @@ dri_init_screen_helper(struct dri_screen *screen, return dri_fill_in_modes(screen, pixel_bits); } -/** - * DRI driver virtual function table. - * - * DRI versions differ in their implementation of init_screen and swap_buffers. - */ -const struct __DriverAPIRec driDriverAPI = { - .DestroyScreen = dri_destroy_screen, - .CreateContext = dri_create_context, - .DestroyContext = dri_destroy_context, - .CreateBuffer = dri_create_buffer, - .DestroyBuffer = dri_destroy_buffer, - .MakeCurrent = dri_make_current, - .UnbindContext = dri_unbind_context, - -#ifndef __NOT_HAVE_DRM_H - - .GetSwapInfo = NULL, - .GetDrawableMSC = NULL, - .WaitForMSC = NULL, - .InitScreen2 = dri2_init_screen, - - .InitScreen = NULL, - .SwapBuffers = NULL, - .CopySubBuffer = NULL, - -#else - - .InitScreen = drisw_init_screen, - .SwapBuffers = drisw_swap_buffers, - -#endif - -}; - /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri/common/dri_screen.h b/src/gallium/state_trackers/dri/common/dri_screen.h index 087ae8d2a4a..53ccce145ba 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.h +++ b/src/gallium/state_trackers/dri/common/dri_screen.h @@ -64,22 +64,10 @@ struct dri_screen int fd; drmLock *drmLock; - /* hooks filled in by dri1, dri2 & drisw */ - __DRIimage * (*lookup_egl_image)(struct dri_context *ctx, void *handle); - void (*allocate_textures)(struct dri_drawable *drawable, - const enum st_attachment_type *statts, - unsigned count); - void (*update_drawable_info)(struct dri_drawable *drawable); - void (*flush_frontbuffer)(struct dri_drawable *drawable, - enum st_attachment_type statt); - /* gallium */ boolean d_depth_bits_last; boolean sd_depth_bits_last; boolean auto_fake_front; - - /* used only by DRI1 */ - struct pipe_context *dri1_pipe; }; /** cast wrapper */ @@ -132,6 +120,9 @@ dri_init_screen_helper(struct dri_screen *screen, void dri_destroy_screen_helper(struct dri_screen * screen); +void +dri_destroy_screen(__DRIscreen * sPriv); + #endif /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri/drm/Makefile b/src/gallium/state_trackers/dri/drm/Makefile index 94fa61fec73..c717b2bdeb5 100644 --- a/src/gallium/state_trackers/dri/drm/Makefile +++ b/src/gallium/state_trackers/dri/drm/Makefile @@ -17,7 +17,6 @@ C_SOURCES = \ dri_context.c \ dri_screen.c \ dri_drawable.c \ - dri1_helper.c \ dri2.c # $(TOP)/src/mesa/drivers/dri/common/utils.c \ diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript index 0c279d22366..2a0af65f9bd 100644 --- a/src/gallium/state_trackers/dri/drm/SConscript +++ b/src/gallium/state_trackers/dri/drm/SConscript @@ -21,7 +21,6 @@ if env['dri']: source = [ 'dri_context.c', 'dri_drawable.c', 'dri_screen.c', - 'dri1_helper.c', 'dri2.c', ] ) diff --git a/src/gallium/state_trackers/dri/drm/dri1_helper.c b/src/gallium/state_trackers/dri/drm/dri1_helper.c deleted file mode 120000 index c45ebf5c102..00000000000 --- a/src/gallium/state_trackers/dri/drm/dri1_helper.c +++ /dev/null @@ -1 +0,0 @@ -../common/dri1_helper.c
\ No newline at end of file diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index 5c6573fa69b..47005c17e2b 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -38,9 +38,6 @@ #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" -#include "dri2.h" - -#include "GL/internal/dri_interface.h" /** * DRI2 flush extension. @@ -70,86 +67,6 @@ static const __DRI2flushExtension dri2FlushExtension = { }; /** - * These are used for GLX_EXT_texture_from_pixmap - */ -static void -dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target, - GLint format, __DRIdrawable *dPriv) -{ - struct dri_context *ctx = dri_context(pDRICtx); - struct dri_drawable *drawable = dri_drawable(dPriv); - struct pipe_resource *pt; - - dri_drawable_validate_att(drawable, ST_ATTACHMENT_FRONT_LEFT); - - pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT]; - - if (pt) { - enum pipe_format internal_format = pt->format; - - if (format == __DRI_TEXTURE_FORMAT_RGB) { - /* only need to cover the formats recognized by dri_fill_st_visual */ - switch (internal_format) { - case PIPE_FORMAT_B8G8R8A8_UNORM: - internal_format = PIPE_FORMAT_B8G8R8X8_UNORM; - break; - case PIPE_FORMAT_A8R8G8B8_UNORM: - internal_format = PIPE_FORMAT_X8R8G8B8_UNORM; - break; - default: - break; - } - } - - ctx->st->teximage(ctx->st, - (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT, - 0, internal_format, pt, FALSE); - } -} - -static void -dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target, - __DRIdrawable *dPriv) -{ - dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv); -} - -static const __DRItexBufferExtension dri2TexBufferExtension = { - { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, - dri2_set_tex_buffer, - dri2_set_tex_buffer2, -}; - -/** - * Get the format and binding of an attachment. - */ -static INLINE void -dri2_drawable_get_format(struct dri_drawable *drawable, - enum st_attachment_type statt, - enum pipe_format *format, - unsigned *bind) -{ - switch (statt) { - case ST_ATTACHMENT_FRONT_LEFT: - case ST_ATTACHMENT_BACK_LEFT: - case ST_ATTACHMENT_FRONT_RIGHT: - case ST_ATTACHMENT_BACK_RIGHT: - *format = drawable->stvis.color_format; - *bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; - break; - case ST_ATTACHMENT_DEPTH_STENCIL: - *format = drawable->stvis.depth_stencil_format; - *bind = PIPE_BIND_DEPTH_STENCIL; /* XXX sampler? */ - break; - default: - *format = PIPE_FORMAT_NONE; - *bind = 0; - break; - } -} - - -/** * Retrieve __DRIbuffer from the DRI loader. */ static __DRIbuffer * @@ -179,7 +96,7 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable, unsigned bind; int att, bpp; - dri2_drawable_get_format(drawable, statts[i], &format, &bind); + dri_drawable_get_format(drawable, statts[i], &format, &bind); if (format == PIPE_FORMAT_NONE) continue; @@ -321,7 +238,7 @@ dri2_drawable_process_buffers(struct dri_drawable *drawable, break; } - dri2_drawable_get_format(drawable, statt, &format, &bind); + dri_drawable_get_format(drawable, statt, &format, &bind); if (statt == ST_ATTACHMENT_INVALID || format == PIPE_FORMAT_NONE) continue; @@ -354,7 +271,8 @@ dri2_allocate_textures(struct dri_drawable *drawable, unsigned num_buffers = count; buffers = dri2_drawable_get_buffers(drawable, statts, &num_buffers); - dri2_drawable_process_buffers(drawable, buffers, num_buffers); + if (buffers) + dri2_drawable_process_buffers(drawable, buffers, num_buffers); } static void @@ -485,7 +403,7 @@ static const __DRIextension *dri_screen_extensions[] = { &driCopySubBufferExtension.base, &driSwapControlExtension.base, &driMediaStreamCounterExtension.base, - &dri2TexBufferExtension.base, + &driTexBufferExtension.base, &dri2FlushExtension.base, &dri2ImageExtension.base, &dri2ConfigQueryExtension.base, @@ -497,7 +415,7 @@ static const __DRIextension *dri_screen_extensions[] = { * * Returns the __GLcontextModes supported by this driver. */ -const __DRIconfig ** +static const __DRIconfig ** dri2_init_screen(__DRIscreen * sPriv) { const __DRIconfig **configs; @@ -510,9 +428,6 @@ dri2_init_screen(__DRIscreen * sPriv) screen->sPriv = sPriv; screen->fd = sPriv->fd; - screen->lookup_egl_image = dri2_lookup_egl_image; - screen->allocate_textures = dri2_allocate_textures; - screen->flush_frontbuffer = dri2_flush_frontbuffer; sPriv->private = (void *)screen; sPriv->extensions = dri_screen_extensions; @@ -534,6 +449,64 @@ fail: return NULL; } +static boolean +dri2_create_context(gl_api api, const __GLcontextModes * visual, + __DRIcontext * cPriv, void *sharedContextPrivate) +{ + struct dri_context *ctx = NULL; + + if (!dri_create_context(api, visual, cPriv, sharedContextPrivate)) + return FALSE; + + ctx = cPriv->driverPrivate; + + ctx->lookup_egl_image = dri2_lookup_egl_image; + + return TRUE; +} + +static boolean +dri2_create_buffer(__DRIscreen * sPriv, + __DRIdrawable * dPriv, + const __GLcontextModes * visual, boolean isPixmap) +{ + struct dri_drawable *drawable = NULL; + + if (!dri_create_buffer(sPriv, dPriv, visual, isPixmap)) + return FALSE; + + drawable = dPriv->driverPrivate; + + drawable->allocate_textures = dri2_allocate_textures; + drawable->flush_frontbuffer = dri2_flush_frontbuffer; + + return TRUE; +} + +/** + * DRI driver virtual function table. + * + * DRI versions differ in their implementation of init_screen and swap_buffers. + */ +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = NULL, + .InitScreen2 = dri2_init_screen, + .DestroyScreen = dri_destroy_screen, + .CreateContext = dri2_create_context, + .DestroyContext = dri_destroy_context, + .CreateBuffer = dri2_create_buffer, + .DestroyBuffer = dri_destroy_buffer, + .MakeCurrent = dri_make_current, + .UnbindContext = dri_unbind_context, + + .GetSwapInfo = NULL, + .GetDrawableMSC = NULL, + .WaitForMSC = NULL, + + .SwapBuffers = NULL, + .CopySubBuffer = NULL, +}; + /* This is the table of extensions that the loader will dlsym() for. */ PUBLIC const __DRIextension *__driDriverExtensions[] = { &driCoreExtension.base, diff --git a/src/gallium/state_trackers/dri/sw/Makefile b/src/gallium/state_trackers/dri/sw/Makefile index a1dadeba5e6..33bc0ed9c94 100644 --- a/src/gallium/state_trackers/dri/sw/Makefile +++ b/src/gallium/state_trackers/dri/sw/Makefile @@ -20,7 +20,6 @@ C_SOURCES = \ dri_context.c \ dri_screen.c \ dri_drawable.c \ - dri1_helper.c \ drisw.c include ../../../Makefile.template diff --git a/src/gallium/state_trackers/dri/sw/SConscript b/src/gallium/state_trackers/dri/sw/SConscript index 0c5194d6edc..d2eb66668e0 100644 --- a/src/gallium/state_trackers/dri/sw/SConscript +++ b/src/gallium/state_trackers/dri/sw/SConscript @@ -21,7 +21,6 @@ if env['dri']: source = [ 'dri_context.c', 'dri_drawable.c', 'dri_screen.c', - 'dri1_helper.c', 'drisw.c', ] ) diff --git a/src/gallium/state_trackers/dri/sw/dri1_helper.c b/src/gallium/state_trackers/dri/sw/dri1_helper.c deleted file mode 120000 index c45ebf5c102..00000000000 --- a/src/gallium/state_trackers/dri/sw/dri1_helper.c +++ /dev/null @@ -1 +0,0 @@ -../common/dri1_helper.c
\ No newline at end of file diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c index 23e99aa0add..249ccd7fcf6 100644 --- a/src/gallium/state_trackers/dri/sw/drisw.c +++ b/src/gallium/state_trackers/dri/sw/drisw.c @@ -43,9 +43,9 @@ #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" -#include "dri1_helper.h" -#include "drisw.h" +DEBUG_GET_ONCE_BOOL_OPTION(swrast_no_present, "SWRAST_NO_PRESENT", FALSE); +static boolean swrast_no_present = FALSE; static INLINE void get_drawable_info(__DRIdrawable *dPriv, int *w, int *h) @@ -87,6 +87,24 @@ drisw_put_image(struct dri_drawable *drawable, put_image(dPriv, data, width, height); } +static struct pipe_surface * +drisw_get_pipe_surface(struct dri_drawable *drawable, struct pipe_resource *ptex) +{ + struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->base.screen; + struct pipe_surface *psurf = drawable->drisw_surface; + + if (!psurf || psurf->texture != ptex) { + pipe_surface_reference(&drawable->drisw_surface, NULL); + + drawable->drisw_surface = pipe_screen->get_tex_surface(pipe_screen, + ptex, 0, 0, 0, 0/* no bind flag???*/); + + psurf = drawable->drisw_surface; + } + + return psurf; +} + static INLINE void drisw_present_texture(__DRIdrawable *dPriv, struct pipe_resource *ptex) @@ -95,7 +113,10 @@ drisw_present_texture(__DRIdrawable *dPriv, struct dri_screen *screen = dri_screen(drawable->sPriv); struct pipe_surface *psurf; - psurf = dri1_get_pipe_surface(drawable, ptex); + if (swrast_no_present) + return; + + psurf = drisw_get_pipe_surface(drawable, ptex); if (!psurf) return; @@ -128,7 +149,7 @@ drisw_copy_to_front(__DRIdrawable * dPriv, * Backend functions for st_framebuffer interface and swap_buffers. */ -void +static void drisw_swap_buffers(__DRIdrawable *dPriv) { struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv); @@ -170,10 +191,6 @@ drisw_flush_frontbuffer(struct dri_drawable *drawable, * During fixed-size operation, the function keeps allocating new attachments * as they are requested. Unused attachments are not removed, not until the * framebuffer is resized or destroyed. - * - * It should be possible for DRI1 and DRISW to share this function, but it - * seems a better seperation and safer for each DRI version to provide its own - * function. */ static void drisw_allocate_textures(struct dri_drawable *drawable, @@ -184,7 +201,7 @@ drisw_allocate_textures(struct dri_drawable *drawable, struct pipe_resource templ; unsigned width, height; boolean resized; - int i; + unsigned i; width = drawable->dPriv->w; height = drawable->dPriv->h; @@ -205,7 +222,7 @@ drisw_allocate_textures(struct dri_drawable *drawable, templ.depth0 = 1; templ.last_level = 0; - for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { + for (i = 0; i < count; i++) { enum pipe_format format; unsigned bind; @@ -215,7 +232,8 @@ drisw_allocate_textures(struct dri_drawable *drawable, dri_drawable_get_format(drawable, statts[i], &format, &bind); - if (statts[i] != ST_ATTACHMENT_DEPTH_STENCIL) + /* if we don't do any present, no need for display targets */ + if (statts[i] != ST_ATTACHMENT_DEPTH_STENCIL && !swrast_no_present) bind |= PIPE_BIND_DISPLAY_TARGET; if (format == PIPE_FORMAT_NONE) @@ -244,7 +262,7 @@ static struct drisw_loader_funcs drisw_lf = { .put_image = drisw_put_image }; -const __DRIconfig ** +static const __DRIconfig ** drisw_init_screen(__DRIscreen * sPriv) { const __DRIconfig **configs; @@ -257,9 +275,8 @@ drisw_init_screen(__DRIscreen * sPriv) screen->sPriv = sPriv; screen->fd = -1; - screen->allocate_textures = drisw_allocate_textures; - screen->update_drawable_info = drisw_update_drawable_info; - screen->flush_frontbuffer = drisw_flush_frontbuffer; + + swrast_no_present = debug_get_option_swrast_no_present(); sPriv->private = (void *)screen; sPriv->extensions = drisw_screen_extensions; @@ -278,6 +295,43 @@ fail: return NULL; } +static boolean +drisw_create_buffer(__DRIscreen * sPriv, + __DRIdrawable * dPriv, + const __GLcontextModes * visual, boolean isPixmap) +{ + struct dri_drawable *drawable = NULL; + + if (!dri_create_buffer(sPriv, dPriv, visual, isPixmap)) + return FALSE; + + drawable = dPriv->driverPrivate; + + drawable->allocate_textures = drisw_allocate_textures; + drawable->update_drawable_info = drisw_update_drawable_info; + drawable->flush_frontbuffer = drisw_flush_frontbuffer; + + return TRUE; +} + +/** + * DRI driver virtual function table. + * + * DRI versions differ in their implementation of init_screen and swap_buffers. + */ +const struct __DriverAPIRec driDriverAPI = { + .InitScreen = drisw_init_screen, + .DestroyScreen = dri_destroy_screen, + .CreateContext = dri_create_context, + .DestroyContext = dri_destroy_context, + .CreateBuffer = drisw_create_buffer, + .DestroyBuffer = dri_destroy_buffer, + .MakeCurrent = dri_make_current, + .UnbindContext = dri_unbind_context, + + .SwapBuffers = drisw_swap_buffers, +}; + /* This is the table of extensions that the loader will dlsym() for. */ PUBLIC const __DRIextension *__driDriverExtensions[] = { &driCoreExtension.base, diff --git a/src/gallium/state_trackers/dri/sw/drisw.h b/src/gallium/state_trackers/dri/sw/drisw.h deleted file mode 100644 index 6c6c891f356..00000000000 --- a/src/gallium/state_trackers/dri/sw/drisw.h +++ /dev/null @@ -1,43 +0,0 @@ -/************************************************************************** - * - * Copyright 2009, VMware, Inc. - * All Rights Reserved. - * Copyright 2010 George Sapountzis <[email protected]> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef DRISW_H -#define DRISW_H - -#include "dri_context.h" -#include "dri_drawable.h" - -#include "state_tracker/st_api.h" -#include "dri_wrapper.h" - -const __DRIconfig ** -drisw_init_screen(__DRIscreen * sPriv); - -void drisw_swap_buffers(__DRIdrawable * dPriv); - -#endif /* DRISW_H */ diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index b6321e6b437..56d575ffe08 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -434,9 +434,11 @@ egl_g3d_free_config(void *conf) static void egl_g3d_free_screen(void *scr) { +#ifdef EGL_MESA_screen_surface struct egl_g3d_screen *gscr = egl_g3d_screen((_EGLScreen *) scr); FREE(gscr->native_modes); FREE(gscr); +#endif } static EGLBoolean diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h index ed2b0409bb9..f33dc91cf90 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.h +++ b/src/gallium/state_trackers/egl/common/egl_g3d.h @@ -95,15 +95,19 @@ struct egl_g3d_image { unsigned zslice; }; +/* standard typecasts */ +_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d) +_EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj) + +#ifdef EGL_MESA_screen_surface + struct egl_g3d_screen { _EGLScreen base; const struct native_connector *native; const struct native_mode **native_modes; }; - -/* standard typecasts */ -_EGL_DRIVER_STANDARD_TYPECASTS(egl_g3d) _EGL_DRIVER_TYPECAST(egl_g3d_screen, _EGLScreen, obj) -_EGL_DRIVER_TYPECAST(egl_g3d_image, _EGLImage, obj) + +#endif /* EGL_MESA_screen_surface */ #endif /* _EGL_G3D_H_ */ diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c index b1fe30a776c..1e13cfcf7e9 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c @@ -78,7 +78,7 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, gimg = CALLOC_STRUCT(egl_g3d_image); if (!gimg) { - _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface"); + _eglError(EGL_BAD_ALLOC, "eglCreateEGLImageKHR"); return NULL; } diff --git a/src/gallium/state_trackers/egl/x11/glxinit.c b/src/gallium/state_trackers/egl/x11/glxinit.c index 809a0987e55..57c6aaff864 100644 --- a/src/gallium/state_trackers/egl/x11/glxinit.c +++ b/src/gallium/state_trackers/egl/x11/glxinit.c @@ -10,10 +10,16 @@ #include <assert.h> #include <X11/Xlib.h> #include <X11/Xproto.h> +#include <X11/Xlibint.h> #include <X11/extensions/Xext.h> #include <X11/extensions/extutil.h> #include <sys/time.h> +#include "GL/glxproto.h" +#include "GL/glxtokens.h" +#include "GL/gl.h" /* for GL types needed by __GLcontextModes */ +#include "GL/internal/glcore.h" /* for __GLcontextModes */ + #include "glxinit.h" #ifdef GLX_DIRECT_RENDERING @@ -55,9 +61,9 @@ static /* const */ XExtensionHooks __glXExtensionHooks = { NULL, /* error_string */ }; -XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, - __glXExtensionName, &__glXExtensionHooks, - __GLX_NUMBER_EVENTS, NULL) +static XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo, + __glXExtensionName, &__glXExtensionHooks, + __GLX_NUMBER_EVENTS, NULL) static GLint _gl_convert_from_x_visual_type(int visualType) @@ -73,6 +79,17 @@ _gl_convert_from_x_visual_type(int visualType) ? glx_visual_types[visualType] : GLX_NONE; } +static void +_gl_context_modes_destroy(__GLcontextModes * modes) +{ + while (modes != NULL) { + __GLcontextModes *const next = modes->next; + + Xfree(modes); + modes = next; + } +} + static __GLcontextModes * _gl_context_modes_create(unsigned count, size_t minimum_size) { @@ -116,18 +133,7 @@ _gl_context_modes_create(unsigned count, size_t minimum_size) return base; } -_X_HIDDEN void -_gl_context_modes_destroy(__GLcontextModes * modes) -{ - while (modes != NULL) { - __GLcontextModes *const next = modes->next; - - Xfree(modes); - modes = next; - } -} - -_X_HIDDEN char * +static char * __glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name) { xGLXGenericGetStringReq *req; @@ -194,10 +200,6 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv) _gl_context_modes_destroy(psc->configs); psc->configs = NULL; /* NOTE: just for paranoia */ } - if (psc->visuals) { - _gl_context_modes_destroy(psc->visuals); - psc->visuals = NULL; /* NOTE: just for paranoia */ - } Xfree((char *) psc->serverGLXexts); } XFree((char *) priv->screenConfigs); @@ -215,14 +217,8 @@ __glXFreeDisplayPrivate(XExtData * extension) priv = (__GLXdisplayPrivate *) extension->private_data; FreeScreenConfigs(priv); - if (priv->serverGLXvendor) { - Xfree((char *) priv->serverGLXvendor); - priv->serverGLXvendor = 0x0; /* to protect against double free's */ - } - if (priv->serverGLXversion) { + if (priv->serverGLXversion) Xfree((char *) priv->serverGLXversion); - priv->serverGLXversion = 0x0; /* to protect against double free's */ - } Xfree((char *) priv); return 0; @@ -234,6 +230,10 @@ __glXFreeDisplayPrivate(XExtData * extension) ** Query the version of the GLX extension. This procedure works even if ** the client extension is not completely set up. */ + +#define GLX_MAJOR_VERSION 1 /* current version numbers */ +#define GLX_MINOR_VERSION 4 + static Bool QueryVersion(Display * dpy, int opcode, int *major, int *minor) { @@ -263,7 +263,13 @@ QueryVersion(Display * dpy, int opcode, int *major, int *minor) return GL_TRUE; } -_X_HIDDEN void +#define __GLX_MIN_CONFIG_PROPS 18 +#define __GLX_MAX_CONFIG_PROPS 500 +#define __GLX_EXT_CONFIG_PROPS 10 +#define __GLX_TOTAL_CONFIG (__GLX_MIN_CONFIG_PROPS + \ + 2 * __GLX_EXT_CONFIG_PROPS) + +static void __glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count, const INT32 * bp, Bool tagged_only, Bool fbconfig_style_tags) @@ -506,35 +512,6 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, } static GLboolean -getVisualConfigs(__GLXscreenConfigs *psc, - __GLXdisplayPrivate *priv, int screen) -{ - xGLXGetVisualConfigsReq *req; - xGLXGetVisualConfigsReply reply; - Display *dpy = priv->dpy; - - LockDisplay(dpy); - - psc->visuals = NULL; - GetReq(GLXGetVisualConfigs, req); - req->reqType = priv->majorOpcode; - req->glxCode = X_GLXGetVisualConfigs; - req->screen = screen; - - if (!_XReply(dpy, (xReply *) & reply, 0, False)) - goto out; - - psc->visuals = createConfigsFromProperties(dpy, - reply.numVisuals, - reply.numProps, - screen, GL_FALSE); - - out: - UnlockDisplay(dpy); - return psc->visuals != NULL; -} - -static GLboolean getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen) { xGLXGetFBConfigsReq *fb_req; @@ -581,32 +558,6 @@ getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen) return psc->configs != NULL; } -_X_HIDDEN Bool -glx_screen_init(__GLXscreenConfigs *psc, - int screen, __GLXdisplayPrivate * priv) -{ - /* Initialize per screen dynamic client GLX extensions */ - psc->ext_list_first_time = GL_TRUE; - psc->scr = screen; - psc->dpy = priv->dpy; - - getVisualConfigs(psc, priv, screen); - getFBConfigs(psc, priv, screen); - - return GL_TRUE; -} - -static __GLXscreenConfigs * -createIndirectScreen() -{ - __GLXscreenConfigs *psc; - - psc = Xmalloc(sizeof *psc); - memset(psc, 0, sizeof *psc); - - return psc; -} - static GLboolean AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) { @@ -630,10 +581,10 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) } for (i = 0; i < screens; i++) { - psc = createIndirectScreen(); + psc = Xcalloc(1, sizeof *psc); if (!psc) return GL_FALSE; - glx_screen_init(psc, i, priv); + getFBConfigs(psc, priv, i); priv->screenConfigs[i] = psc; } @@ -682,13 +633,8 @@ __glXInitialize(Display * dpy) ** structures from the server. */ dpyPriv->majorOpcode = info->codes->major_opcode; - dpyPriv->majorVersion = major; - dpyPriv->minorVersion = minor; dpyPriv->dpy = dpy; - dpyPriv->serverGLXvendor = NULL; - dpyPriv->serverGLXversion = NULL; - if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) { Xfree(dpyPriv); Xfree(private); diff --git a/src/gallium/state_trackers/egl/x11/glxinit.h b/src/gallium/state_trackers/egl/x11/glxinit.h index 1cc7c460fe2..4078aef2fee 100644 --- a/src/gallium/state_trackers/egl/x11/glxinit.h +++ b/src/gallium/state_trackers/egl/x11/glxinit.h @@ -2,10 +2,21 @@ #define GLXINIT_INCLUDED #include <X11/Xlib.h> -#include "glxclient.h" +#include <GL/gl.h> -/* this is used by DRI loaders */ -extern void -_gl_context_modes_destroy(__GLcontextModes * modes); +typedef struct { + __GLcontextModes *configs; + char *serverGLXexts; +} __GLXscreenConfigs; + +typedef struct { + Display *dpy; + __GLXscreenConfigs **screenConfigs; + char *serverGLXversion; + int majorOpcode; + struct x11_screen *xscr; +} __GLXdisplayPrivate; + +extern __GLXdisplayPrivate *__glXInitialize(Display * dpy); #endif /* GLXINIT_INCLUDED */ diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c index bc6482ab15d..c07ebb7ef6c 100644 --- a/src/gallium/state_trackers/egl/x11/x11_screen.c +++ b/src/gallium/state_trackers/egl/x11/x11_screen.c @@ -39,11 +39,6 @@ #include "glxinit.h" struct x11_screen { -#ifdef GLX_DIRECT_RENDERING - /* dummy base class */ - struct __GLXDRIdisplayRec base; -#endif - Display *dpy; int number; @@ -108,7 +103,7 @@ x11_screen_destroy(struct x11_screen *xscr) #ifdef GLX_DIRECT_RENDERING /* xscr->glx_dpy will be destroyed with the X display */ if (xscr->glx_dpy) - xscr->glx_dpy->dri2Display = NULL; + xscr->glx_dpy->xscr = NULL; #endif if (xscr->visuals) @@ -231,17 +226,6 @@ x11_screen_get_glx_configs(struct x11_screen *xscr) } /** - * Return the GLX visuals. - */ -const __GLcontextModes * -x11_screen_get_glx_visuals(struct x11_screen *xscr) -{ - return (x11_screen_init_glx(xscr)) - ? xscr->glx_dpy->screenConfigs[xscr->number]->visuals - : NULL; -} - -/** * Probe the screen for the DRI2 driver name. */ const char * @@ -306,14 +290,14 @@ x11_screen_enable_dri2(struct x11_screen *xscr, close(fd); return -1; } - if (xscr->glx_dpy->dri2Display) { + if (xscr->glx_dpy->xscr) { _eglLog(_EGL_WARNING, "display is already managed by another x11 screen"); close(fd); return -1; } - xscr->glx_dpy->dri2Display = (__GLXDRIdisplay *) xscr; + xscr->glx_dpy->xscr = xscr; xscr->dri_invalidate_buffers = invalidate_buffers; xscr->dri_user_data = user_data; @@ -428,6 +412,9 @@ x11_context_modes_count(const __GLcontextModes *modes) return count; } +extern void +dri2InvalidateBuffers(Display *dpy, XID drawable); + /** * This is called from src/glx/dri2.c. */ @@ -437,8 +424,8 @@ dri2InvalidateBuffers(Display *dpy, XID drawable) __GLXdisplayPrivate *priv = __glXInitialize(dpy); struct x11_screen *xscr = NULL; - if (priv && priv->dri2Display) - xscr = (struct x11_screen *) priv->dri2Display; + if (priv && priv->xscr) + xscr = priv->xscr; if (!xscr || !xscr->dri_invalidate_buffers) return; diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index cf0144b5dc6..40c4603fb9d 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -289,6 +289,20 @@ struct st_context { $self->vertex_buffers); } + void set_index_buffer(unsigned index_size, + unsigned offset, + struct pipe_resource *buffer) + { + struct pipe_index_buffer ib; + + memset(&ib, 0, sizeof(ib)); + ib.index_size = index_size; + ib.offset = offset; + ib.buffer = buffer; + + $self->pipe->set_index_buffer($self->pipe, &ib); + } + void set_vertex_element(unsigned index, const struct pipe_vertex_element *element) { @@ -308,29 +322,12 @@ struct st_context { */ void draw_arrays(unsigned mode, unsigned start, unsigned count) { - $self->pipe->draw_arrays($self->pipe, mode, start, count); - } - - void draw_elements( struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned mode, unsigned start, unsigned count) - { - $self->pipe->draw_elements($self->pipe, - indexBuffer, - indexSize, - indexBias, - mode, start, count); + util_draw_arrays($self->pipe, mode, start, count); } - void draw_range_elements( struct pipe_resource *indexBuffer, - unsigned indexSize, int indexBias, - unsigned minIndex, unsigned maxIndex, - unsigned mode, unsigned start, unsigned count) + void draw_vbo(const struct pipe_draw_info *info) { - $self->pipe->draw_range_elements($self->pipe, - indexBuffer, indexSize, indexBias, - minIndex, maxIndex, - mode, start, count); + $self->pipe->draw_vbo($self->pipe, info); } void draw_vertices(unsigned prim, @@ -382,7 +379,7 @@ struct st_context { pipe->set_vertex_buffers(pipe, 1, &vbuffer); /* draw */ - pipe->draw_arrays(pipe, prim, 0, num_verts); + util_draw_arrays(pipe, prim, 0, num_verts); cso_restore_vertex_elements($self->cso); diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c index e9c8f031373..bc94170eb96 100644 --- a/src/gallium/state_trackers/vega/polygon.c +++ b/src/gallium/state_trackers/vega/polygon.c @@ -301,8 +301,7 @@ static void draw_polygon(struct vg_context *ctx, cso_set_vertex_elements(ctx->cso_context, 1, &velement); /* draw */ - pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, - 0, poly->num_verts); + util_draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, (uint) poly->num_verts); } void polygon_fill(struct polygon *poly, struct vg_context *ctx) diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index e993ccc9bf0..e10ff2f9508 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -472,7 +472,6 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) max_height = max < max_height ? max : max_height; } - drmModeFreeResources(res); xf86CrtcSetSizeRange(pScrn, res->min_width, res->min_height, max_width, max_height); xf86DrvMsg(pScrn->scrnIndex, X_PROBED, @@ -481,6 +480,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Min height %d, Max Height %d.\n", res->min_height, max_height); + drmModeFreeResources(res); } diff --git a/src/gallium/targets/Makefile.xorg b/src/gallium/targets/Makefile.xorg index c2d00649789..762c905985e 100644 --- a/src/gallium/targets/Makefile.xorg +++ b/src/gallium/targets/Makefile.xorg @@ -42,7 +42,7 @@ endif default: depend $(TOP)/$(LIB_DIR)/gallium $(LIBNAME) $(LIBNAME_STAGING) $(LIBNAME): $(OBJECTS) Makefile ../Makefile.xorg $(LIBS) $(DRIVER_PIPES) - $(MKLIB) -noprefix -o $@ $(OBJECTS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $(DRIVER_LINKS) + $(MKLIB) -noprefix -o $@ $(LDFLAGS) $(OBJECTS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $(DRIVER_LINKS) depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) $(GENERATED_SOURCES) rm -f depend diff --git a/src/gallium/targets/dri-i915/Makefile b/src/gallium/targets/dri-i915/Makefile index e88c3c9f66a..9c10d71a4a6 100644 --- a/src/gallium/targets/dri-i915/Makefile +++ b/src/gallium/targets/dri-i915/Makefile @@ -22,7 +22,7 @@ DRIVER_DEFINES = \ -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD -DGALLIUM_SOFTPIPE ifeq ($(MESA_LLVM),1) -DRIVER_DEFINS += -DGALLIUM_LLVMPIPE +DRIVER_DEFINES += -DGALLIUM_LLVMPIPE endif include ../Makefile.dri diff --git a/src/gallium/targets/dri-i965/Makefile b/src/gallium/targets/dri-i965/Makefile index 3679c075b24..4b50d04255f 100644 --- a/src/gallium/targets/dri-i965/Makefile +++ b/src/gallium/targets/dri-i965/Makefile @@ -6,10 +6,11 @@ LIBNAME = i965_dri.so PIPE_DRIVERS = \ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \ - $(TOP)/src/gallium/drivers/trace/libtrace.a \ - $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ + $(TOP)/src/gallium/drivers/galahad/libgalahad.a \ + $(TOP)/src/gallium/drivers/trace/libtrace.a \ + $(TOP)/src/gallium/drivers/rbug/librbug.a \ $(TOP)/src/gallium/drivers/i965/libi965.a C_SOURCES = \ @@ -18,7 +19,11 @@ C_SOURCES = \ $(DRIVER_SOURCES) DRIVER_DEFINES = \ - -DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE + -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD -DGALLIUM_SOFTPIPE + +ifeq ($(MESA_LLVM),1) +DRIVER_DEFINES += -DGALLIUM_LLVMPIPE +endif include ../Makefile.dri diff --git a/src/gallium/targets/dri-r600/SConscript b/src/gallium/targets/dri-r600/SConscript index 97c5df01fe2..64d6d2a7f6f 100644 --- a/src/gallium/targets/dri-r600/SConscript +++ b/src/gallium/targets/dri-r600/SConscript @@ -12,7 +12,7 @@ env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE']) env.Prepend(LIBS = [ st_dri, - r600drm, + r600winsys, r600, trace, rbug, diff --git a/src/gallium/targets/egl/st_GL.c b/src/gallium/targets/egl/st_GL.c index 676300b0cc1..17b7bf9d481 100644 --- a/src/gallium/targets/egl/st_GL.c +++ b/src/gallium/targets/egl/st_GL.c @@ -1,4 +1,5 @@ #include "state_tracker/st_gl_api.h" +#include "state_tracker/st_api.h" #if FEATURE_GL PUBLIC struct st_api * diff --git a/src/gallium/targets/egl/st_GLESv1_CM.c b/src/gallium/targets/egl/st_GLESv1_CM.c index 0c8de8992f3..c1652d5131a 100644 --- a/src/gallium/targets/egl/st_GLESv1_CM.c +++ b/src/gallium/targets/egl/st_GLESv1_CM.c @@ -1,3 +1,4 @@ +#include "state_tracker/st_api.h" #include "state_tracker/st_gl_api.h" PUBLIC struct st_api * diff --git a/src/gallium/targets/egl/st_GLESv2.c b/src/gallium/targets/egl/st_GLESv2.c index 87b3e65e239..9c269890089 100644 --- a/src/gallium/targets/egl/st_GLESv2.c +++ b/src/gallium/targets/egl/st_GLESv2.c @@ -1,3 +1,4 @@ +#include "state_tracker/st_api.h" #include "state_tracker/st_gl_api.h" PUBLIC struct st_api * diff --git a/src/gallium/tests/graw/SConscript b/src/gallium/tests/graw/SConscript index 61121732e38..860a17e13e7 100644 --- a/src/gallium/tests/graw/SConscript +++ b/src/gallium/tests/graw/SConscript @@ -11,6 +11,12 @@ env = env.Clone() env.Prepend(LIBPATH = [graw.dir]) env.Prepend(LIBS = ['graw'] + gallium) +if platform in ('freebsd8', 'sunos5'): + env.Append(LIBS = ['m']) + +if platform == 'freebsd8': + env.Append(LIBS = ['pthread']) + progs = [ 'clear', 'tri', diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c index dea087357d6..53fbb744d86 100644 --- a/src/gallium/tests/graw/fs-test.c +++ b/src/gallium/tests/graw/fs-test.c @@ -13,6 +13,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" #include "util/u_box.h" static const char *filename = NULL; @@ -275,7 +276,7 @@ static void draw( void ) float clear_color[4] = {.1,.3,.5,0}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); #if 0 diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c index 3087d446fca..62714900bd9 100644 --- a/src/gallium/tests/graw/gs-test.c +++ b/src/gallium/tests/graw/gs-test.c @@ -13,6 +13,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" #include "util/u_box.h" static const char *filename = NULL; @@ -336,9 +337,9 @@ static void draw( void ) ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); if (draw_strip) - ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); else - ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); diff --git a/src/gallium/tests/graw/quad-tex.c b/src/gallium/tests/graw/quad-tex.c index 6a0a2ba2950..c50ef12ab5a 100644 --- a/src/gallium/tests/graw/quad-tex.c +++ b/src/gallium/tests/graw/quad-tex.c @@ -12,6 +12,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" #include "util/u_box.h" enum pipe_format formats[] = { @@ -146,7 +147,7 @@ static void draw( void ) float clear_color[4] = {.5,.5,.5,1}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4); + util_draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); #if 0 diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c index d187505f8d4..152ae408eb0 100644 --- a/src/gallium/tests/graw/tri-gs.c +++ b/src/gallium/tests/graw/tri-gs.c @@ -10,6 +10,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" enum pipe_format formats[] = { PIPE_FORMAT_R8G8B8A8_UNORM, @@ -161,7 +162,7 @@ static void draw( void ) float clear_color[4] = {1,0,1,1}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); screen->flush_frontbuffer(screen, surf, window); diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c index 30e205f1434..8859f745fdb 100644 --- a/src/gallium/tests/graw/tri-instanced.c +++ b/src/gallium/tests/graw/tri-instanced.c @@ -13,6 +13,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" enum pipe_format formats[] = { @@ -27,7 +28,6 @@ static const int HEIGHT = 300; static struct pipe_screen *screen = NULL; static struct pipe_context *ctx = NULL; static struct pipe_surface *surf = NULL; -static struct pipe_resource *indexBuffer = NULL; static void *window = NULL; struct vertex { @@ -105,6 +105,7 @@ static void set_vertices( void ) { struct pipe_vertex_element ve[3]; struct pipe_vertex_buffer vbuf[2]; + struct pipe_index_buffer ibuf; void *handle; memset(ve, 0, sizeof ve); @@ -151,11 +152,14 @@ static void set_vertices( void ) ctx->set_vertex_buffers(ctx, 2, vbuf); /* index data */ - indexBuffer = screen->user_buffer_create(screen, + ibuf.buffer = screen->user_buffer_create(screen, indices, sizeof(indices), PIPE_BIND_VERTEX_BUFFER); + ibuf.offset = 0; + ibuf.index_size = 2; + ctx->set_index_buffer(ctx, &ibuf); } @@ -195,18 +199,19 @@ static void set_fragment_shader( void ) static void draw( void ) { float clear_color[4] = {1,0,1,1}; + struct pipe_draw_info info; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); + util_draw_init_info(&info); + info.indexed = (draw_elements != 0); + info.mode = PIPE_PRIM_TRIANGLES; + info.start = 0; + info.count = 3; /* draw NUM_INST triangles */ - if (draw_elements) - ctx->draw_elements_instanced(ctx, indexBuffer, 2, - 0, /* indexBias */ - PIPE_PRIM_TRIANGLES, - 0, 3, /* start, count */ - 0, NUM_INST); /* startInst, instCount */ - else - ctx->draw_arrays_instanced(ctx, PIPE_PRIM_TRIANGLES, 0, 3, 0, NUM_INST); + info.instance_count = NUM_INST; + + ctx->draw_vbo(ctx, &info); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); diff --git a/src/gallium/tests/graw/tri.c b/src/gallium/tests/graw/tri.c index 80377f526d6..4dbd2c062a5 100644 --- a/src/gallium/tests/graw/tri.c +++ b/src/gallium/tests/graw/tri.c @@ -10,6 +10,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" enum pipe_format formats[] = { PIPE_FORMAT_R8G8B8A8_UNORM, @@ -134,7 +135,7 @@ static void draw( void ) float clear_color[4] = {1,0,1,1}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); + util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); #if 0 diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c index 7f93db42c0d..e1cd814bf72 100644 --- a/src/gallium/tests/graw/vs-test.c +++ b/src/gallium/tests/graw/vs-test.c @@ -14,6 +14,7 @@ #include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ +#include "util/u_draw_quad.h" #include "util/u_box.h" static const char *filename = NULL; @@ -226,7 +227,7 @@ static void draw( void ) float clear_color[4] = {.1,.3,.5,0}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->draw_arrays(ctx, PIPE_PRIM_POINTS, 0, Elements(vertices)); + util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, Elements(vertices)); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); #if 0 diff --git a/src/gallium/tests/unit/Makefile b/src/gallium/tests/unit/Makefile index f65958dadd5..345bd1f6941 100644 --- a/src/gallium/tests/unit/Makefile +++ b/src/gallium/tests/unit/Makefile @@ -22,7 +22,8 @@ SOURCES = \ pipe_barrier_test.c \ u_cache_test.c \ u_half_test.c \ - u_format_test.c + u_format_test.c \ + translate_test.c OBJECTS = $(SOURCES:.c=.o) diff --git a/src/gallium/tests/unit/SConscript b/src/gallium/tests/unit/SConscript index 8a9f3504c75..edc68e34d9e 100644 --- a/src/gallium/tests/unit/SConscript +++ b/src/gallium/tests/unit/SConscript @@ -4,11 +4,18 @@ env = env.Clone() env.Prepend(LIBS = [gallium]) +if platform in ('freebsd8', 'sunos5'): + env.Append(LIBS = ['m']) + +if platform == 'freebsd8': + env.Append(LIBS = ['pthread']) + progs = [ 'pipe_barrier_test', 'u_cache_test', 'u_format_test', - 'u_half_test' + 'u_half_test', + 'translate_test' ] for prog in progs: diff --git a/src/gallium/tests/unit/translate_test.c b/src/gallium/tests/unit/translate_test.c new file mode 100644 index 00000000000..d0946a91a26 --- /dev/null +++ b/src/gallium/tests/unit/translate_test.c @@ -0,0 +1,310 @@ +/************************************************************************** + * + * Copyright © 2010 Luca Barbieri + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <stdio.h> +#include <translate/translate.h> +#include <util/u_memory.h> +#include <util/u_format.h> +#include <util/u_cpu_detect.h> +#include <rtasm/rtasm_cpu.h> + +/* don't use this for serious use */ +static double rand_double() +{ + const double rm = (double)RAND_MAX + 1; + double div = 1; + double v = 0; + unsigned i; + for(i = 0; i < 4; ++i) + { + div *= rm; + v += (double)rand() / div; + } + return v; +} + +int main(int argc, char** argv) +{ + struct translate *(*create_fn)(const struct translate_key *key) = 0; + + struct translate_key key; + unsigned output_format; + unsigned input_format; + unsigned buffer_size = 4096; + unsigned char* buffer[5]; + unsigned char* byte_buffer; + float* float_buffer; + double* double_buffer; + unsigned count = 4; + unsigned i, j, k; + unsigned passed = 0; + unsigned total = 0; + const float error = 0.03125; + + create_fn = 0; + + util_cpu_detect(); + + if(argc <= 1) + {} + else if (!strcmp(argv[1], "generic")) + create_fn = translate_generic_create; + else if (!strcmp(argv[1], "x86")) + create_fn = translate_sse2_create; + else if (!strcmp(argv[1], "nosse")) + { + util_cpu_caps.has_sse = 0; + util_cpu_caps.has_sse2 = 0; + util_cpu_caps.has_sse3 = 0; + util_cpu_caps.has_sse4_1 = 0; + create_fn = translate_sse2_create; + } + else if (!strcmp(argv[1], "sse")) + { + if(!util_cpu_caps.has_sse || !rtasm_cpu_has_sse()) + { + printf("Error: CPU doesn't support SSE (test with qemu)\n"); + return 2; + } + util_cpu_caps.has_sse2 = 0; + util_cpu_caps.has_sse3 = 0; + util_cpu_caps.has_sse4_1 = 0; + create_fn = translate_sse2_create; + } + else if (!strcmp(argv[1], "sse2")) + { + if(!util_cpu_caps.has_sse2 || !rtasm_cpu_has_sse()) + { + printf("Error: CPU doesn't support SSE2 (test with qemu)\n"); + return 2; + } + util_cpu_caps.has_sse3 = 0; + util_cpu_caps.has_sse4_1 = 0; + create_fn = translate_sse2_create; + } + else if (!strcmp(argv[1], "sse3")) + { + if(!util_cpu_caps.has_sse3 || !rtasm_cpu_has_sse()) + { + printf("Error: CPU doesn't support SSE3 (test with qemu)\n"); + return 2; + } + util_cpu_caps.has_sse4_1 = 0; + create_fn = translate_sse2_create; + } + else if (!strcmp(argv[1], "sse4.1")) + { + if(!util_cpu_caps.has_sse4_1 || !rtasm_cpu_has_sse()) + { + printf("Error: CPU doesn't support SSE4.1 (test with qemu)\n"); + return 2; + } + create_fn = translate_sse2_create; + } + + if (!create_fn) + { + printf("Usage: ./translate_test [generic|x86|nosse|sse|sse2|sse3|sse4.1]\n"); + return 2; + } + + for (i = 1; i < Elements(buffer); ++i) + buffer[i] = align_malloc(buffer_size, 4096); + + byte_buffer = align_malloc(buffer_size, 4096); + float_buffer = align_malloc(buffer_size, 4096); + double_buffer = align_malloc(buffer_size, 4096); + + key.nr_elements = 1; + key.element[0].input_buffer = 0; + key.element[0].input_offset = 0; + key.element[0].output_offset = 0; + key.element[0].type = TRANSLATE_ELEMENT_NORMAL; + key.element[0].instance_divisor = 0; + + srand(4359025); + + /* avoid negative values that work badly when converted to unsigned format*/ + for (i = 0; i < buffer_size; ++i) + byte_buffer[i] = rand() & 0x7f7f7f7f; + + for (i = 0; i < buffer_size / sizeof(float); ++i) + float_buffer[i] = (float)rand_double(); + + for (i = 0; i < buffer_size / sizeof(double); ++i) + double_buffer[i] = rand_double(); + + for (output_format = 1; output_format < PIPE_FORMAT_COUNT; ++output_format) + { + const struct util_format_description* output_format_desc = util_format_description(output_format); + unsigned output_format_size; + unsigned output_normalized = 0; + + if (!output_format_desc + || !output_format_desc->fetch_rgba_float + || !output_format_desc->pack_rgba_float + || output_format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB + || output_format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN + || !translate_is_output_format_supported(output_format)) + continue; + + for(i = 0; i < output_format_desc->nr_channels; ++i) + { + if(output_format_desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT) + output_normalized |= (1 << output_format_desc->channel[i].normalized); + } + + output_format_size = util_format_get_stride(output_format, 1); + + for (input_format = 1; input_format < PIPE_FORMAT_COUNT; ++input_format) + { + const struct util_format_description* input_format_desc = util_format_description(input_format); + unsigned input_format_size; + struct translate* translate[2]; + unsigned fail = 0; + unsigned used_generic = 0; + unsigned input_normalized = 0; + boolean input_is_float = FALSE; + + if (!input_format_desc + || !input_format_desc->fetch_rgba_float + || !input_format_desc->pack_rgba_float + || input_format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB + || input_format_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN + || !translate_is_output_format_supported(input_format)) + continue; + + input_format_size = util_format_get_stride(input_format, 1); + + for(i = 0; i < input_format_desc->nr_channels; ++i) + { + if(input_format_desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) + { + input_is_float = 1; + input_normalized |= 1 << 1; + } + else + input_normalized |= (1 << input_format_desc->channel[i].normalized); + } + + if(((input_normalized | output_normalized) == 3) + || ((input_normalized & 1) && (output_normalized & 1) + && input_format_size * output_format_desc->nr_channels > output_format_size * input_format_desc->nr_channels)) + continue; + + key.element[0].input_format = input_format; + key.element[0].output_format = output_format; + key.output_stride = output_format_size; + translate[0] = create_fn(&key); + if (!translate[0]) + continue; + + key.element[0].input_format = output_format; + key.element[0].output_format = input_format; + key.output_stride = input_format_size; + translate[1] = create_fn(&key); + if(!translate[1]) + { + used_generic = 1; + translate[1] = translate_generic_create(&key); + if(!translate[1]) + continue; + } + + for(i = 1; i < 5; ++i) + memset(buffer[i], 0xcd - (0x22 * i), 4096); + + if(input_is_float && input_format_desc->channel[0].size == 32) + buffer[0] = (unsigned char*)float_buffer; + else if(input_is_float && input_format_desc->channel[0].size == 64) + buffer[0] = (unsigned char*)double_buffer; + else if(input_is_float) + abort(); + else + buffer[0] = byte_buffer; + + translate[0]->set_buffer(translate[0], 0, buffer[0], input_format_size, ~0); + translate[0]->run(translate[0], 0, count, 0, buffer[1]); + translate[1]->set_buffer(translate[1], 0, buffer[1], output_format_size, ~0); + translate[1]->run(translate[1], 0, count, 0, buffer[2]); + translate[0]->set_buffer(translate[0], 0, buffer[2], input_format_size, ~0); + translate[0]->run(translate[0], 0, count, 0, buffer[3]); + translate[1]->set_buffer(translate[1], 0, buffer[3], output_format_size, ~0); + translate[1]->run(translate[1], 0, count, 0, buffer[4]); + + for (i = 0; i < count; ++i) + { + float a[4]; + float b[4]; + input_format_desc->fetch_rgba_float(a, buffer[2] + i * input_format_size, 0, 0); + input_format_desc->fetch_rgba_float(b, buffer[4] + i * input_format_size, 0, 0); + + for (j = 0; j < count; ++j) + { + float d = a[j] - b[j]; + if (d > error || d < -error) + { + fail = 1; + break; + } + } + } + + printf("%s%s: %s -> %s -> %s -> %s -> %s\n", + fail ? "FAIL" : "PASS", + used_generic ? "[GENERIC]" : "", + input_format_desc->name, output_format_desc->name, input_format_desc->name, output_format_desc->name, input_format_desc->name); + + if (1) + { + for (i = 0; i < Elements(buffer); ++i) + { + unsigned format_size = (i & 1) ? output_format_size : input_format_size; + printf("%c ", (i == 2 || i == 4) ? '*' : ' '); + for (j = 0; j < count; ++j) + { + for (k = 0; k < format_size; ++k) + { + printf("%02x", buffer[i][j * format_size + k]); + } + printf(" "); + } + printf("\n"); + } + } + + if (!fail) + ++passed; + ++total; + + if(translate[1]) + translate[1]->release(translate[1]); + translate[0]->release(translate[0]); + } + } + + printf("%u/%u tests passed for translate_%s\n", passed, total, argv[1]); + return passed != total; +} diff --git a/src/gallium/winsys/r600/drm/SConscript b/src/gallium/winsys/r600/drm/SConscript new file mode 100644 index 00000000000..2f20d9f8957 --- /dev/null +++ b/src/gallium/winsys/r600/drm/SConscript @@ -0,0 +1,25 @@ +Import('*') + +env = env.Clone() + +r600_sources = [ + 'bof.c', + 'r600_state.c', + 'radeon_ctx.c', + 'radeon_draw.c', + 'radeon_state.c', + 'radeon_bo.c', + 'radeon_pciid.c', + 'radeon.c', + 'r600_drm.c' +] + +env.ParseConfig('pkg-config --cflags libdrm_radeon') +env.Append(CPPPATH = '#/src/gallium/drivers/r600') + +r600winsys = env.ConvenienceLibrary( + target ='r600winsys', + source = r600_sources, +) + +Export('r600winsys') diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index 3d87a994c15..c76e7f5fa51 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -30,8 +30,7 @@ #include "util/u_debug.h" #include "radeon_priv.h" #include "r600_screen.h" -#include "r600_texture.h" -#include "r600_public.h" +#include "r600_resource.h" #include "r600_drm_public.h" #include "state_tracker/drm_driver.h" @@ -45,7 +44,7 @@ boolean r600_buffer_get_handle(struct radeon *rw, struct winsys_handle *whandle) { struct drm_gem_flink flink; - struct r600_buffer* rbuffer = (struct r600_buffer*)buf; + struct r600_resource* rbuffer = (struct r600_resource*)buf; if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) { if (!rbuffer->flink) { diff --git a/src/gallium/winsys/r600/drm/r600_states.h b/src/gallium/winsys/r600/drm/r600_states.h index 5896df21b21..e40c77d8f6c 100644 --- a/src/gallium/winsys/r600/drm/r600_states.h +++ b/src/gallium/winsys/r600/drm/r600_states.h @@ -372,6 +372,76 @@ static const struct radeon_register R600_CB0_names[] = { {0x00028100, 0, 0, "CB_COLOR0_MASK"}, }; +static const struct radeon_register R600_CB1_names[] = { + {0x00028044, 1, 0, "CB_COLOR1_BASE"}, + {0x000280A4, 0, 0, "CB_COLOR1_INFO"}, + {0x00028064, 0, 0, "CB_COLOR1_SIZE"}, + {0x00028084, 0, 0, "CB_COLOR1_VIEW"}, + {0x000280E4, 1, 1, "CB_COLOR1_FRAG"}, + {0x000280C4, 1, 2, "CB_COLOR1_TILE"}, + {0x00028104, 0, 0, "CB_COLOR1_MASK"}, +}; + +static const struct radeon_register R600_CB2_names[] = { + {0x00028048, 1, 0, "CB_COLOR2_BASE"}, + {0x000280A8, 0, 0, "CB_COLOR2_INFO"}, + {0x00028068, 0, 0, "CB_COLOR2_SIZE"}, + {0x00028088, 0, 0, "CB_COLOR2_VIEW"}, + {0x000280E8, 1, 1, "CB_COLOR2_FRAG"}, + {0x000280C8, 1, 2, "CB_COLOR2_TILE"}, + {0x00028108, 0, 0, "CB_COLOR2_MASK"}, +}; + +static const struct radeon_register R600_CB3_names[] = { + {0x0002804C, 1, 0, "CB_COLOR3_BASE"}, + {0x000280AC, 0, 0, "CB_COLOR3_INFO"}, + {0x0002806C, 0, 0, "CB_COLOR3_SIZE"}, + {0x0002808C, 0, 0, "CB_COLOR3_VIEW"}, + {0x000280EC, 1, 1, "CB_COLOR3_FRAG"}, + {0x000280CC, 1, 2, "CB_COLOR3_TILE"}, + {0x0002810C, 0, 0, "CB_COLOR3_MASK"}, +}; + +static const struct radeon_register R600_CB4_names[] = { + {0x00028050, 1, 0, "CB_COLOR4_BASE"}, + {0x000280B0, 0, 0, "CB_COLOR4_INFO"}, + {0x00028070, 0, 0, "CB_COLOR4_SIZE"}, + {0x00028090, 0, 0, "CB_COLOR4_VIEW"}, + {0x000280F0, 1, 1, "CB_COLOR4_FRAG"}, + {0x000280D0, 1, 2, "CB_COLOR4_TILE"}, + {0x00028110, 0, 0, "CB_COLOR4_MASK"}, +}; + +static const struct radeon_register R600_CB5_names[] = { + {0x00028054, 1, 0, "CB_COLOR5_BASE"}, + {0x000280B4, 0, 0, "CB_COLOR5_INFO"}, + {0x00028074, 0, 0, "CB_COLOR5_SIZE"}, + {0x00028094, 0, 0, "CB_COLOR5_VIEW"}, + {0x000280F4, 1, 1, "CB_COLOR5_FRAG"}, + {0x000280D4, 1, 2, "CB_COLOR5_TILE"}, + {0x00028114, 0, 0, "CB_COLOR5_MASK"}, +}; + +static const struct radeon_register R600_CB6_names[] = { + {0x00028058, 1, 0, "CB_COLOR6_BASE"}, + {0x000280B8, 0, 0, "CB_COLOR6_INFO"}, + {0x00028078, 0, 0, "CB_COLOR6_SIZE"}, + {0x00028098, 0, 0, "CB_COLOR6_VIEW"}, + {0x000280F8, 1, 1, "CB_COLOR6_FRAG"}, + {0x000280D8, 1, 2, "CB_COLOR6_TILE"}, + {0x00028118, 0, 0, "CB_COLOR6_MASK"}, +}; + +static const struct radeon_register R600_CB7_names[] = { + {0x0002805C, 1, 0, "CB_COLOR7_BASE"}, + {0x000280BC, 0, 0, "CB_COLOR7_INFO"}, + {0x0002807C, 0, 0, "CB_COLOR7_SIZE"}, + {0x0002809C, 0, 0, "CB_COLOR7_VIEW"}, + {0x000280FC, 1, 1, "CB_COLOR7_FRAG"}, + {0x000280DC, 1, 2, "CB_COLOR7_TILE"}, + {0x0002811C, 0, 0, "CB_COLOR7_MASK"}, +}; + static const struct radeon_register R600_DB_names[] = { {0x0002800C, 1, 0, "DB_DEPTH_BASE"}, {0x00028000, 0, 0, "DB_DEPTH_SIZE"}, @@ -425,9 +495,16 @@ static struct radeon_type R600_types[] = { { 128, 1233, 0x0000A600, 0x0000A720, 0x0010, 0, "R600_VS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_VS_SAMPLER_BORDER_names}, { 128, 1251, 0x0000A800, 0x0000A920, 0x0010, 0, "R600_GS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_GS_SAMPLER_BORDER_names}, { 128, 1269, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB0", 7, r600_state_pm4_cb0, R600_CB0_names}, - { 128, 1270, 0x00000000, 0x00000000, 0x0000, 0, "R600_DB", 6, r600_state_pm4_db, R600_DB_names}, - { 128, 1271, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names}, - { 128, 1272, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names}, + { 128, 1270, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB1", 7, r600_state_pm4_cb0, R600_CB1_names}, + { 128, 1271, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB2", 7, r600_state_pm4_cb0, R600_CB2_names}, + { 128, 1272, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB3", 7, r600_state_pm4_cb0, R600_CB3_names}, + { 128, 1273, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB4", 7, r600_state_pm4_cb0, R600_CB4_names}, + { 128, 1274, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB5", 7, r600_state_pm4_cb0, R600_CB5_names}, + { 128, 1275, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB6", 7, r600_state_pm4_cb0, R600_CB6_names}, + { 128, 1276, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB7", 7, r600_state_pm4_cb0, R600_CB7_names}, + { 128, 1277, 0x00000000, 0x00000000, 0x0000, 0, "R600_DB", 6, r600_state_pm4_db, R600_DB_names}, + { 128, 1278, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names}, + { 128, 1279, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names}, }; static struct radeon_type R700_types[] = { @@ -453,9 +530,16 @@ static struct radeon_type R700_types[] = { { 128, 1233, 0x0000A600, 0x0000A720, 0x0010, 0, "R600_VS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_VS_SAMPLER_BORDER_names}, { 128, 1251, 0x0000A800, 0x0000A920, 0x0010, 0, "R600_GS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_GS_SAMPLER_BORDER_names}, { 128, 1269, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB0", 7, r700_state_pm4_cb0, R600_CB0_names}, - { 128, 1270, 0x00000000, 0x00000000, 0x0000, 0, "R600_DB", 6, r700_state_pm4_db, R600_DB_names}, - { 128, 1271, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names}, - { 128, 1272, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names}, + { 128, 1270, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB1", 7, r600_state_pm4_cb0, R600_CB1_names}, + { 128, 1271, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB2", 7, r600_state_pm4_cb0, R600_CB2_names}, + { 128, 1272, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB3", 7, r600_state_pm4_cb0, R600_CB3_names}, + { 128, 1273, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB4", 7, r600_state_pm4_cb0, R600_CB4_names}, + { 128, 1274, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB5", 7, r600_state_pm4_cb0, R600_CB5_names}, + { 128, 1275, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB6", 7, r600_state_pm4_cb0, R600_CB6_names}, + { 128, 1276, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB7", 7, r600_state_pm4_cb0, R600_CB7_names}, + { 128, 1277, 0x00000000, 0x00000000, 0x0000, 0, "R600_DB", 6, r700_state_pm4_db, R600_DB_names}, + { 128, 1278, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names}, + { 128, 1279, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names}, }; #endif diff --git a/src/gallium/winsys/r600/drm/radeon.c b/src/gallium/winsys/r600/drm/radeon.c index 7e656698064..80b0a1d3972 100644 --- a/src/gallium/winsys/r600/drm/radeon.c +++ b/src/gallium/winsys/r600/drm/radeon.c @@ -23,7 +23,6 @@ #include "xf86drm.h" #include "radeon_priv.h" #include "radeon_drm.h" -#include "r600d.h" enum radeon_family radeon_get_family(struct radeon *radeon) { diff --git a/src/gallium/winsys/r600/drm/radeon_ctx.c b/src/gallium/winsys/r600/drm/radeon_ctx.c index 6b0eba0b289..45b706bb0f9 100644 --- a/src/gallium/winsys/r600/drm/radeon_ctx.c +++ b/src/gallium/winsys/r600/drm/radeon_ctx.c @@ -112,6 +112,7 @@ struct radeon_ctx *radeon_ctx_decref(struct radeon_ctx *ctx) ctx->bo[i] = radeon_bo_decref(ctx->radeon, ctx->bo[i]); } ctx->radeon = radeon_decref(ctx->radeon); + free(ctx->state); free(ctx->draw); free(ctx->bo); free(ctx->pm4); @@ -151,6 +152,8 @@ int radeon_ctx_submit(struct radeon_ctx *ctx) uint64_t chunk_array[2]; int r = 0; + if (!ctx->cpm4) + return 0; #if 0 for (r = 0; r < ctx->cpm4; r++) { fprintf(stderr, "0x%08X\n", ctx->pm4[r]); diff --git a/src/gallium/winsys/r600/drm/radeon_priv.h b/src/gallium/winsys/r600/drm/radeon_priv.h index b91421f4389..96c0d060f7e 100644 --- a/src/gallium/winsys/r600/drm/radeon_priv.h +++ b/src/gallium/winsys/r600/drm/radeon_priv.h @@ -68,36 +68,6 @@ extern int radeon_is_family_compatible(unsigned family1, unsigned family2); extern int radeon_reg_id(struct radeon *radeon, unsigned offset, unsigned *typeid, unsigned *stateid, unsigned *id); extern unsigned radeon_type_from_id(struct radeon *radeon, unsigned id); -/* - * radeon context functions - */ -#pragma pack(1) -struct radeon_cs_reloc { - uint32_t handle; - uint32_t read_domain; - uint32_t write_domain; - uint32_t flags; -}; -#pragma pack() - -struct radeon_ctx { - int refcount; - struct radeon *radeon; - u32 *pm4; - u32 cpm4; - u32 draw_cpm4; - unsigned id; - unsigned next_id; - unsigned nreloc; - struct radeon_cs_reloc *reloc; - unsigned nbo; - struct radeon_bo **bo; - unsigned ndraw; - struct radeon_draw *cdraw; - struct radeon_draw **draw; - unsigned nstate; - struct radeon_state **state; -}; int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo); struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc); diff --git a/src/gallium/winsys/radeon/drm/radeon_drm.c b/src/gallium/winsys/radeon/drm/radeon_drm.c index e9a276362f3..86d4f949697 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm.c @@ -39,7 +39,6 @@ #include "util/u_memory.h" #include "xf86drm.h" -#include <sys/ioctl.h> static struct radeon_libdrm_winsys * radeon_winsys_create(int fd) @@ -55,6 +54,31 @@ radeon_winsys_create(int fd) return rws; } +/* Enable/disable Hyper-Z access. Return TRUE on success. */ +static boolean radeon_set_hyperz_access(int fd, boolean enable) +{ +#ifndef RADEON_INFO_WANT_HYPERZ +#define RADEON_INFO_WANT_HYPERZ 7 +#endif + + struct drm_radeon_info info = {0}; + unsigned value = enable ? 1 : 0; + + if (!debug_get_bool_option("RADEON_HYPERZ", FALSE)) + return FALSE; + + info.value = (unsigned long)&value; + info.request = RADEON_INFO_WANT_HYPERZ; + + if (drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)) != 0) + return FALSE; + + if (enable && !value) + return FALSE; + + return TRUE; +} + /* Helper function to do the ioctls needed for setup and init. */ static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) { @@ -103,6 +127,10 @@ static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) winsys->drm_2_3_0 = version->version_major > 2 || version->version_minor >= 3; + winsys->drm_2_6_0 = version->version_major > 2 || + (version->version_major == 2 && + version->version_minor >= 6); + info.request = RADEON_INFO_DEVICE_ID; retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); if (retval) { @@ -130,6 +158,8 @@ static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) } winsys->z_pipes = target; + winsys->hyperz = radeon_set_hyperz_access(fd, TRUE); + retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO, &gem_info, sizeof(gem_info)); if (retval) { @@ -142,12 +172,14 @@ static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys) debug_printf("radeon: Successfully grabbed chipset info from kernel!\n" "radeon: DRM version: %d.%d.%d ID: 0x%04x GB: %d Z: %d\n" - "radeon: GART size: %d MB VRAM size: %d MB\n", + "radeon: GART size: %d MB VRAM size: %d MB\n" + "radeon: HyperZ: %s\n", version->version_major, version->version_minor, version->version_patchlevel, winsys->pci_id, winsys->gb_pipes, winsys->z_pipes, winsys->gart_size / 1024 / 1024, - winsys->vram_size / 1024 / 1024); + winsys->vram_size / 1024 / 1024, + winsys->hyperz ? "YES" : "NO"); drmFreeVersion(version); } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c index 5ea5912089e..017eac8464e 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c @@ -189,7 +189,7 @@ struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager pipe_reference_init(&buf->base.base.reference, 1); buf->base.base.alignment = 0; buf->base.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ; - buf->base.base.size = 0; + buf->base.base.size = bo->size; buf->base.vtbl = &radeon_drm_buffer_vtbl; buf->mgr = mgr; diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c index effa27f5c72..58400986421 100644 --- a/src/gallium/winsys/radeon/drm/radeon_r300.c +++ b/src/gallium/winsys/radeon/drm/radeon_r300.c @@ -109,14 +109,19 @@ static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws, static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws, struct winsys_handle *whandle, - unsigned *stride) + unsigned *stride, + unsigned *size) { struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws); struct pb_buffer *_buf; - *stride = whandle->stride; - _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, whandle->handle); + + if (stride) + *stride = whandle->stride; + if (size) + *size = _buf->base.size; + return radeon_libdrm_winsys_buffer(_buf); } @@ -206,6 +211,10 @@ static uint32_t radeon_get_value(struct r300_winsys_screen *rws, return ws->squaretiling; case R300_VID_DRM_2_3_0: return ws->drm_2_3_0; + case R300_VID_DRM_2_6_0: + return ws->drm_2_6_0; + case R300_CAN_HYPERZ: + return ws->hyperz; } return 0; } diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h index 533b7b2e2d2..6f4aa4bce30 100644 --- a/src/gallium/winsys/radeon/drm/radeon_winsys.h +++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h @@ -65,6 +65,15 @@ struct radeon_libdrm_winsys { */ boolean drm_2_3_0; + /* DRM 2.6.0 + * - Hyper-Z + * - GB_Z_PEQ_CONFIG allowed on rv350->r4xx, we should initialize it + */ + boolean drm_2_6_0; + + /* hyperz user */ + boolean hyperz; + /* DRM FD */ int fd; diff --git a/src/gallium/winsys/svga/drm/vmw_screen_dri.c b/src/gallium/winsys/svga/drm/vmw_screen_dri.c index 1b0d10f60d6..7bd4407e9f1 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen_dri.c +++ b/src/gallium/winsys/svga/drm/vmw_screen_dri.c @@ -32,8 +32,6 @@ #include "vmw_screen.h" #include "vmw_surface.h" -#include "vmw_fence.h" -#include "vmw_context.h" #include "svga_drm_public.h" #include "state_tracker/drm_driver.h" diff --git a/src/glsl/apps/compile.c b/src/glsl/apps/compile.c index 3aa4fd4d53e..5114fc9d0be 100644 --- a/src/glsl/apps/compile.c +++ b/src/glsl/apps/compile.c @@ -30,6 +30,7 @@ #include <string.h> #include <assert.h> #include "../pp/sl_pp_public.h" +#include "../pp/sl_pp_purify.h" #include "../cl/sl_cl_parse.h" diff --git a/src/glsl/apps/process.c b/src/glsl/apps/process.c index caf72a71cf1..6d5ce6eea3f 100644 --- a/src/glsl/apps/process.c +++ b/src/glsl/apps/process.c @@ -30,6 +30,8 @@ #include <string.h> #include <assert.h> #include "../pp/sl_pp_public.h" +#include "../pp/sl_pp_purify.h" +#include "../pp/sl_pp_token.h" int diff --git a/src/glsl/apps/purify.c b/src/glsl/apps/purify.c index 0f09b157efd..e3fca59ab45 100644 --- a/src/glsl/apps/purify.c +++ b/src/glsl/apps/purify.c @@ -30,6 +30,7 @@ #include <stdlib.h> #include <string.h> #include "../pp/sl_pp_public.h" +#include "../pp/sl_pp_purify.h" int diff --git a/src/glsl/apps/tokenise.c b/src/glsl/apps/tokenise.c index f89f47d0611..3d68334bed3 100644 --- a/src/glsl/apps/tokenise.c +++ b/src/glsl/apps/tokenise.c @@ -30,6 +30,8 @@ #include <string.h> #include <assert.h> #include "../pp/sl_pp_public.h" +#include "../pp/sl_pp_purify.h" +#include "../pp/sl_pp_token.h" int diff --git a/src/glsl/apps/version.c b/src/glsl/apps/version.c index fa5c226da83..8506f35ba11 100644 --- a/src/glsl/apps/version.c +++ b/src/glsl/apps/version.c @@ -30,6 +30,7 @@ #include <string.h> #include <assert.h> #include "../pp/sl_pp_public.h" +#include "../pp/sl_pp_purify.h" int diff --git a/src/glsl/cl/sl_cl_parse.c b/src/glsl/cl/sl_cl_parse.c index 09456f5219a..c1bc6031ce6 100644 --- a/src/glsl/cl/sl_cl_parse.c +++ b/src/glsl/cl/sl_cl_parse.c @@ -29,6 +29,7 @@ #include <stdlib.h> #include <string.h> #include "../pp/sl_pp_public.h" +#include "../pp/sl_pp_token.h" #include "sl_cl_parse.h" diff --git a/src/glsl/cl/sl_cl_parse.h b/src/glsl/cl/sl_cl_parse.h index dd5791d5901..a954d439276 100644 --- a/src/glsl/cl/sl_cl_parse.h +++ b/src/glsl/cl/sl_cl_parse.h @@ -28,6 +28,8 @@ #ifndef SL_CL_PARSE_H #define SL_CL_PARSE_H +struct sl_pp_context; + int sl_cl_compile(struct sl_pp_context *context, unsigned int shader_type, diff --git a/src/glsl/pp/sl_pp_context.c b/src/glsl/pp/sl_pp_context.c index 74a9bdddfdc..b8e1e99fc86 100644 --- a/src/glsl/pp/sl_pp_context.c +++ b/src/glsl/pp/sl_pp_context.c @@ -27,6 +27,7 @@ #include <stdlib.h> #include <string.h> +#include "sl_pp_macro.h" #include "sl_pp_public.h" #include "sl_pp_context.h" diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 8abb9708b85..e6244f62575 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -29,7 +29,6 @@ #define SL_PP_CONTEXT_H #include "sl_pp_dict.h" -#include "sl_pp_macro.h" #include "sl_pp_process.h" #include "sl_pp_purify.h" #include "sl_pp_token_util.h" diff --git a/src/glsl/pp/sl_pp_define.c b/src/glsl/pp/sl_pp_define.c index 808a6a0d4f1..370e6aa6606 100644 --- a/src/glsl/pp/sl_pp_define.c +++ b/src/glsl/pp/sl_pp_define.c @@ -28,8 +28,10 @@ #include <stdlib.h> #include <string.h> #include "sl_pp_context.h" +#include "sl_pp_macro.h" #include "sl_pp_process.h" #include "sl_pp_public.h" +#include "sl_pp_token.h" static void diff --git a/src/glsl/pp/sl_pp_error.c b/src/glsl/pp/sl_pp_error.c index b628e37ce83..482b67fcafb 100644 --- a/src/glsl/pp/sl_pp_error.c +++ b/src/glsl/pp/sl_pp_error.c @@ -30,6 +30,7 @@ #include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" +#include "sl_pp_token.h" void diff --git a/src/glsl/pp/sl_pp_expression.c b/src/glsl/pp/sl_pp_expression.c index ec904787dd7..c3f48356b09 100644 --- a/src/glsl/pp/sl_pp_expression.c +++ b/src/glsl/pp/sl_pp_expression.c @@ -27,8 +27,10 @@ #include <stdlib.h> #include <string.h> +#include "sl_pp_context.h" #include "sl_pp_expression.h" #include "sl_pp_public.h" +#include "sl_pp_token.h" struct parse_context { diff --git a/src/glsl/pp/sl_pp_expression.h b/src/glsl/pp/sl_pp_expression.h index 377d5b4cbd9..522263bb259 100644 --- a/src/glsl/pp/sl_pp_expression.h +++ b/src/glsl/pp/sl_pp_expression.h @@ -28,8 +28,8 @@ #ifndef SL_PP_EXPRESSION_H #define SL_PP_EXPRESSION_H -#include "sl_pp_context.h" -#include "sl_pp_token.h" +struct sl_pp_context; +struct sl_pp_token_info; int diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c index d119677c268..00dbdcf22bc 100644 --- a/src/glsl/pp/sl_pp_extension.c +++ b/src/glsl/pp/sl_pp_extension.c @@ -25,11 +25,13 @@ * **************************************************************************/ +#include <assert.h> #include <stdlib.h> #include <string.h> #include "sl_pp_context.h" #include "sl_pp_process.h" #include "sl_pp_public.h" +#include "sl_pp_token.h" /** diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index 25cb7a3ca11..6b7a1590b42 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -27,8 +27,11 @@ #include <stdlib.h> #include <string.h> +#include "sl_pp_context.h" #include "sl_pp_expression.h" +#include "sl_pp_macro.h" #include "sl_pp_process.h" +#include "sl_pp_token.h" static int diff --git a/src/glsl/pp/sl_pp_line.c b/src/glsl/pp/sl_pp_line.c index 6f7e9eb562c..51581c7bb59 100644 --- a/src/glsl/pp/sl_pp_line.c +++ b/src/glsl/pp/sl_pp_line.c @@ -28,8 +28,10 @@ #include <stdlib.h> #include <string.h> #include "sl_pp_context.h" +#include "sl_pp_macro.h" #include "sl_pp_public.h" #include "sl_pp_process.h" +#include "sl_pp_token.h" int diff --git a/src/glsl/pp/sl_pp_macro.c b/src/glsl/pp/sl_pp_macro.c index 9f520b8fc53..2cf9ea342b2 100644 --- a/src/glsl/pp/sl_pp_macro.c +++ b/src/glsl/pp/sl_pp_macro.c @@ -32,6 +32,7 @@ #include "sl_pp_public.h" #include "sl_pp_macro.h" #include "sl_pp_process.h" +#include "sl_pp_token.h" static void diff --git a/src/glsl/pp/sl_pp_macro.h b/src/glsl/pp/sl_pp_macro.h index 1d210681091..6e65a0a588d 100644 --- a/src/glsl/pp/sl_pp_macro.h +++ b/src/glsl/pp/sl_pp_macro.h @@ -28,9 +28,6 @@ #ifndef SL_PP_MACRO_H #define SL_PP_MACRO_H -#include "sl_pp_token.h" - - struct sl_pp_context; struct sl_pp_process_state; struct sl_pp_token_buffer; diff --git a/src/glsl/pp/sl_pp_pragma.c b/src/glsl/pp/sl_pp_pragma.c index caf4c63f657..6789704db0c 100644 --- a/src/glsl/pp/sl_pp_pragma.c +++ b/src/glsl/pp/sl_pp_pragma.c @@ -29,6 +29,7 @@ #include <string.h> #include "sl_pp_context.h" #include "sl_pp_process.h" +#include "sl_pp_token.h" int diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index 315ad9bf1cd..2f12393237c 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -25,11 +25,14 @@ * **************************************************************************/ +#include <assert.h> #include <stdlib.h> #include <string.h> #include "sl_pp_context.h" +#include "sl_pp_macro.h" #include "sl_pp_process.h" #include "sl_pp_public.h" +#include "sl_pp_token.h" int diff --git a/src/glsl/pp/sl_pp_process.h b/src/glsl/pp/sl_pp_process.h index fe6ff0d4648..04e9be43989 100644 --- a/src/glsl/pp/sl_pp_process.h +++ b/src/glsl/pp/sl_pp_process.h @@ -28,11 +28,8 @@ #ifndef SL_PP_PROCESS_H #define SL_PP_PROCESS_H -#include "sl_pp_macro.h" -#include "sl_pp_token.h" - - struct sl_pp_context; +struct sl_pp_token_buffer; struct sl_pp_process_state { struct sl_pp_token_info *out; diff --git a/src/glsl/pp/sl_pp_public.h b/src/glsl/pp/sl_pp_public.h index ca6f722543d..66ced6cf589 100644 --- a/src/glsl/pp/sl_pp_public.h +++ b/src/glsl/pp/sl_pp_public.h @@ -28,13 +28,9 @@ #ifndef SL_PP_PUBLIC_H #define SL_PP_PUBLIC_H - struct sl_pp_context; - - -#include "sl_pp_purify.h" -#include "sl_pp_token.h" - +struct sl_pp_purify_options; +struct sl_pp_token_info; struct sl_pp_context * sl_pp_context_create(const char *input, diff --git a/src/glsl/pp/sl_pp_token_util.c b/src/glsl/pp/sl_pp_token_util.c index c85263d9a11..43be49670b0 100644 --- a/src/glsl/pp/sl_pp_token_util.c +++ b/src/glsl/pp/sl_pp_token_util.c @@ -28,6 +28,7 @@ #include <assert.h> #include <stdlib.h> #include "sl_pp_token_util.h" +#include "sl_pp_token.h" int diff --git a/src/glsl/pp/sl_pp_token_util.h b/src/glsl/pp/sl_pp_token_util.h index 2a668ad0a84..35d72101ca5 100644 --- a/src/glsl/pp/sl_pp_token_util.h +++ b/src/glsl/pp/sl_pp_token_util.h @@ -28,11 +28,6 @@ #ifndef SL_PP_TOKEN_UTIL_H #define SL_PP_TOKEN_UTIL_H -#include <assert.h> -#include <stdlib.h> -#include "sl_pp_token.h" - - struct sl_pp_context; /* diff --git a/src/glsl/pp/sl_pp_version.c b/src/glsl/pp/sl_pp_version.c index 3c995b77501..6735c05e8ae 100644 --- a/src/glsl/pp/sl_pp_version.c +++ b/src/glsl/pp/sl_pp_version.c @@ -29,6 +29,7 @@ #include <string.h> #include "sl_pp_public.h" #include "sl_pp_context.h" +#include "sl_pp_token.h" int diff --git a/src/glut/glx/glut_dstr.c b/src/glut/glx/glut_dstr.c index 2513af45394..319930c4b11 100644 --- a/src/glut/glx/glut_dstr.c +++ b/src/glut/glx/glut_dstr.c @@ -232,7 +232,7 @@ loadVisuals(int *nitems_return) XVisualInfo *vinfo, **vlist, template; FrameBufferMode *fbmodes, *mode; int n, i, j, rc, glcapable; -#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) +#if defined(GLX_VERSION_1_1) && (defined(GLX_SGIS_multisample) || defined(GLX_ARB_multisample)) int multisample; #endif #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) @@ -275,8 +275,9 @@ loadVisuals(int *nitems_return) } } -#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) - multisample = __glutIsSupportedByGLX("GLX_SGIS_multisample"); +#if defined(GLX_VERSION_1_1) && (defined(GLX_SGIS_multisample) || defined(GLX_ARB_multisample)) + multisample = __glutIsSupportedByGLX("GLX_SGIS_multisample") || + __glutIsSupportedByGLX("GLX_ARB_multisample"); #endif #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) visual_info = __glutIsSupportedByGLX("GLX_EXT_visual_info"); @@ -572,7 +573,7 @@ loadVisuals(int *nitems_return) #else mode->cap[TRANSPARENT] = 0; #endif -#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) +#if defined(GLX_VERSION_1_1) && (defined(GLX_SGIS_multisample) || defined(GLX_ARB_multisample)) if (multisample) { rc = __glut_glXGetFBConfigAttribSGIX(__glutDisplay, fbc, GLX_SAMPLES_SGIS, &mode->cap[SAMPLES]); @@ -1250,8 +1251,9 @@ parseModeString(char *mode, int *ncriteria, Bool * allowDoubleAsSingle, word = strtok(NULL, " \t"); } -#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) - if (__glutIsSupportedByGLX("GLX_SGIS_multisample")) { +#if defined(GLX_VERSION_1_1) && (defined(GLX_SGIS_multisample) || defined(GLX_ARB_multisample)) + if (__glutIsSupportedByGLX("GLX_SGIS_multisample") || + __glutIsSupportedByGLX("GLX_ARB_multisample")) { if (!(mask & (1 << SAMPLES))) { criteria[n].capability = SAMPLES; criteria[n].comparison = EQ; diff --git a/src/glut/glx/glut_overlay.c b/src/glut/glx/glut_overlay.c index 32434650ebe..ce8e68d164a 100644 --- a/src/glut/glx/glut_overlay.c +++ b/src/glut/glx/glut_overlay.c @@ -81,10 +81,11 @@ checkOverlayAcceptability(XVisualInfo * vi, unsigned int mode) if (GLUT_WIND_HAS_STENCIL(mode) && (value <= 0)) return 1; -#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) +#if defined(GLX_VERSION_1_1) && (defined(GLX_SGIS_multisample) || defined(GLX_ARB_multisample)) /* XXX Multisampled overlay color index?? Pretty unlikely. */ /* Look for multisampling if requested. */ - if (__glutIsSupportedByGLX("GLX_SGIS_multisample")) + if (__glutIsSupportedByGLX("GLX_SGIS_multisample") || + __glutIsSupportedByGLX("GLX_ARB_multisample")) glXGetConfig(__glutDisplay, vi, GLX_SAMPLES_SGIS, &value); else value = 0; diff --git a/src/glx/Makefile b/src/glx/Makefile index 48d901fb894..9a22d0c547a 100644 --- a/src/glx/Makefile +++ b/src/glx/Makefile @@ -5,14 +5,15 @@ EXTRA_DEFINES = -DXF86VIDMODE -D_REENTRANT \ -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" SOURCES = \ - glcontextmodes.c \ clientattrib.c \ compsize.c \ eval.c \ + glxconfig.c \ glxcmds.c \ glxcurrent.c \ glxext.c \ glxextensions.c \ + indirect_glx.c \ indirect.c \ indirect_init.c \ indirect_size.c \ @@ -37,7 +38,9 @@ SOURCES = \ XF86dri.c \ glxhash.c \ dri2_glx.c \ - dri2.c + dri2.c \ + applegl_glx.c + GLAPI_LIB = $(TOP)/src/mapi/glapi/libglapi.a diff --git a/src/glx/XF86dri.c b/src/glx/XF86dri.c index 36b43f0f84a..5c181d6db9e 100644 --- a/src/glx/XF86dri.c +++ b/src/glx/XF86dri.c @@ -39,21 +39,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) #include <X11/Xlibint.h> +#include <X11/Xfuncproto.h> #include <X11/extensions/Xext.h> #include <X11/extensions/extutil.h> #include "xf86dristr.h" - -#if defined(__GNUC__) -# define PUBLIC __attribute__((visibility("default"))) -# define USED __attribute__((used)) -#else -# define PUBLIC -# define USED -#endif - - - static XExtensionInfo _xf86dri_info_data; static XExtensionInfo *xf86dri_info = &_xf86dri_info_data; static char xf86dri_extension_name[] = XF86DRINAME; diff --git a/src/glx/apple/apple_glx_drawable.h b/src/glx/apple/apple_glx_drawable.h index e49eae355e9..af79e0590e1 100644 --- a/src/glx/apple/apple_glx_drawable.h +++ b/src/glx/apple/apple_glx_drawable.h @@ -211,7 +211,7 @@ bool apple_glx_pbuffer_get_event_mask(GLXDrawable d, unsigned long *mask); /* Pixmaps */ -/* mode is a __GLcontextModes * */ +/* mode is a struct glx_config * */ /* Returns true if an error occurred. */ bool apple_glx_pixmap_create(Display * dpy, int screen, Pixmap pixmap, const void *mode); diff --git a/src/glx/apple/apple_glx_pbuffer.c b/src/glx/apple/apple_glx_pbuffer.c index 1466fea4874..a5ef59ccf82 100644 --- a/src/glx/apple/apple_glx_pbuffer.c +++ b/src/glx/apple/apple_glx_pbuffer.c @@ -128,7 +128,7 @@ apple_glx_pbuffer_create(Display * dpy, GLXFBConfig config, Window root; int screen; Pixmap xid; - __GLcontextModes *modes = (__GLcontextModes *) config; + struct glx_config *modes = (__GLcontextModes *) config; root = DefaultRootWindow(dpy); screen = DefaultScreen(dpy); diff --git a/src/glx/apple/apple_glx_pixmap.c b/src/glx/apple/apple_glx_pixmap.c index af1791afb70..fec05e02de6 100644 --- a/src/glx/apple/apple_glx_pixmap.c +++ b/src/glx/apple/apple_glx_pixmap.c @@ -125,7 +125,7 @@ apple_glx_pixmap_create(Display * dpy, int screen, Pixmap pixmap, bool double_buffered; bool uses_stereo; CGLError error; - const __GLcontextModes *cmodes = mode; + const struct glx_config *cmodes = mode; if (apple_glx_drawable_create(dpy, screen, pixmap, &d, &callbacks)) return true; diff --git a/src/glx/apple/apple_visual.c b/src/glx/apple/apple_visual.c index da5aa05fd50..7a9525e8170 100644 --- a/src/glx/apple/apple_visual.c +++ b/src/glx/apple/apple_visual.c @@ -61,7 +61,7 @@ apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const void *mode, bool offscreen) { CGLPixelFormatAttribute attr[MAX_ATTR]; - const __GLcontextModes *c = mode; + const struct glx_config *c = mode; int numattr = 0; GLint vsref = 0; CGLError error = 0; diff --git a/src/glx/apple/apple_visual.h b/src/glx/apple/apple_visual.h index ebfafa340bf..2cf9a9e2513 100644 --- a/src/glx/apple/apple_visual.h +++ b/src/glx/apple/apple_visual.h @@ -33,7 +33,7 @@ #include <stdbool.h> #include <OpenGL/CGLTypes.h> -/* mode is expected to be of type __GLcontextModes. */ +/* mode is expected to be of type struct glx_config. */ void apple_visual_create_pfobj(CGLPixelFormatObj * pfobj, const void *mode, bool * double_buffered, bool * uses_stereo, bool offscreen); diff --git a/src/glx/apple/glx_empty.c b/src/glx/apple/glx_empty.c index 1569679c713..5967ecabc1a 100644 --- a/src/glx/apple/glx_empty.c +++ b/src/glx/apple/glx_empty.c @@ -152,7 +152,7 @@ glXReleaseBuffersMESA(Display * dpy, GLXDrawable d) } -PUBLIC GLXPixmap +_X_EXPORT GLXPixmap glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual, Pixmap pixmap, Colormap cmap) { @@ -180,7 +180,7 @@ glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable, } -PUBLIC int +_X_EXPORT int glXQueryGLXPbufferSGIX(Display * dpy, GLXDrawable drawable, int attribute, unsigned int *value) { @@ -191,7 +191,7 @@ glXQueryGLXPbufferSGIX(Display * dpy, GLXDrawable drawable, return 0; } -PUBLIC GLXDrawable +_X_EXPORT GLXDrawable glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfig config, unsigned int width, unsigned int height, int *attrib_list) @@ -206,7 +206,7 @@ glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfig config, #if 0 /* GLX_SGIX_fbconfig */ -PUBLIC int +_X_EXPORT int glXGetFBConfigAttribSGIX(Display * dpy, void *config, int a, int *b) { (void) dpy; @@ -216,7 +216,7 @@ glXGetFBConfigAttribSGIX(Display * dpy, void *config, int a, int *b) return 0; } -PUBLIC void * +_X_EXPORT void * glXChooseFBConfigSGIX(Display * dpy, int a, int *b, int *c) { (void) dpy; @@ -226,7 +226,7 @@ glXChooseFBConfigSGIX(Display * dpy, int a, int *b, int *c) return NULL; } -PUBLIC GLXPixmap +_X_EXPORT GLXPixmap glXCreateGLXPixmapWithConfigSGIX(Display * dpy, void *config, Pixmap p) { (void) dpy; @@ -235,7 +235,7 @@ glXCreateGLXPixmapWithConfigSGIX(Display * dpy, void *config, Pixmap p) return None; } -PUBLIC GLXContext +_X_EXPORT GLXContext glXCreateContextWithConfigSGIX(Display * dpy, void *config, int a, GLXContext b, Bool c) { @@ -247,7 +247,7 @@ glXCreateContextWithConfigSGIX(Display * dpy, void *config, int a, return NULL; } -PUBLIC XVisualInfo * +_X_EXPORT XVisualInfo * glXGetVisualFromFBConfigSGIX(Display * dpy, void *config) { (void) dpy; @@ -255,7 +255,7 @@ glXGetVisualFromFBConfigSGIX(Display * dpy, void *config) return NULL; } -PUBLIC void * +_X_EXPORT void * glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * visinfo) { (void) dpy; @@ -265,17 +265,17 @@ glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * visinfo) #endif -PUBLIC +_X_EXPORT GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX, (Display * dpy, GLXDrawable pbuf), (dpy, pbuf), glXDestroyPbuffer) - PUBLIC GLX_ALIAS_VOID(glXSelectEventSGIX, + _X_EXPORT GLX_ALIAS_VOID(glXSelectEventSGIX, (Display * dpy, GLXDrawable drawable, unsigned long mask), (dpy, drawable, mask), glXSelectEvent) - PUBLIC GLX_ALIAS_VOID(glXGetSelectedEventSGIX, + _X_EXPORT GLX_ALIAS_VOID(glXGetSelectedEventSGIX, (Display * dpy, GLXDrawable drawable, unsigned long *mask), (dpy, drawable, mask), glXGetSelectedEvent) diff --git a/src/glx/apple/glxreply.c b/src/glx/apple/glxreply.c index 7280bc9715a..f17ebe6b406 100644 --- a/src/glx/apple/glxreply.c +++ b/src/glx/apple/glxreply.c @@ -55,7 +55,7 @@ __glXReadReply(Display * dpy, size_t size, void *dest, } void -__glXReadPixelReply(Display * dpy, __GLXcontext * gc, unsigned max_dim, +__glXReadPixelReply(Display * dpy, struct glx_context * gc, unsigned max_dim, GLint width, GLint height, GLint depth, GLenum format, GLenum type, void *dest, GLboolean dimensions_in_reply) { @@ -101,7 +101,7 @@ __glXReadPixelReply(Display * dpy, __GLXcontext * gc, unsigned max_dim, #if 0 GLubyte * -__glXSetupSingleRequest(__GLXcontext * gc, GLint sop, GLint cmdlen) +__glXSetupSingleRequest(struct glx_context * gc, GLint sop, GLint cmdlen) { xGLXSingleReq *req; Display *const dpy = gc->currentDpy; @@ -117,7 +117,7 @@ __glXSetupSingleRequest(__GLXcontext * gc, GLint sop, GLint cmdlen) #endif GLubyte * -__glXSetupVendorRequest(__GLXcontext * gc, GLint code, GLint vop, +__glXSetupVendorRequest(struct glx_context * gc, GLint code, GLint vop, GLint cmdlen) { xGLXVendorPrivateReq *req; diff --git a/src/glx/applegl_glx.c b/src/glx/applegl_glx.c new file mode 100644 index 00000000000..3da1f19323f --- /dev/null +++ b/src/glx/applegl_glx.c @@ -0,0 +1,155 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg ([email protected]) + */ + +#if defined(GLX_USE_APPLEGL) + +static void +applegl_destroy_context(struct glx_context *gc) +{ + apple_glx_destroy_context(&gc->driContext, gc->currentDpy); +} + +static int +applegl_bind_context(struct glx_context *gc, struct glx_context *old, + GLXDrawable draw, GLXDrawable read) +{ + bool error = apple_glx_make_current_context(dpy, + (oldGC && oldGC != &dummyContext) ? oldGC->driContext : NUL~ + gc ? gc->driContext : NULL, draw); + + apple_glx_diagnostic("%s: error %s\n", __func__, error ? "YES" : "NO"); + if (error) + return GLXBadContext; + + return Success; +} + +static void +applegl_unbind_context(struct glx_context *gc, struct glx_context *new) +{ +} + +static void +applegl_wait_gl(struct glx_context *gc) +{ + glFinish(); +} + +static void +applegl_wait_x(struct glx_context *gc) +{ + apple_glx_waitx(gc->dpy, gc->driContext); +} + +static const struct glx_context_vtable applegl_context_vtable = { + applegl_destroy_context, + applegl_bind_context, + applegl_unbind_context, + applegl_wait_gl, + applegl_wait_x, + DRI_glXUseXFont, + NULL, /* bind_tex_image, */ + NULL, /* release_tex_image, */ +}; + +static struct glx_context * +applegl_create_context(struct glx_screen *psc, + struct glx_config *mode, + struct glx_context *shareList, int renderType) +{ + struct glx_context *gc; + int errorcode; + bool x11error; + + /* TODO: Integrate this with apple_glx_create_context and make + * struct apple_glx_context inherit from struct glx_context. */ + + gc = Xmalloc(sizeof *gc); + if (pcp == NULL) + return NULL; + + memset(gc, 0, sizeof *gc); + if (!glx_context_init(&gc->base, &psc->base, mode)) { + Xfree(gc); + return NULL; + } + + gc->vtable = &applegl_context_vtable; + gc->driContext = NULL; + gc->do_destroy = False; + + /* TODO: darwin: Integrate with above to do indirect */ + if(apple_glx_create_context(&gc->driContext, dpy, screen, fbconfig, + shareList ? shareList->driContext : NULL, + &errorcode, &x11error)) { + __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error); + gc->vtable->destroy(gc); + return NULL; + } + + gc->currentContextTag = -1; + gc->mode = fbconfig; + gc->isDirect = allowDirect; + gc->xid = 1; /* Just something not None, so we know when to destroy + * it in MakeContextCurrent. */ + + return gc; +} + +struct glx_screen_vtable appegl_screen_vtable = { + applegl_create_context +}; + +_X_HIDDEN struct glx_screen * +applegl_create_screen(int screen, struct glx_display * priv) +{ + struct glx_screen *psc; + + psc = Xmalloc(sizeof *psc); + if (psc == NULL) + return NULL; + + memset(psc, 0, sizeof *psc); + glx_screen_init(psc, screen, priv); + psc->vtable = &applegl_screen_vtable; + + return psc; +} + +_X_HIDDEN int +applegl_create_display(struct glx_display *display) +{ + /* create applegl display and stuff in display->appleglDisplay */ + apple_init_glx(display); +} + +#endif diff --git a/src/glx/clientattrib.c b/src/glx/clientattrib.c index b26c17938db..7792fa31f9d 100644 --- a/src/glx/clientattrib.c +++ b/src/glx/clientattrib.c @@ -39,7 +39,7 @@ static void do_enable_disable(GLenum array, GLboolean val) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); unsigned index = 0; @@ -69,7 +69,7 @@ __indirect_glDisableClientState(GLenum array) void __indirect_glPushClientAttrib(GLuint mask) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); __GLXattribute **spp = gc->attributes.stackPointer, *sp; @@ -97,7 +97,7 @@ __indirect_glPushClientAttrib(GLuint mask) void __indirect_glPopClientAttrib(void) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); __GLXattribute **spp = gc->attributes.stackPointer, *sp; GLuint mask; @@ -127,7 +127,7 @@ __indirect_glPopClientAttrib(void) #endif void -__glFreeAttributeState(__GLXcontext * gc) +__glFreeAttributeState(struct glx_context * gc) { __GLXattribute *sp, **spp; diff --git a/src/glx/dri2.c b/src/glx/dri2.c index d53431c19a6..d70ec5a3ecf 100644 --- a/src/glx/dri2.c +++ b/src/glx/dri2.c @@ -88,7 +88,6 @@ static Bool DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); - __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy); XextCheckExtension(dpy, info, dri2ExtensionName, False); @@ -100,6 +99,7 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire; __GLXDRIdrawable *pdraw; + struct glx_display *glx_dpy = __glXInitialize(dpy); /* Ignore swap events if we're not looking for them */ pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable); diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index 2f12387860e..ff48c79c272 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -76,7 +76,7 @@ struct dri2_display }; struct dri2_screen { - __GLXscreenConfigs base; + struct glx_screen base; __DRIscreen *driScreen; __GLXDRIscreen vtable; @@ -94,8 +94,7 @@ struct dri2_screen { struct dri2_context { - __GLXcontext base; - __GLXDRIcontext dri_vtable; + struct glx_context base; __DRIcontext *driContext; }; @@ -114,31 +113,47 @@ struct dri2_drawable static const struct glx_context_vtable dri2_context_vtable; static void -dri2DestroyContext(__GLXcontext *context) +dri2_destroy_context(struct glx_context *context) { struct dri2_context *pcp = (struct dri2_context *) context; struct dri2_screen *psc = (struct dri2_screen *) context->psc; + if (context->xid) + glx_send_destroy_context(psc->base.dpy, context->xid); + + if (context->extensions) + XFree((char *) context->extensions); + + GarbageCollectDRIDrawables(context->psc); + (*psc->core->destroyContext) (pcp->driContext); Xfree(pcp); } static Bool -dri2BindContext(__GLXcontext *context, - __GLXDRIdrawable *draw, __GLXDRIdrawable *read) +dri2_bind_context(struct glx_context *context, struct glx_context *old, + GLXDrawable draw, GLXDrawable read) { struct dri2_context *pcp = (struct dri2_context *) context; struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc; - struct dri2_drawable *pdr = (struct dri2_drawable *) draw; - struct dri2_drawable *prd = (struct dri2_drawable *) read; + struct dri2_drawable *pdraw, *pread; + + pdraw = (struct dri2_drawable *) driFetchDrawable(context, draw); + pread = (struct dri2_drawable *) driFetchDrawable(context, read); + + if (pdraw == NULL || pread == NULL) + return GLXBadDrawable; - return (*psc->core->bindContext) (pcp->driContext, - pdr->driDrawable, prd->driDrawable); + if ((*psc->core->bindContext) (pcp->driContext, + pdraw->driDrawable, pread->driDrawable)) + return Success; + + return GLXBadContext; } static void -dri2UnbindContext(__GLXcontext *context) +dri2_unbind_context(struct glx_context *context, struct glx_context *new) { struct dri2_context *pcp = (struct dri2_context *) context; struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc; @@ -146,18 +161,18 @@ dri2UnbindContext(__GLXcontext *context) (*psc->core->unbindContext) (pcp->driContext); } -static __GLXcontext * -dri2CreateContext(__GLXscreenConfigs *base, - const __GLcontextModes * mode, - GLXContext shareList, int renderType) +static struct glx_context * +dri2_create_context(struct glx_screen *base, + struct glx_config *config_base, + struct glx_context *shareList, int renderType) { struct dri2_context *pcp, *pcp_shared; struct dri2_screen *psc = (struct dri2_screen *) base; - __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; __DRIcontext *shared = NULL; if (shareList) { - pcp_shared = (struct dri2_context *) shareList->driContext; + pcp_shared = (struct dri2_context *) shareList; shared = pcp_shared->driContext; } @@ -166,7 +181,7 @@ dri2CreateContext(__GLXscreenConfigs *base, return NULL; memset(pcp, 0, sizeof *pcp); - if (!glx_context_init(&pcp->base, &psc->base, mode)) { + if (!glx_context_init(&pcp->base, &psc->base, &config->base)) { Xfree(pcp); return NULL; } @@ -181,10 +196,6 @@ dri2CreateContext(__GLXscreenConfigs *base, } pcp->base.vtable = &dri2_context_vtable; - pcp->base.driContext = &pcp->dri_vtable; - pcp->dri_vtable.destroyContext = dri2DestroyContext; - pcp->dri_vtable.bindContext = dri2BindContext; - pcp->dri_vtable.unbindContext = dri2UnbindContext; return &pcp->base; } @@ -194,7 +205,7 @@ dri2DestroyDrawable(__GLXDRIdrawable *base) { struct dri2_screen *psc = (struct dri2_screen *) base->psc; struct dri2_drawable *pdraw = (struct dri2_drawable *) base; - __GLXdisplayPrivate *dpyPriv = psc->base.display; + struct glx_display *dpyPriv = psc->base.display; struct dri2_display *pdp = (struct dri2_display *)dpyPriv->dri2Display; __glxHashDelete(pdp->dri2Hash, pdraw->base.xDrawable); @@ -204,13 +215,13 @@ dri2DestroyDrawable(__GLXDRIdrawable *base) } static __GLXDRIdrawable * -dri2CreateDrawable(__GLXscreenConfigs *base, XID xDrawable, - GLXDrawable drawable, const __GLcontextModes * modes) +dri2CreateDrawable(struct glx_screen *base, XID xDrawable, + GLXDrawable drawable, struct glx_config *config_base) { struct dri2_drawable *pdraw; struct dri2_screen *psc = (struct dri2_screen *) base; - __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; - __GLXdisplayPrivate *dpyPriv; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; + struct glx_display *dpyPriv; struct dri2_display *pdp; GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1; @@ -218,6 +229,7 @@ dri2CreateDrawable(__GLXscreenConfigs *base, XID xDrawable, if (!pdraw) return NULL; + memset(pdraw, 0, sizeof *pdraw); pdraw->base.destroyDrawable = dri2DestroyDrawable; pdraw->base.xDrawable = xDrawable; pdraw->base.drawable = drawable; @@ -280,7 +292,7 @@ dri2CreateDrawable(__GLXscreenConfigs *base, XID xDrawable, #ifdef X_DRI2GetMSC static int -dri2DrawableGetMSC(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw, +dri2DrawableGetMSC(struct glx_screen *psc, __GLXDRIdrawable *pdraw, int64_t *ust, int64_t *msc, int64_t *sbc) { CARD64 dri2_ust, dri2_msc, dri2_sbc; @@ -394,7 +406,7 @@ dri2_copy_drawable(struct dri2_drawable *priv, int dest, int src) } static void -dri2_wait_x(__GLXcontext *gc) +dri2_wait_x(struct glx_context *gc) { struct dri2_drawable *priv = (struct dri2_drawable *) GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); @@ -406,7 +418,7 @@ dri2_wait_x(__GLXcontext *gc) } static void -dri2_wait_gl(__GLXcontext *gc) +dri2_wait_gl(struct glx_context *gc) { struct dri2_drawable *priv = (struct dri2_drawable *) GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); @@ -421,19 +433,20 @@ static void dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate) { struct dri2_drawable *pdraw = loaderPrivate; - __GLXdisplayPrivate *priv = __glXInitialize(pdraw->base.psc->dpy); + struct glx_display *priv = __glXInitialize(pdraw->base.psc->dpy); struct dri2_display *pdp = (struct dri2_display *)priv->dri2Display; + struct glx_context *gc = __glXGetCurrentContext(); /* Old servers don't send invalidate events */ if (!pdp->invalidateAvailable) - dri2InvalidateBuffers(priv->dpy, pdraw->base.drawable); + dri2InvalidateBuffers(priv->dpy, pdraw->base.xDrawable); - dri2_copy_drawable(pdraw, DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); + dri2_wait_gl(gc); } static void -dri2DestroyScreen(__GLXscreenConfigs *base) +dri2DestroyScreen(struct glx_screen *base) { struct dri2_screen *psc = (struct dri2_screen *) base; @@ -481,11 +494,11 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, int64_t remainder) { struct dri2_drawable *priv = (struct dri2_drawable *) pdraw; - __GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy); + struct glx_display *dpyPriv = __glXInitialize(priv->base.psc->dpy); struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc; struct dri2_display *pdp = (struct dri2_display *)dpyPriv->dri2Display; - CARD64 ret; + CARD64 ret = 0; #ifdef __DRI2_FLUSH if (psc->f) @@ -494,7 +507,7 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, /* Old servers don't send invalidate events */ if (!pdp->invalidateAvailable) - dri2InvalidateBuffers(dpyPriv->dpy, pdraw->drawable); + dri2InvalidateBuffers(dpyPriv->dpy, pdraw->xDrawable); /* Old servers can't handle swapbuffers */ if (!pdp->swapAvailable) { @@ -637,16 +650,17 @@ dri2_bind_tex_image(Display * dpy, GLXDrawable drawable, int buffer, const int *attrib_list) { - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); + struct dri2_context *pcp = (struct dri2_context *) gc; __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable); - __GLXdisplayPrivate *dpyPriv = __glXInitialize(dpy); + struct glx_display *dpyPriv = __glXInitialize(dpy); struct dri2_drawable *pdraw = (struct dri2_drawable *) base; struct dri2_display *pdp = (struct dri2_display *) dpyPriv->dri2Display; - struct dri2_screen *psc = (struct dri2_screen *) base->psc; - struct dri2_context *pcp = (struct dri2_context *) gc->driContext; + struct dri2_screen *psc; if (pdraw != NULL) { + psc = (struct dri2_screen *) base->psc; #if __DRI2_FLUSH_VERSION >= 3 if (!pdp->invalidateAvailable && psc->f) @@ -674,6 +688,9 @@ dri2_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer) } static const struct glx_context_vtable dri2_context_vtable = { + dri2_destroy_context, + dri2_bind_context, + dri2_unbind_context, dri2_wait_gl, dri2_wait_x, DRI_glXUseXFont, @@ -710,9 +727,12 @@ dri2BindExtensions(struct dri2_screen *psc, const __DRIextension **extensions) } } +static const struct glx_screen_vtable dri2_screen_vtable = { + dri2_create_context +}; -static __GLXscreenConfigs * -dri2CreateScreen(int screen, __GLXdisplayPrivate * priv) +static struct glx_screen * +dri2CreateScreen(int screen, struct glx_display * priv) { const __DRIconfig **driver_configs; const __DRIextension **extensions; @@ -803,10 +823,10 @@ dri2CreateScreen(int screen, __GLXdisplayPrivate * priv) psc->driver_configs = driver_configs; + psc->base.vtable = &dri2_screen_vtable; psp = &psc->vtable; psc->base.driScreen = psp; psp->destroyScreen = dri2DestroyScreen; - psp->createContext = dri2CreateContext; psp->createDrawable = dri2CreateDrawable; psp->swapBuffers = dri2SwapBuffers; psp->getDrawableMSC = NULL; @@ -863,7 +883,7 @@ dri2DestroyDisplay(__GLXDRIdisplay * dpy) _X_HIDDEN __GLXDRIdrawable * dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id) { - __GLXdisplayPrivate *d = __glXInitialize(dpy); + struct glx_display *d = __glXInitialize(dpy); struct dri2_display *pdp = (struct dri2_display *) d->dri2Display; __GLXDRIdrawable *pdraw; diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c index 9b7da3e7df5..a7fb4c64244 100644 --- a/src/glx/dri_common.c +++ b/src/glx/dri_common.c @@ -39,7 +39,6 @@ #include <dlfcn.h> #include <stdarg.h> #include "glxclient.h" -#include "glcontextmodes.h" #include "dri_common.h" #ifndef RTLD_NOW @@ -176,7 +175,7 @@ _X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension = { }; #define __ATTRIB(attrib, field) \ - { attrib, offsetof(__GLcontextModes, field) } + { attrib, offsetof(struct glx_config, field) } static const struct { @@ -225,10 +224,8 @@ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), bindToMipmapTexture), __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),}; -#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) - static int -scalarEqual(__GLcontextModes * mode, unsigned int attrib, unsigned int value) +scalarEqual(struct glx_config *mode, unsigned int attrib, unsigned int value) { unsigned int glxValue; int i; @@ -243,8 +240,8 @@ scalarEqual(__GLcontextModes * mode, unsigned int attrib, unsigned int value) } static int -driConfigEqual(const __DRIcoreExtension * core, - __GLcontextModes * modes, const __DRIconfig * driConfig) +driConfigEqual(const __DRIcoreExtension *core, + struct glx_config *config, const __DRIconfig *driConfig) { unsigned int attrib, value, glxValue; int i; @@ -260,7 +257,7 @@ driConfigEqual(const __DRIcoreExtension * core, else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) { glxValue |= GLX_COLOR_INDEX_BIT; } - if (glxValue != modes->renderType) + if (glxValue != config->renderType) return GL_FALSE; break; @@ -271,7 +268,7 @@ driConfigEqual(const __DRIcoreExtension * core, glxValue = GLX_SLOW_CONFIG; else glxValue = GLX_NONE; - if (glxValue != modes->visualRating) + if (glxValue != config->visualRating) return GL_FALSE; break; @@ -283,13 +280,13 @@ driConfigEqual(const __DRIcoreExtension * core, glxValue |= GLX_TEXTURE_2D_BIT_EXT; if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT) glxValue |= GLX_TEXTURE_RECTANGLE_BIT_EXT; - if (modes->bindToTextureTargets != GLX_DONT_CARE && - glxValue != modes->bindToTextureTargets) + if (config->bindToTextureTargets != GLX_DONT_CARE && + glxValue != config->bindToTextureTargets) return GL_FALSE; break; default: - if (!scalarEqual(modes, attrib, value)) + if (!scalarEqual(config, attrib, value)) return GL_FALSE; } } @@ -297,41 +294,41 @@ driConfigEqual(const __DRIcoreExtension * core, return GL_TRUE; } -static __GLcontextModes * +static struct glx_config * createDriMode(const __DRIcoreExtension * core, - __GLcontextModes * modes, const __DRIconfig ** driConfigs) + struct glx_config *config, const __DRIconfig **driConfigs) { - __GLXDRIconfigPrivate *config; + __GLXDRIconfigPrivate *driConfig; int i; for (i = 0; driConfigs[i]; i++) { - if (driConfigEqual(core, modes, driConfigs[i])) + if (driConfigEqual(core, config, driConfigs[i])) break; } if (driConfigs[i] == NULL) return NULL; - config = Xmalloc(sizeof *config); - if (config == NULL) + driConfig = Xmalloc(sizeof *driConfig); + if (driConfig == NULL) return NULL; - config->modes = *modes; - config->driConfig = driConfigs[i]; + driConfig->base = *config; + driConfig->driConfig = driConfigs[i]; - return &config->modes; + return &driConfig->base; } -_X_HIDDEN __GLcontextModes * +_X_HIDDEN struct glx_config * driConvertConfigs(const __DRIcoreExtension * core, - __GLcontextModes * modes, const __DRIconfig ** configs) + struct glx_config *configs, const __DRIconfig **driConfigs) { - __GLcontextModes head, *tail, *m; + struct glx_config head, *tail, *m; tail = &head; head.next = NULL; - for (m = modes; m; m = m->next) { - tail->next = createDriMode(core, m, configs); + for (m = configs; m; m = m->next) { + tail->next = createDriMode(core, m, driConfigs); if (tail->next == NULL) { /* no matching dri config for m */ continue; @@ -341,7 +338,7 @@ driConvertConfigs(const __DRIcoreExtension * core, tail = tail->next; } - _gl_context_modes_destroy(modes); + glx_config_destroy_list(configs); return head.next; } @@ -356,4 +353,31 @@ driDestroyConfigs(const __DRIconfig **configs) free(configs); } +_X_HIDDEN __GLXDRIdrawable * +driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable) +{ + struct glx_display *const priv = __glXInitialize(gc->psc->dpy); + __GLXDRIdrawable *pdraw; + struct glx_screen *psc; + + if (priv == NULL) + return NULL; + + psc = priv->screens[gc->screen]; + if (priv->drawHash == NULL) + return NULL; + + if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0) + return pdraw; + + pdraw = psc->driScreen->createDrawable(psc, glxDrawable, + glxDrawable, gc->config); + if (__glxHashInsert(priv->drawHash, glxDrawable, pdraw)) { + (*pdraw->destroyDrawable) (pdraw); + return NULL; + } + + return pdraw; +} + #endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/dri_common.h b/src/glx/dri_common.h index f3da50ecf09..846a905a880 100644 --- a/src/glx/dri_common.h +++ b/src/glx/dri_common.h @@ -42,16 +42,19 @@ typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate; struct __GLXDRIconfigPrivateRec { - __GLcontextModes modes; + struct glx_config base; const __DRIconfig *driConfig; }; -extern __GLcontextModes *driConvertConfigs(const __DRIcoreExtension * core, - __GLcontextModes * modes, +extern struct glx_config *driConvertConfigs(const __DRIcoreExtension * core, + struct glx_config * modes, const __DRIconfig ** configs); extern void driDestroyConfigs(const __DRIconfig **configs); +extern __GLXDRIdrawable * +driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable); + extern const __DRIsystemTimeExtension systemTimeExtension; extern void InfoMessageF(const char *f, ...); diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index 352d833fd7d..43a2aa495a7 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -61,7 +61,7 @@ struct dri_display struct dri_screen { - __GLXscreenConfigs base; + struct glx_screen base; __DRIscreen *driScreen; __GLXDRIscreen vtable; @@ -78,11 +78,9 @@ struct dri_screen struct dri_context { - __GLXcontext base; - __GLXDRIcontext dri_vtable; + struct glx_context base; __DRIcontext *driContext; XID hwContextID; - __GLXscreenConfigs *psc; }; struct dri_drawable @@ -92,13 +90,7 @@ struct dri_drawable __DRIdrawable *driDrawable; }; -static const struct glx_context_vtable dri_context_vtable = { - NULL, - NULL, - DRI_glXUseXFont, - NULL, - NULL, -}; +static const struct glx_context_vtable dri_context_vtable; /* * Given a display pointer and screen number, determine the name of @@ -158,7 +150,7 @@ driGetDriverName(Display * dpy, int scrNum, char **driverName) * The returned char pointer points to a static array that will be * overwritten by subsequent calls. */ -PUBLIC const char * +_X_EXPORT const char * glXGetScreenDriver(Display * dpy, int scrNum) { static char ret[32]; @@ -188,7 +180,7 @@ glXGetScreenDriver(Display * dpy, int scrNum) * * Note: The driver remains opened after this function returns. */ -PUBLIC const char * +_X_EXPORT const char * glXGetDriverConfig(const char *driverName) { void *handle = driOpenDriver(driverName); @@ -233,7 +225,7 @@ __glXReportDamage(__DRIdrawable * driDraw, int i; int x_off, y_off; __GLXDRIdrawable *glxDraw = loaderPrivate; - __GLXscreenConfigs *psc = glxDraw->psc; + struct glx_screen *psc = glxDraw->psc; Display *dpy = psc->dpy; Drawable drawable; @@ -285,7 +277,7 @@ __glXDRIGetDrawableInfo(__DRIdrawable * drawable, void *loaderPrivate) { __GLXDRIdrawable *glxDraw = loaderPrivate; - __GLXscreenConfigs *psc = glxDraw->psc; + struct glx_screen *psc = glxDraw->psc; Display *dpy = psc->dpy; return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable, @@ -344,7 +336,7 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, drm_handle_t hFB; int junk; const __DRIconfig **driver_configs; - __GLcontextModes *visual; + struct glx_config *visual; /* DRI protocol version. */ dri_version.major = driDpy->driMajor; @@ -506,55 +498,82 @@ CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc, } static void -driDestroyContext(__GLXcontext * context) +dri_destroy_context(struct glx_context * context) { struct dri_context *pcp = (struct dri_context *) context; struct dri_screen *psc = (struct dri_screen *) context->psc; + if (context->xid) + glx_send_destroy_context(psc->base.dpy, context->xid); + + if (context->extensions) + XFree((char *) context->extensions); + + GarbageCollectDRIDrawables(context->psc); + (*psc->core->destroyContext) (pcp->driContext); XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID); Xfree(pcp); } -static Bool -driBindContext(__GLXcontext *context, - __GLXDRIdrawable *draw, __GLXDRIdrawable *read) +static int +dri_bind_context(struct glx_context *context, struct glx_context *old, + GLXDrawable draw, GLXDrawable read) { struct dri_context *pcp = (struct dri_context *) context; - struct dri_screen *psc = (struct dri_screen *) pcp->psc; - struct dri_drawable *pdr = (struct dri_drawable *) draw; - struct dri_drawable *prd = (struct dri_drawable *) read; + struct dri_screen *psc = (struct dri_screen *) pcp->base.psc; + struct dri_drawable *pdraw, *pread; + + pdraw = (struct dri_drawable *) driFetchDrawable(context, draw); + pread = (struct dri_drawable *) driFetchDrawable(context, read); - return (*psc->core->bindContext) (pcp->driContext, - pdr->driDrawable, prd->driDrawable); + if (pdraw == NULL || pread == NULL) + return GLXBadDrawable; + + if ((*psc->core->bindContext) (pcp->driContext, + pdraw->driDrawable, pread->driDrawable)) + return Success; + + return GLXBadContext; } static void -driUnbindContext(__GLXcontext * context) +dri_unbind_context(struct glx_context *context, struct glx_context *new) { struct dri_context *pcp = (struct dri_context *) context; - struct dri_screen *psc = (struct dri_screen *) pcp->psc; + struct dri_screen *psc = (struct dri_screen *) pcp->base.psc; (*psc->core->unbindContext) (pcp->driContext); } -static __GLXcontext * -driCreateContext(__GLXscreenConfigs *base, - const __GLcontextModes * mode, - GLXContext shareList, int renderType) +static const struct glx_context_vtable dri_context_vtable = { + dri_destroy_context, + dri_bind_context, + dri_unbind_context, + NULL, + NULL, + DRI_glXUseXFont, + NULL, + NULL, +}; + +static struct glx_context * +dri_create_context(struct glx_screen *base, + struct glx_config *config_base, + struct glx_context *shareList, int renderType) { struct dri_context *pcp, *pcp_shared; struct dri_screen *psc = (struct dri_screen *) base; drm_context_t hwContext; __DRIcontext *shared = NULL; - __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; if (!psc->base.driScreen) return NULL; if (shareList) { - pcp_shared = (struct dri_context *) shareList->driContext; + pcp_shared = (struct dri_context *) shareList; shared = pcp_shared->driContext; } @@ -563,13 +582,13 @@ driCreateContext(__GLXscreenConfigs *base, return NULL; memset(pcp, 0, sizeof *pcp); - if (!glx_context_init(&pcp->base, &psc->base, mode)) { + if (!glx_context_init(&pcp->base, &psc->base, &config->base)) { Xfree(pcp); return NULL; } if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr, - mode->visualID, + config->base.visualID, &pcp->hwContextID, &hwContext)) { Xfree(pcp); return NULL; @@ -586,10 +605,6 @@ driCreateContext(__GLXscreenConfigs *base, } pcp->base.vtable = &dri_context_vtable; - pcp->base.driContext = &pcp->dri_vtable; - pcp->dri_vtable.destroyContext = driDestroyContext; - pcp->dri_vtable.bindContext = driBindContext; - pcp->dri_vtable.unbindContext = driUnbindContext; return &pcp->base; } @@ -606,13 +621,13 @@ driDestroyDrawable(__GLXDRIdrawable * pdraw) } static __GLXDRIdrawable * -driCreateDrawable(__GLXscreenConfigs *base, +driCreateDrawable(struct glx_screen *base, XID xDrawable, - GLXDrawable drawable, const __GLcontextModes * modes) + GLXDrawable drawable, struct glx_config *config_base) { drm_drawable_t hwDrawable; void *empty_attribute_list = NULL; - __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; struct dri_screen *psc = (struct dri_screen *) base; struct dri_drawable *pdp; @@ -624,6 +639,7 @@ driCreateDrawable(__GLXscreenConfigs *base, if (!pdp) return NULL; + memset(pdp, 0, sizeof *pdp); pdp->base.drawable = drawable; pdp->base.psc = &psc->base; @@ -675,7 +691,7 @@ driCopySubBuffer(__GLXDRIdrawable * pdraw, } static void -driDestroyScreen(__GLXscreenConfigs *base) +driDestroyScreen(struct glx_screen *base) { struct dri_screen *psc = (struct dri_screen *) base; @@ -691,7 +707,7 @@ driDestroyScreen(__GLXscreenConfigs *base) #ifdef __DRI_SWAP_BUFFER_COUNTER static int -driDrawableGetMSC(__GLXscreenConfigs *base, __GLXDRIdrawable *pdraw, +driDrawableGetMSC(struct glx_screen *base, __GLXDRIdrawable *pdraw, int64_t *ust, int64_t *msc, int64_t *sbc) { struct dri_screen *psc = (struct dri_screen *) base; @@ -746,17 +762,12 @@ driWaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, static int driSetSwapInterval(__GLXDRIdrawable *pdraw, int interval) { - GLXContext gc = __glXGetCurrentContext(); struct dri_drawable *pdp = (struct dri_drawable *) pdraw; - struct dri_screen *psc; - - if (gc->driContext) { - psc = (struct dri_screen *) pdraw->psc; + struct dri_screen *psc = (struct dri_screen *) pdraw->psc; - if (psc->swapControl != NULL && pdraw != NULL) { - psc->swapControl->setSwapInterval(pdp->driDrawable, interval); - return 0; - } + if (psc->swapControl != NULL && pdraw != NULL) { + psc->swapControl->setSwapInterval(pdp->driDrawable, interval); + return 0; } return GLX_BAD_CONTEXT; @@ -765,17 +776,11 @@ driSetSwapInterval(__GLXDRIdrawable *pdraw, int interval) static int driGetSwapInterval(__GLXDRIdrawable *pdraw) { - GLXContext gc = __glXGetCurrentContext(); struct dri_drawable *pdp = (struct dri_drawable *) pdraw; - struct dri_screen *psc; - - if (gc != NULL && gc->driContext) { - psc = (struct dri_screen *) pdraw->psc; + struct dri_screen *psc = (struct dri_screen *) pdraw->psc; - if (psc->swapControl != NULL && pdraw != NULL) { - return psc->swapControl->getSwapInterval(pdp->driDrawable); - } - } + if (psc->swapControl != NULL && pdraw != NULL) + return psc->swapControl->getSwapInterval(pdp->driDrawable); return 0; } @@ -812,8 +817,12 @@ driBindExtensions(struct dri_screen *psc, const __DRIextension **extensions) } } -static __GLXscreenConfigs * -driCreateScreen(int screen, __GLXdisplayPrivate *priv) +static const struct glx_screen_vtable dri_screen_vtable = { + dri_create_context +}; + +static struct glx_screen * +driCreateScreen(int screen, struct glx_display *priv) { struct dri_display *pdp; __GLXDRIscreen *psp; @@ -873,13 +882,13 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv) extensions = psc->core->getExtensions(psc->driScreen); driBindExtensions(psc, extensions); + psc->base.vtable = &dri_screen_vtable; psp = &psc->vtable; psc->base.driScreen = psp; if (psc->driCopySubBuffer) psp->copySubBuffer = driCopySubBuffer; psp->destroyScreen = driDestroyScreen; - psp->createContext = driCreateContext; psp->createDrawable = driCreateDrawable; psp->swapBuffers = driSwapBuffers; diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index 0ad73914575..c5b179157b3 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -35,15 +35,14 @@ struct drisw_display struct drisw_context { - __GLXcontext base; - __GLXDRIcontext dri_vtable; + struct glx_context base; __DRIcontext *driContext; - __GLXscreenConfigs *psc; + }; struct drisw_screen { - __GLXscreenConfigs base; + struct glx_screen base; __DRIscreen *driScreen; __GLXDRIscreen vtable; @@ -240,39 +239,58 @@ static const __DRIextension *loader_extensions[] = { */ static void -driDestroyContext(__GLXcontext *context) +drisw_destroy_context(struct glx_context *context) { struct drisw_context *pcp = (struct drisw_context *) context; struct drisw_screen *psc = (struct drisw_screen *) context->psc; + if (context->xid) + glx_send_destroy_context(psc->base.dpy, context->xid); + + if (context->extensions) + XFree((char *) context->extensions); + + GarbageCollectDRIDrawables(context->psc); + (*psc->core->destroyContext) (pcp->driContext); Xfree(pcp); } -static Bool -driBindContext(__GLXcontext * context, - __GLXDRIdrawable * draw, __GLXDRIdrawable * read) +static int +drisw_bind_context(struct glx_context *context, struct glx_context *old, + GLXDrawable draw, GLXDrawable read) { struct drisw_context *pcp = (struct drisw_context *) context; - struct drisw_screen *psc = (struct drisw_screen *) pcp->psc; - struct drisw_drawable *pdr = (struct drisw_drawable *) draw; - struct drisw_drawable *prd = (struct drisw_drawable *) read; + struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc; + struct drisw_drawable *pdraw, *pread; + + pdraw = (struct drisw_drawable *) driFetchDrawable(context, draw); + pread = (struct drisw_drawable *) driFetchDrawable(context, read); + + if (pdraw == NULL || pread == NULL) + return GLXBadDrawable; - return (*psc->core->bindContext) (pcp->driContext, - pdr->driDrawable, prd->driDrawable); + if ((*psc->core->bindContext) (pcp->driContext, + pdraw->driDrawable, pread->driDrawable)) + return Success; + + return GLXBadContext; } static void -driUnbindContext(__GLXcontext * context) +drisw_unbind_context(struct glx_context *context, struct glx_context *new) { struct drisw_context *pcp = (struct drisw_context *) context; - struct drisw_screen *psc = (struct drisw_screen *) pcp->psc; + struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc; (*psc->core->unbindContext) (pcp->driContext); } static const struct glx_context_vtable drisw_context_vtable = { + drisw_destroy_context, + drisw_bind_context, + drisw_unbind_context, NULL, NULL, DRI_glXUseXFont, @@ -280,13 +298,13 @@ static const struct glx_context_vtable drisw_context_vtable = { NULL, }; -static __GLXcontext * -driCreateContext(__GLXscreenConfigs *base, - const __GLcontextModes *mode, - GLXContext shareList, int renderType) +static struct glx_context * +drisw_create_context(struct glx_screen *base, + struct glx_config *config_base, + struct glx_context *shareList, int renderType) { struct drisw_context *pcp, *pcp_shared; - __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode; + __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base; struct drisw_screen *psc = (struct drisw_screen *) base; __DRIcontext *shared = NULL; @@ -294,7 +312,7 @@ driCreateContext(__GLXscreenConfigs *base, return NULL; if (shareList) { - pcp_shared = (struct drisw_context *) shareList->driContext; + pcp_shared = (struct drisw_context *) shareList; shared = pcp_shared->driContext; } @@ -303,7 +321,7 @@ driCreateContext(__GLXscreenConfigs *base, return NULL; memset(pcp, 0, sizeof *pcp); - if (!glx_context_init(&pcp->base, &psc->base, mode)) { + if (!glx_context_init(&pcp->base, &psc->base, &config->base)) { Xfree(pcp); return NULL; } @@ -317,10 +335,6 @@ driCreateContext(__GLXscreenConfigs *base, } pcp->base.vtable = &drisw_context_vtable; - pcp->base.driContext = &pcp->dri_vtable; - pcp->dri_vtable.destroyContext = driDestroyContext; - pcp->dri_vtable.bindContext = driBindContext; - pcp->dri_vtable.unbindContext = driUnbindContext; return &pcp->base; } @@ -338,8 +352,8 @@ driDestroyDrawable(__GLXDRIdrawable * pdraw) } static __GLXDRIdrawable * -driCreateDrawable(__GLXscreenConfigs *base, XID xDrawable, - GLXDrawable drawable, const __GLcontextModes * modes) +driCreateDrawable(struct glx_screen *base, XID xDrawable, + GLXDrawable drawable, struct glx_config *modes) { struct drisw_drawable *pdp; __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes; @@ -355,6 +369,7 @@ driCreateDrawable(__GLXscreenConfigs *base, XID xDrawable, if (!pdp) return NULL; + memset(pdp, 0, sizeof *pdp); pdp->base.xDrawable = xDrawable; pdp->base.drawable = drawable; pdp->base.psc = &psc->base; @@ -393,7 +408,7 @@ driSwapBuffers(__GLXDRIdrawable * pdraw, } static void -driDestroyScreen(__GLXscreenConfigs *base) +driDestroyScreen(struct glx_screen *base) { struct drisw_screen *psc = (struct drisw_screen *) base; @@ -419,8 +434,12 @@ driOpenSwrast(void) return driver; } -static __GLXscreenConfigs * -driCreateScreen(int screen, __GLXdisplayPrivate *priv) +static const struct glx_screen_vtable drisw_screen_vtable = { + drisw_create_context +}; + +static struct glx_screen * +driCreateScreen(int screen, struct glx_display *priv) { __GLXDRIscreen *psp; const __DRIconfig **driver_configs; @@ -466,8 +485,6 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv) goto handle_error; } - extensions = psc->core->getExtensions(psc->driScreen); - psc->base.configs = driConvertConfigs(psc->core, psc->base.configs, driver_configs); psc->base.visuals = @@ -475,20 +492,19 @@ driCreateScreen(int screen, __GLXdisplayPrivate *priv) psc->driver_configs = driver_configs; + psc->base.vtable = &drisw_screen_vtable; psp = &psc->vtable; psc->base.driScreen = psp; psp->destroyScreen = driDestroyScreen; - psp->createContext = driCreateContext; psp->createDrawable = driCreateDrawable; psp->swapBuffers = driSwapBuffers; return &psc->base; handle_error: - Xfree(psc); - if (psc->driver) dlclose(psc->driver); + Xfree(psc); ErrorMessageF("reverting to indirect rendering\n"); diff --git a/src/glx/glcontextmodes.c b/src/glx/glcontextmodes.c deleted file mode 100644 index cdc16f8330a..00000000000 --- a/src/glx/glcontextmodes.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2003 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file glcontextmodes.c - * Utility routines for working with \c __GLcontextModes structures. At - * some point most or all of these functions will be moved to the Mesa - * code base. - * - * \author Ian Romanick <[email protected]> - */ - -#include <GL/glx.h> -#include "GL/glxint.h" -#include <stdlib.h> -#include <string.h> - -#include "glcontextmodes.h" - -#define NUM_VISUAL_TYPES 6 - -/** - * Convert an X visual type to a GLX visual type. - * - * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.) - * to be converted. - * \return If \c visualType is a valid X visual type, a GLX visual type will - * be returned. Otherwise \c GLX_NONE will be returned. - */ -GLint -_gl_convert_from_x_visual_type(int visualType) -{ - static const int glx_visual_types[NUM_VISUAL_TYPES] = { - GLX_STATIC_GRAY, GLX_GRAY_SCALE, - GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, - GLX_TRUE_COLOR, GLX_DIRECT_COLOR - }; - - return ((unsigned) visualType < NUM_VISUAL_TYPES) - ? glx_visual_types[visualType] : GLX_NONE; -} - - -/** - * Convert a GLX visual type to an X visual type. - * - * \param visualType GLX visual type (i.e., \c GLX_TRUE_COLOR, - * \c GLX_STATIC_GRAY, etc.) to be converted. - * \return If \c visualType is a valid GLX visual type, an X visual type will - * be returned. Otherwise -1 will be returned. - */ -GLint -_gl_convert_to_x_visual_type(int visualType) -{ - static const int x_visual_types[NUM_VISUAL_TYPES] = { - TrueColor, DirectColor, - PseudoColor, StaticColor, - GrayScale, StaticGray - }; - - return ((unsigned) (visualType - GLX_TRUE_COLOR) < NUM_VISUAL_TYPES) - ? x_visual_types[visualType - GLX_TRUE_COLOR] : -1; -} - - -/** - * Copy a GLX visual config structure to a GL context mode structure. All - * of the fields in \c config are copied to \c mode. Additional fields in - * \c mode that can be derrived from the fields of \c config (i.e., - * \c haveDepthBuffer) are also filled in. The remaining fields in \c mode - * that cannot be derived are set to default values. - * - * \param mode Destination GL context mode. - * \param config Source GLX visual config. - * - * \note - * The \c fbconfigID and \c visualID fields of the \c __GLcontextModes - * structure will be set to the \c vid of the \c __GLXvisualConfig structure. - */ -void -_gl_copy_visual_to_context_mode(__GLcontextModes * mode, - const __GLXvisualConfig * config) -{ - __GLcontextModes *const next = mode->next; - - (void) memset(mode, 0, sizeof(__GLcontextModes)); - mode->next = next; - - mode->visualID = config->vid; - mode->visualType = _gl_convert_from_x_visual_type(config->class); - mode->xRenderable = GL_TRUE; - mode->fbconfigID = config->vid; - mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; - - mode->rgbMode = (config->rgba != 0); - mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; - - mode->colorIndexMode = !(mode->rgbMode); - mode->doubleBufferMode = (config->doubleBuffer != 0); - mode->stereoMode = (config->stereo != 0); - - mode->haveAccumBuffer = ((config->accumRedSize + - config->accumGreenSize + - config->accumBlueSize + - config->accumAlphaSize) > 0); - mode->haveDepthBuffer = (config->depthSize > 0); - mode->haveStencilBuffer = (config->stencilSize > 0); - - mode->redBits = config->redSize; - mode->greenBits = config->greenSize; - mode->blueBits = config->blueSize; - mode->alphaBits = config->alphaSize; - mode->redMask = config->redMask; - mode->greenMask = config->greenMask; - mode->blueMask = config->blueMask; - mode->alphaMask = config->alphaMask; - mode->rgbBits = mode->rgbMode ? config->bufferSize : 0; - mode->indexBits = mode->colorIndexMode ? config->bufferSize : 0; - - mode->accumRedBits = config->accumRedSize; - mode->accumGreenBits = config->accumGreenSize; - mode->accumBlueBits = config->accumBlueSize; - mode->accumAlphaBits = config->accumAlphaSize; - mode->depthBits = config->depthSize; - mode->stencilBits = config->stencilSize; - - mode->numAuxBuffers = config->auxBuffers; - mode->level = config->level; - - mode->visualRating = config->visualRating; - mode->transparentPixel = config->transparentPixel; - mode->transparentRed = config->transparentRed; - mode->transparentGreen = config->transparentGreen; - mode->transparentBlue = config->transparentBlue; - mode->transparentAlpha = config->transparentAlpha; - mode->transparentIndex = config->transparentIndex; - mode->samples = config->multiSampleSize; - mode->sampleBuffers = config->nMultiSampleBuffers; - /* mode->visualSelectGroup = config->visualSelectGroup; ? */ - - mode->swapMethod = GLX_SWAP_UNDEFINED_OML; - - mode->bindToTextureRgb = (mode->rgbMode) ? GL_TRUE : GL_FALSE; - mode->bindToTextureRgba = (mode->rgbMode && mode->alphaBits) ? - GL_TRUE : GL_FALSE; - mode->bindToMipmapTexture = mode->rgbMode ? GL_TRUE : GL_FALSE; - mode->bindToTextureTargets = mode->rgbMode ? - GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | - GLX_TEXTURE_RECTANGLE_BIT_EXT : 0; - mode->yInverted = GL_FALSE; -} - - -/** - * Get data from a GL context mode. - * - * \param mode GL context mode whose data is to be returned. - * \param attribute Attribute of \c mode that is to be returned. - * \param value_return Location to store the data member of \c mode. - * \return If \c attribute is a valid attribute of \c mode, zero is - * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned. - */ -int -_gl_get_context_mode_data(const __GLcontextModes * mode, int attribute, - int *value_return) -{ - switch (attribute) { - case GLX_USE_GL: - *value_return = GL_TRUE; - return 0; - case GLX_BUFFER_SIZE: - *value_return = mode->rgbBits; - return 0; - case GLX_RGBA: - *value_return = mode->rgbMode; - return 0; - case GLX_RED_SIZE: - *value_return = mode->redBits; - return 0; - case GLX_GREEN_SIZE: - *value_return = mode->greenBits; - return 0; - case GLX_BLUE_SIZE: - *value_return = mode->blueBits; - return 0; - case GLX_ALPHA_SIZE: - *value_return = mode->alphaBits; - return 0; - case GLX_DOUBLEBUFFER: - *value_return = mode->doubleBufferMode; - return 0; - case GLX_STEREO: - *value_return = mode->stereoMode; - return 0; - case GLX_AUX_BUFFERS: - *value_return = mode->numAuxBuffers; - return 0; - case GLX_DEPTH_SIZE: - *value_return = mode->depthBits; - return 0; - case GLX_STENCIL_SIZE: - *value_return = mode->stencilBits; - return 0; - case GLX_ACCUM_RED_SIZE: - *value_return = mode->accumRedBits; - return 0; - case GLX_ACCUM_GREEN_SIZE: - *value_return = mode->accumGreenBits; - return 0; - case GLX_ACCUM_BLUE_SIZE: - *value_return = mode->accumBlueBits; - return 0; - case GLX_ACCUM_ALPHA_SIZE: - *value_return = mode->accumAlphaBits; - return 0; - case GLX_LEVEL: - *value_return = mode->level; - return 0; -#ifndef GLX_USE_APPLEGL /* This isn't supported by CGL. */ - case GLX_TRANSPARENT_TYPE_EXT: - *value_return = mode->transparentPixel; - return 0; -#endif - case GLX_TRANSPARENT_RED_VALUE: - *value_return = mode->transparentRed; - return 0; - case GLX_TRANSPARENT_GREEN_VALUE: - *value_return = mode->transparentGreen; - return 0; - case GLX_TRANSPARENT_BLUE_VALUE: - *value_return = mode->transparentBlue; - return 0; - case GLX_TRANSPARENT_ALPHA_VALUE: - *value_return = mode->transparentAlpha; - return 0; - case GLX_TRANSPARENT_INDEX_VALUE: - *value_return = mode->transparentIndex; - return 0; - case GLX_X_VISUAL_TYPE: - *value_return = mode->visualType; - return 0; - case GLX_CONFIG_CAVEAT: - *value_return = mode->visualRating; - return 0; - case GLX_VISUAL_ID: - *value_return = mode->visualID; - return 0; - case GLX_DRAWABLE_TYPE: - *value_return = mode->drawableType; - return 0; - case GLX_RENDER_TYPE: - *value_return = mode->renderType; - return 0; - case GLX_X_RENDERABLE: - *value_return = mode->xRenderable; - return 0; - case GLX_FBCONFIG_ID: - *value_return = mode->fbconfigID; - return 0; - case GLX_MAX_PBUFFER_WIDTH: - *value_return = mode->maxPbufferWidth; - return 0; - case GLX_MAX_PBUFFER_HEIGHT: - *value_return = mode->maxPbufferHeight; - return 0; - case GLX_MAX_PBUFFER_PIXELS: - *value_return = mode->maxPbufferPixels; - return 0; -#ifndef GLX_USE_APPLEGL /* These aren't supported by CGL. */ - case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: - *value_return = mode->optimalPbufferWidth; - return 0; - case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: - *value_return = mode->optimalPbufferHeight; - return 0; - case GLX_SWAP_METHOD_OML: - *value_return = mode->swapMethod; - return 0; -#endif - case GLX_SAMPLE_BUFFERS_SGIS: - *value_return = mode->sampleBuffers; - return 0; - case GLX_SAMPLES_SGIS: - *value_return = mode->samples; - return 0; - case GLX_BIND_TO_TEXTURE_RGB_EXT: - *value_return = mode->bindToTextureRgb; - return 0; - case GLX_BIND_TO_TEXTURE_RGBA_EXT: - *value_return = mode->bindToTextureRgba; - return 0; - case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: - *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE : - GL_FALSE; - return 0; - case GLX_BIND_TO_TEXTURE_TARGETS_EXT: - *value_return = mode->bindToTextureTargets; - return 0; - case GLX_Y_INVERTED_EXT: - *value_return = mode->yInverted; - return 0; - - /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX. - * It is ONLY for communication between the GLX client and the GLX - * server. - */ - case GLX_VISUAL_SELECT_GROUP_SGIX: - default: - return GLX_BAD_ATTRIBUTE; - } -} - - -/** - * Allocate a linked list of \c __GLcontextModes structures. The fields of - * each structure will be initialized to "reasonable" default values. In - * most cases this is the default value defined by table 3.4 of the GLX - * 1.3 specification. This means that most values are either initialized to - * zero or \c GLX_DONT_CARE (which is -1). As support for additional - * extensions is added, the new values will be initialized to appropriate - * values from the extension specification. - * - * \param count Number of structures to allocate. - * \param minimum_size Minimum size of a structure to allocate. This allows - * for differences in the version of the - * \c __GLcontextModes stucture used in libGL and in a - * DRI-based driver. - * \returns A pointer to the first element in a linked list of \c count - * stuctures on success, or \c NULL on failure. - * - * \warning Use of \c minimum_size does \b not guarantee binary compatibility. - * The fundamental assumption is that if the \c minimum_size - * specified by the driver and the size of the \c __GLcontextModes - * structure in libGL is the same, then the meaning of each byte in - * the structure is the same in both places. \b Be \b careful! - * Basically this means that fields have to be added in libGL and - * then propagated to drivers. Drivers should \b never arbitrarilly - * extend the \c __GLcontextModes data-structure. - */ -__GLcontextModes * -_gl_context_modes_create(unsigned count, size_t minimum_size) -{ - const size_t size = (minimum_size > sizeof(__GLcontextModes)) - ? minimum_size : sizeof(__GLcontextModes); - __GLcontextModes *base = NULL; - __GLcontextModes **next; - unsigned i; - - next = &base; - for (i = 0; i < count; i++) { - *next = (__GLcontextModes *) malloc(size); - if (*next == NULL) { - _gl_context_modes_destroy(base); - base = NULL; - break; - } - - (void) memset(*next, 0, size); - (*next)->visualID = GLX_DONT_CARE; - (*next)->visualType = GLX_DONT_CARE; - (*next)->visualRating = GLX_NONE; - (*next)->transparentPixel = GLX_NONE; - (*next)->transparentRed = GLX_DONT_CARE; - (*next)->transparentGreen = GLX_DONT_CARE; - (*next)->transparentBlue = GLX_DONT_CARE; - (*next)->transparentAlpha = GLX_DONT_CARE; - (*next)->transparentIndex = GLX_DONT_CARE; - (*next)->xRenderable = GLX_DONT_CARE; - (*next)->fbconfigID = GLX_DONT_CARE; - (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; - (*next)->bindToTextureRgb = GLX_DONT_CARE; - (*next)->bindToTextureRgba = GLX_DONT_CARE; - (*next)->bindToMipmapTexture = GLX_DONT_CARE; - (*next)->bindToTextureTargets = GLX_DONT_CARE; - (*next)->yInverted = GLX_DONT_CARE; - - next = &((*next)->next); - } - - return base; -} - - -/** - * Destroy a linked list of \c __GLcontextModes structures created by - * \c _gl_context_modes_create. - * - * \param modes Linked list of structures to be destroyed. All structres - * in the list will be freed. - */ -void -_gl_context_modes_destroy(__GLcontextModes * modes) -{ - while (modes != NULL) { - __GLcontextModes *const next = modes->next; - - free(modes); - modes = next; - } -} - - -/** - * Find a context mode matching a Visual ID. - * - * \param modes List list of context-mode structures to be searched. - * \param vid Visual ID to be found. - * \returns A pointer to a context-mode in \c modes if \c vid was found in - * the list, or \c NULL if it was not. - */ - -__GLcontextModes * -_gl_context_modes_find_visual(__GLcontextModes * modes, int vid) -{ - __GLcontextModes *m; - - for (m = modes; m != NULL; m = m->next) - if (m->visualID == vid) - return m; - - return NULL; -} - -__GLcontextModes * -_gl_context_modes_find_fbconfig(__GLcontextModes * modes, int fbid) -{ - __GLcontextModes *m; - - for (m = modes; m != NULL; m = m->next) - if (m->fbconfigID == fbid) - return m; - - return NULL; -} - -/** - * Determine if two context-modes are the same. This is intended to be used - * by libGL implementations to compare to sets of driver generated FBconfigs. - * - * \param a Context-mode to be compared. - * \param b Context-mode to be compared. - * \returns \c GL_TRUE if the two context-modes are the same. \c GL_FALSE is - * returned otherwise. - */ -GLboolean -_gl_context_modes_are_same(const __GLcontextModes * a, - const __GLcontextModes * b) -{ - return ((a->rgbMode == b->rgbMode) && - (a->floatMode == b->floatMode) && - (a->colorIndexMode == b->colorIndexMode) && - (a->doubleBufferMode == b->doubleBufferMode) && - (a->stereoMode == b->stereoMode) && - (a->redBits == b->redBits) && - (a->greenBits == b->greenBits) && - (a->blueBits == b->blueBits) && (a->alphaBits == b->alphaBits) && -#if 0 /* For some reason these don't get set on the client-side in libGL. */ - (a->redMask == b->redMask) && - (a->greenMask == b->greenMask) && - (a->blueMask == b->blueMask) && (a->alphaMask == b->alphaMask) && -#endif - (a->rgbBits == b->rgbBits) && - (a->indexBits == b->indexBits) && - (a->accumRedBits == b->accumRedBits) && - (a->accumGreenBits == b->accumGreenBits) && - (a->accumBlueBits == b->accumBlueBits) && - (a->accumAlphaBits == b->accumAlphaBits) && - (a->depthBits == b->depthBits) && - (a->stencilBits == b->stencilBits) && - (a->numAuxBuffers == b->numAuxBuffers) && - (a->level == b->level) && - (a->pixmapMode == b->pixmapMode) && - (a->visualRating == b->visualRating) && - (a->transparentPixel == b->transparentPixel) && - ((a->transparentPixel != GLX_TRANSPARENT_RGB) || - ((a->transparentRed == b->transparentRed) && - (a->transparentGreen == b->transparentGreen) && - (a->transparentBlue == b->transparentBlue) && - (a->transparentAlpha == b->transparentAlpha))) && - ((a->transparentPixel != GLX_TRANSPARENT_INDEX) || - (a->transparentIndex == b->transparentIndex)) && - (a->sampleBuffers == b->sampleBuffers) && - (a->samples == b->samples) && - ((a->drawableType & b->drawableType) != 0) && - (a->renderType == b->renderType) && - (a->maxPbufferWidth == b->maxPbufferWidth) && - (a->maxPbufferHeight == b->maxPbufferHeight) && - (a->maxPbufferPixels == b->maxPbufferPixels) && - (a->optimalPbufferWidth == b->optimalPbufferWidth) && - (a->optimalPbufferHeight == b->optimalPbufferHeight) && - (a->swapMethod == b->swapMethod) && - (a->bindToTextureRgb == b->bindToTextureRgb) && - (a->bindToTextureRgba == b->bindToTextureRgba) && - (a->bindToMipmapTexture == b->bindToMipmapTexture) && - (a->bindToTextureTargets == b->bindToTextureTargets) && - (a->yInverted == b->yInverted)); -} diff --git a/src/glx/glcontextmodes.h b/src/glx/glcontextmodes.h deleted file mode 100644 index ecf0280cba3..00000000000 --- a/src/glx/glcontextmodes.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * (C) Copyright IBM Corporation 2003 - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * \file glcontextmodes.h - * \author Ian Romanick <[email protected]> - */ - -#ifndef GLCONTEXTMODES_H -#define GLCONTEXTMODES_H - -#include "GL/internal/glcore.h" - -extern GLint _gl_convert_from_x_visual_type(int visualType); -extern GLint _gl_convert_to_x_visual_type(int visualType); -extern void _gl_copy_visual_to_context_mode(__GLcontextModes * mode, - const __GLXvisualConfig * config); -extern int _gl_get_context_mode_data(const __GLcontextModes * mode, - int attribute, int *value_return); - -extern __GLcontextModes *_gl_context_modes_create(unsigned count, - size_t minimum_size); -extern void _gl_context_modes_destroy(__GLcontextModes * modes); -extern __GLcontextModes *_gl_context_modes_find_visual(__GLcontextModes * - modes, int vid); -extern __GLcontextModes *_gl_context_modes_find_fbconfig(__GLcontextModes * - modes, int fbid); -extern GLboolean _gl_context_modes_are_same(const __GLcontextModes * a, - const __GLcontextModes * b); - -#endif /* GLCONTEXTMODES_H */ diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c index 02809aacfa5..15bfb159191 100644 --- a/src/glx/glx_pbuffer.c +++ b/src/glx/glx_pbuffer.c @@ -57,7 +57,7 @@ static void warn_GLX_1_3(Display * dpy, const char *function_name) { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); + struct glx_display *priv = __glXInitialize(dpy); if (priv->minorVersion < 3) { fprintf(stderr, @@ -85,7 +85,7 @@ static void ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable, const CARD32 * attribs, size_t num_attribs) { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); + struct glx_display *priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw; CARD32 *output; CARD8 opcode; @@ -183,20 +183,20 @@ determineTextureFormat(const int *attribs, int numAttribs) } static void -CreateDRIDrawable(Display *dpy, const __GLcontextModes *fbconfig, +CreateDRIDrawable(Display *dpy, struct glx_config *config, XID drawable, XID glxdrawable, const int *attrib_list, size_t num_attribs) { - __GLXdisplayPrivate *const priv = __glXInitialize(dpy); + struct glx_display *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw; - __GLXscreenConfigs *psc; + struct glx_screen *psc; - psc = priv->screenConfigs[fbconfig->screen]; + psc = priv->screens[config->screen]; if (psc->driScreen == NULL) return; pdraw = psc->driScreen->createDrawable(psc, drawable, - glxdrawable, fbconfig); + glxdrawable, config); if (pdraw == NULL) { fprintf(stderr, "failed to create drawable\n"); return; @@ -214,7 +214,7 @@ CreateDRIDrawable(Display *dpy, const __GLcontextModes *fbconfig, static void DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable) { - __GLXdisplayPrivate *const priv = __glXInitialize(dpy); + struct glx_display *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); if (pdraw != NULL) { @@ -228,7 +228,7 @@ DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable) #else static void -CreateDRIDrawable(Display *dpy, const __GLcontextModes * fbconfig, +CreateDRIDrawable(Display *dpy, const struct glx_config * fbconfig, XID drawable, XID glxdrawable, const int *attrib_list, size_t num_attribs) { @@ -263,7 +263,7 @@ static int GetDrawableAttribute(Display * dpy, GLXDrawable drawable, int attribute, unsigned int *value) { - __GLXdisplayPrivate *priv; + struct glx_display *priv; xGLXGetDrawableAttributesReply reply; CARD32 *data; CARD8 opcode; @@ -367,7 +367,7 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable, * This function needs to be modified to work with direct-rendering drivers. */ static GLXDrawable -CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig, +CreateDrawable(Display *dpy, struct glx_config *config, Drawable drawable, const int *attrib_list, CARD8 glxCode) { xGLXCreateWindowReq *req; @@ -391,11 +391,11 @@ CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig, req->reqType = opcode; req->glxCode = glxCode; - req->screen = (CARD32) fbconfig->screen; - req->fbconfig = fbconfig->fbconfigID; - req->window = (CARD32) drawable; - req->glxwindow = (GLXWindow) XAllocID(dpy); - req->numAttribs = (CARD32) i; + req->screen = config->screen; + req->fbconfig = config->fbconfigID; + req->window = drawable; + req->glxwindow = XAllocID(dpy); + req->numAttribs = i; if (attrib_list) memcpy(data, attrib_list, 8 * i); @@ -403,9 +403,9 @@ CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig, UnlockDisplay(dpy); SyncHandle(); - CreateDRIDrawable(dpy, fbconfig, drawable, req->glxwindow, attrib_list, i); + CreateDRIDrawable(dpy, config, drawable, req->glxwindow, attrib_list, i); - return (GLXDrawable) req->glxwindow; + return req->glxwindow; } @@ -457,11 +457,11 @@ DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode) * This function needs to be modified to work with direct-rendering drivers. */ static GLXDrawable -CreatePbuffer(Display * dpy, const __GLcontextModes * fbconfig, +CreatePbuffer(Display * dpy, struct glx_config *config, unsigned int width, unsigned int height, const int *attrib_list, GLboolean size_in_attribs) { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); + struct glx_display *priv = __glXInitialize(dpy); GLXDrawable id = 0; CARD32 *data; CARD8 opcode; @@ -490,10 +490,10 @@ CreatePbuffer(Display * dpy, const __GLcontextModes * fbconfig, req->reqType = opcode; req->glxCode = X_GLXCreatePbuffer; - req->screen = (CARD32) fbconfig->screen; - req->fbconfig = fbconfig->fbconfigID; - req->pbuffer = (GLXPbuffer) id; - req->numAttribs = (CARD32) (i + extra); + req->screen = config->screen; + req->fbconfig = config->fbconfigID; + req->pbuffer = id; + req->numAttribs = i + extra; if (!size_in_attribs) { data[(2 * i) + 0] = GLX_PBUFFER_WIDTH; @@ -513,11 +513,11 @@ CreatePbuffer(Display * dpy, const __GLcontextModes * fbconfig, vpreq->glxCode = X_GLXVendorPrivate; vpreq->vendorCode = X_GLXvop_CreateGLXPbufferSGIX; - data[0] = (CARD32) fbconfig->screen; - data[1] = (CARD32) fbconfig->fbconfigID; - data[2] = (CARD32) id; - data[3] = (CARD32) width; - data[4] = (CARD32) height; + data[0] = config->screen; + data[1] = config->fbconfigID; + data[2] = id; + data[3] = width; + data[4] = height; data += 5; } @@ -526,10 +526,10 @@ CreatePbuffer(Display * dpy, const __GLcontextModes * fbconfig, UnlockDisplay(dpy); SyncHandle(); - pixmap = XCreatePixmap(dpy, RootWindow(dpy, fbconfig->screen), - width, height, fbconfig->rgbBits); + pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen), + width, height, config->rgbBits); - CreateDRIDrawable(dpy, fbconfig, pixmap, id, attrib_list, i); + CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i); return id; } @@ -547,7 +547,7 @@ CreatePbuffer(Display * dpy, const __GLcontextModes * fbconfig, static void DestroyPbuffer(Display * dpy, GLXDrawable drawable) { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); + struct glx_display *priv = __glXInitialize(dpy); CARD8 opcode; if ((dpy == NULL) || (drawable == 0)) { @@ -593,12 +593,12 @@ DestroyPbuffer(Display * dpy, GLXDrawable drawable) /** * Create a new pbuffer. */ -PUBLIC GLXPbufferSGIX +_X_EXPORT GLXPbufferSGIX glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list) { - return (GLXPbufferSGIX) CreatePbuffer(dpy, (__GLcontextModes *) config, + return (GLXPbufferSGIX) CreatePbuffer(dpy, (struct glx_config *) config, width, height, attrib_list, GL_FALSE); } @@ -608,7 +608,7 @@ glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config, /** * Create a new pbuffer. */ -PUBLIC GLXPbuffer +_X_EXPORT GLXPbuffer glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list) { int i, width, height; @@ -674,7 +674,7 @@ glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list) } } - return (GLXPbuffer) CreatePbuffer(dpy, (__GLcontextModes *) config, + return (GLXPbuffer) CreatePbuffer(dpy, (struct glx_config *) config, width, height, attrib_list, GL_TRUE); #endif } @@ -683,7 +683,7 @@ glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list) /** * Destroy an existing pbuffer. */ -PUBLIC void +_X_EXPORT void glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf) { #ifdef GLX_USE_APPLEGL @@ -699,7 +699,7 @@ glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf) /** * Query an attribute of a drawable. */ -PUBLIC void +_X_EXPORT void glXQueryDrawable(Display * dpy, GLXDrawable drawable, int attribute, unsigned int *value) { @@ -748,7 +748,7 @@ glXQueryDrawable(Display * dpy, GLXDrawable drawable, /** * Query an attribute of a pbuffer. */ -PUBLIC int +_X_EXPORT int glXQueryGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX drawable, int attribute, unsigned int *value) { @@ -759,7 +759,7 @@ glXQueryGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX drawable, /** * Select the event mask for a drawable. */ -PUBLIC void +_X_EXPORT void glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask) { #ifdef GLX_USE_APPLEGL @@ -792,7 +792,7 @@ glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask) /** * Get the selected event mask for a drawable. */ -PUBLIC void +_X_EXPORT void glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask) { #ifdef GLX_USE_APPLEGL @@ -829,27 +829,27 @@ glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask) } -PUBLIC GLXPixmap +_X_EXPORT GLXPixmap glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list) { WARN_ONCE_GLX_1_3(dpy, __func__); #ifdef GLX_USE_APPLEGL - const __GLcontextModes *modes = (const __GLcontextModes *) config; + const struct glx_config *modes = (const __GLcontextModes *) config; if (apple_glx_pixmap_create(dpy, modes->screen, pixmap, modes)) return None; return pixmap; #else - return CreateDrawable(dpy, (__GLcontextModes *) config, + return CreateDrawable(dpy, (struct glx_config *) config, (Drawable) pixmap, attrib_list, X_GLXCreatePixmap); #endif } -PUBLIC GLXWindow +_X_EXPORT GLXWindow glXCreateWindow(Display * dpy, GLXFBConfig config, Window win, const int *attrib_list) { @@ -878,13 +878,13 @@ glXCreateWindow(Display * dpy, GLXFBConfig config, Window win, return win; #else - return CreateDrawable(dpy, (__GLcontextModes *) config, + return CreateDrawable(dpy, (struct glx_config *) config, (Drawable) win, attrib_list, X_GLXCreateWindow); #endif } -PUBLIC void +_X_EXPORT void glXDestroyPixmap(Display * dpy, GLXPixmap pixmap) { WARN_ONCE_GLX_1_3(dpy, __func__); @@ -897,7 +897,7 @@ glXDestroyPixmap(Display * dpy, GLXPixmap pixmap) } -PUBLIC void +_X_EXPORT void glXDestroyWindow(Display * dpy, GLXWindow win) { WARN_ONCE_GLX_1_3(dpy, __func__); @@ -907,17 +907,17 @@ glXDestroyWindow(Display * dpy, GLXWindow win) } #ifndef GLX_USE_APPLEGL -PUBLIC +_X_EXPORT GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX, (Display * dpy, GLXPbufferSGIX pbuf), (dpy, pbuf), glXDestroyPbuffer) -PUBLIC +_X_EXPORT GLX_ALIAS_VOID(glXSelectEventSGIX, (Display * dpy, GLXDrawable drawable, unsigned long mask), (dpy, drawable, mask), glXSelectEvent) -PUBLIC +_X_EXPORT GLX_ALIAS_VOID(glXGetSelectedEventSGIX, (Display * dpy, GLXDrawable drawable, unsigned long *mask), (dpy, drawable, mask), diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index 8112c01e7cc..81c9a266696 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -39,6 +39,7 @@ #define _GLX_client_h_ #include <X11/Xproto.h> #include <X11/Xlibint.h> +#include <X11/Xfuncproto.h> #include <X11/extensions/extutil.h> #define GLX_GLXEXT_PROTOTYPES #include <GL/glx.h> @@ -49,10 +50,9 @@ #ifdef WIN32 #include <stdint.h> #endif -#include "GL/glxint.h" #include "GL/glxproto.h" -#include "GL/internal/glcore.h" #include "glapi/glapitable.h" +#include "glxconfig.h" #include "glxhash.h" #if defined( PTHREADS ) # include <pthread.h> @@ -60,42 +60,21 @@ #include "glxextensions.h" - -/* If we build the library with gcc's -fvisibility=hidden flag, we'll - * use the PUBLIC macro to mark functions that are to be exported. - * - * We also need to define a USED attribute, so the optimizer doesn't - * inline a static function that we later use in an alias. - ajax - */ -#if defined(__GNUC__) -# define PUBLIC __attribute__((visibility("default"))) -# define USED __attribute__((used)) -#else -# define PUBLIC -# define USED -#endif - - +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) #define GLX_MAJOR_VERSION 1 /* current version numbers */ #define GLX_MINOR_VERSION 4 #define __GLX_MAX_TEXTURE_UNITS 32 -typedef struct __GLXscreenConfigsRec __GLXscreenConfigs; -typedef struct __GLXcontextRec __GLXcontext; -typedef struct __GLXdrawableRec __GLXdrawable; -typedef struct __GLXdisplayPrivateRec __GLXdisplayPrivate; -typedef struct _glapi_table __GLapi; +struct glx_display; +struct glx_context; /************************************************************************/ #ifdef GLX_DIRECT_RENDERING -#define containerOf(ptr, type, member) \ - (type *)( (char *)ptr - offsetof(type,member) ) - -extern void DRI_glXUseXFont(GLXContext CC, +extern void DRI_glXUseXFont(struct glx_context *ctx, Font font, int first, int count, int listbase); #endif @@ -109,7 +88,6 @@ extern void DRI_glXUseXFont(GLXContext CC, typedef struct __GLXDRIdisplayRec __GLXDRIdisplay; typedef struct __GLXDRIscreenRec __GLXDRIscreen; typedef struct __GLXDRIdrawableRec __GLXDRIdrawable; -typedef struct __GLXDRIcontextRec __GLXDRIcontext; #include "glxextensions.h" @@ -120,27 +98,28 @@ struct __GLXDRIdisplayRec */ void (*destroyDisplay) (__GLXDRIdisplay * display); - __GLXscreenConfigs *(*createScreen)(int screen, __GLXdisplayPrivate * priv); + struct glx_screen *(*createScreen)(int screen, struct glx_display * priv); }; struct __GLXDRIscreenRec { - void (*destroyScreen)(__GLXscreenConfigs *psc); + void (*destroyScreen)(struct glx_screen *psc); - __GLXcontext *(*createContext)(__GLXscreenConfigs *psc, - const __GLcontextModes *mode, - GLXContext shareList, int renderType); + struct glx_context *(*createContext)(struct glx_screen *psc, + struct glx_config *config, + struct glx_context *shareList, + int renderType); - __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc, + __GLXDRIdrawable *(*createDrawable)(struct glx_screen *psc, XID drawable, GLXDrawable glxDrawable, - const __GLcontextModes *modes); + struct glx_config *config); int64_t (*swapBuffers)(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, int64_t remainder); void (*copySubBuffer)(__GLXDRIdrawable *pdraw, int x, int y, int width, int height); - int (*getDrawableMSC)(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw, + int (*getDrawableMSC)(struct glx_screen *psc, __GLXDRIdrawable *pdraw, int64_t *ust, int64_t *msc, int64_t *sbc); int (*waitForMSC)(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, @@ -151,21 +130,13 @@ struct __GLXDRIscreenRec { int (*getSwapInterval)(__GLXDRIdrawable *pdraw); }; -struct __GLXDRIcontextRec -{ - void (*destroyContext) (__GLXcontext *context); - Bool(*bindContext) (__GLXcontext *context, __GLXDRIdrawable *pdraw, - __GLXDRIdrawable *pread); - void (*unbindContext) (__GLXcontext *context); -}; - struct __GLXDRIdrawableRec { void (*destroyDrawable) (__GLXDRIdrawable * drawable); XID xDrawable; XID drawable; - __GLXscreenConfigs *psc; + struct glx_screen *psc; GLenum textureTarget; GLenum textureFormat; /* EXT_texture_from_pixmap support */ unsigned long eventMask; @@ -241,9 +212,13 @@ typedef struct __GLXattributeMachineRec } __GLXattributeMachine; struct glx_context_vtable { - void (*wait_gl)(__GLXcontext *ctx); - void (*wait_x)(__GLXcontext *ctx); - void (*use_x_font)(__GLXcontext *ctx, + void (*destroy)(struct glx_context *ctx); + int (*bind)(struct glx_context *context, struct glx_context *old, + GLXDrawable draw, GLXDrawable read); + void (*unbind)(struct glx_context *context, struct glx_context *new); + void (*wait_gl)(struct glx_context *ctx); + void (*wait_x)(struct glx_context *ctx); + void (*use_x_font)(struct glx_context *ctx, Font font, int first, int count, int listBase); void (*bind_tex_image)(Display * dpy, GLXDrawable drawable, @@ -252,11 +227,14 @@ struct glx_context_vtable { }; +extern void +glx_send_destroy_context(Display *dpy, XID xid); + /** * GLX state that needs to be kept on the client. One of these records * exist for each context that has been made current by this client. */ -struct __GLXcontextRec +struct glx_context { /** * \name Drawing command buffer. @@ -299,7 +277,7 @@ struct __GLXcontextRec * Screen number. */ GLint screen; - __GLXscreenConfigs *psc; + struct glx_screen *psc; /** * \c GL_TRUE if the context was created with ImportContext, which @@ -342,7 +320,7 @@ struct __GLXcontextRec * Fill newImage with the unpacked form of \c oldImage getting it * ready for transport to the server. */ - void (*fillImage) (__GLXcontext *, GLint, GLint, GLint, GLint, GLenum, + void (*fillImage) (struct glx_context *, GLint, GLint, GLint, GLint, GLenum, GLenum, const GLvoid *, GLubyte *, GLubyte *); /** @@ -401,18 +379,9 @@ struct __GLXcontextRec GLint majorOpcode; /** - * Pointer to the mode used to create this context. + * Pointer to the config used to create this context. */ - const __GLcontextModes *mode; - -#ifdef GLX_DIRECT_RENDERING -#ifdef GLX_USE_APPLEGL - void *driContext; - Bool do_destroy; -#else - __GLXDRIcontext *driContext; -#endif -#endif + struct glx_config *config; /** * The current read-drawable for this context. Will be None if this @@ -459,15 +428,15 @@ struct __GLXcontextRec }; extern Bool -glx_context_init(__GLXcontext *gc, - __GLXscreenConfigs *psc, const __GLcontextModes *fbconfig); +glx_context_init(struct glx_context *gc, + struct glx_screen *psc, struct glx_config *fbconfig); #define __glXSetError(gc,code) \ if (!(gc)->error) { \ (gc)->error = code; \ } -extern void __glFreeAttributeState(__GLXcontext *); +extern void __glFreeAttributeState(struct glx_context *); /************************************************************************/ @@ -501,8 +470,17 @@ extern void __glFreeAttributeState(__GLXcontext *); * One of these records exists per screen of the display. It contains * a pointer to the config data for that screen (if the screen supports GL). */ -struct __GLXscreenConfigsRec +struct glx_screen_vtable { + struct glx_context *(*create_context)(struct glx_screen *psc, + struct glx_config *config, + struct glx_context *shareList, + int renderType); +}; + +struct glx_screen { + const struct glx_screen_vtable *vtable; + /** * GLX extension string reported by the X-server. */ @@ -514,7 +492,7 @@ struct __GLXscreenConfigsRec */ char *effectiveGLXexts; - __GLXdisplayPrivate *display; + struct glx_display *display; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) /** @@ -529,13 +507,13 @@ struct __GLXscreenConfigsRec /** * Linked list of glx visuals and fbconfigs for this screen. */ - __GLcontextModes *visuals, *configs; + struct glx_config *visuals, *configs; /** * Per-screen dynamic GLX extension tracking. The \c direct_support * field only contains enough bits for 64 extensions. Should libGL * ever need to track more than 64 GLX extensions, we can safely grow - * this field. The \c __GLXscreenConfigs structure is not used outside + * this field. The \c struct glx_screen structure is not used outside * libGL. */ /*@{ */ @@ -549,11 +527,11 @@ struct __GLXscreenConfigsRec * Per display private data. One of these records exists for each display * that is using the OpenGL (GLX) extension. */ -struct __GLXdisplayPrivateRec +struct glx_display { /* The extension protocol codes */ XExtCodes *codes; - struct __GLXdisplayPrivateRec *next; + struct glx_display *next; /** * Back pointer to the display @@ -591,7 +569,7 @@ struct __GLXdisplayPrivateRec * Also, per screen data which now includes the server \c GLX_EXTENSION * string. */ - __GLXscreenConfigs **screenConfigs; + struct glx_screen **screens; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) __glxHashTable *drawHash; @@ -606,25 +584,25 @@ struct __GLXdisplayPrivateRec }; extern int -glx_screen_init(__GLXscreenConfigs *psc, - int screen, __GLXdisplayPrivate * priv); +glx_screen_init(struct glx_screen *psc, + int screen, struct glx_display * priv); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) extern __GLXDRIdrawable * dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id); #endif -extern GLubyte *__glXFlushRenderBuffer(__GLXcontext *, GLubyte *); +extern GLubyte *__glXFlushRenderBuffer(struct glx_context *, GLubyte *); -extern void __glXSendLargeChunk(__GLXcontext * gc, GLint requestNumber, +extern void __glXSendLargeChunk(struct glx_context * gc, GLint requestNumber, GLint totalRequests, const GLvoid * data, GLint dataLen); -extern void __glXSendLargeCommand(__GLXcontext *, const GLvoid *, GLint, +extern void __glXSendLargeCommand(struct glx_context *, const GLvoid *, GLint, const GLvoid *, GLint); /* Initialize the GLX extension for dpy */ -extern __GLXdisplayPrivate *__glXInitialize(Display *); +extern struct glx_display *__glXInitialize(Display *); extern void __glXPreferEGL(int state); @@ -635,7 +613,7 @@ extern int __glXDebug; /* This is per-thread storage in an MT environment */ #if defined( PTHREADS ) -extern void __glXSetCurrentContext(__GLXcontext * c); +extern void __glXSetCurrentContext(struct glx_context * c); # if defined( GLX_USE_TLS ) @@ -646,13 +624,13 @@ extern __thread void *__glX_tls_Context # else -extern __GLXcontext *__glXGetCurrentContext(void); +extern struct glx_context *__glXGetCurrentContext(void); # endif /* defined( GLX_USE_TLS ) */ #else -extern __GLXcontext *__glXcurrentContext; +extern struct glx_context *__glXcurrentContext; #define __glXGetCurrentContext() __glXcurrentContext #define __glXSetCurrentContext(gc) __glXcurrentContext = gc @@ -660,8 +638,6 @@ extern __GLXcontext *__glXcurrentContext; extern void __glXSetCurrentContextNull(void); -extern void __glXFreeContext(__GLXcontext *); - /* ** Global lock for all threads in this address space using the GLX @@ -690,7 +666,7 @@ extern CARD8 __glXSetupForCommand(Display * dpy); extern const GLuint __glXDefaultPixelStore[9]; /* Send an image to the server using RenderLarge. */ -extern void __glXSendLargeImage(__GLXcontext * gc, GLint compsize, GLint dim, +extern void __glXSendLargeImage(struct glx_context * gc, GLint compsize, GLint dim, GLint width, GLint height, GLint depth, GLenum format, GLenum type, const GLvoid * src, GLubyte * pc, @@ -714,7 +690,7 @@ extern GLint __glBytesPerElement(GLenum type); ** updated to contain the modes needed by the server to decode the ** sent data. */ -extern void __glFillImage(__GLXcontext *, GLint, GLint, GLint, GLint, GLenum, +extern void __glFillImage(struct glx_context *, GLint, GLint, GLint, GLint, GLenum, GLenum, const GLvoid *, GLubyte *, GLubyte *); /* Copy map data with a stride into a packed buffer */ @@ -729,15 +705,15 @@ extern void __glFillMap2d(GLint, GLint, GLint, GLint, GLint, ** Empty an image out of the reply buffer into the clients memory applying ** the pack modes to pack back into the clients requested format. */ -extern void __glEmptyImage(__GLXcontext *, GLint, GLint, GLint, GLint, GLenum, +extern void __glEmptyImage(struct glx_context *, GLint, GLint, GLint, GLint, GLenum, GLenum, const GLubyte *, GLvoid *); /* ** Allocate and Initialize Vertex Array client state, and free. */ -extern void __glXInitVertexArrayState(__GLXcontext *); -extern void __glXFreeVertexArrayState(__GLXcontext *); +extern void __glXInitVertexArrayState(struct glx_context *); +extern void __glXFreeVertexArrayState(struct glx_context *); /* ** Inform the Server of the major and minor numbers and of the client @@ -758,7 +734,7 @@ extern void _XSend(Display *, const void *, long); #endif -extern void __glXInitializeVisualConfigFromTags(__GLcontextModes * config, +extern void __glXInitializeVisualConfigFromTags(struct glx_config * config, int count, const INT32 * bp, Bool tagged_only, Bool fbconfig_style_tags); @@ -790,9 +766,21 @@ __glxGetMscRate(__GLXDRIdrawable *glxDraw, * glx_info->codes->first_event */ XExtDisplayInfo *__glXFindDisplay (Display *dpy); +extern void +GarbageCollectDRIDrawables(struct glx_screen *psc); + extern __GLXDRIdrawable * GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable); #endif +extern struct glx_context dummyContext; + +extern struct glx_screen * +indirect_create_screen(int screen, struct glx_display * priv); +extern struct glx_context * +indirect_create_context(struct glx_screen *psc, + struct glx_config *mode, + struct glx_context *shareList, int renderType); + #endif /* !__GLX_client_h__ */ diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index 8ee9a999e4a..d4aa8b58668 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -36,22 +36,18 @@ #include "glxclient.h" #include "glapi.h" #include "glxextensions.h" -#include "glcontextmodes.h" #ifdef GLX_DIRECT_RENDERING #ifdef GLX_USE_APPLEGL #include "apple_glx_context.h" #include "apple_glx.h" #include "glx_error.h" -#define GC_IS_DIRECT(gc) ((gc)->isDirect) #else #include <sys/time.h> #include <X11/extensions/xf86vmode.h> #include "xf86dri.h" -#define GC_IS_DIRECT(gc) ((gc)->driContext != NULL) #endif #else -#define GC_IS_DIRECT(gc) (0) #endif #if defined(USE_XCB) @@ -62,7 +58,6 @@ static const char __glXGLXClientVendorName[] = "Mesa Project and SGI"; static const char __glXGLXClientVersion[] = "1.4"; -static const struct glx_context_vtable indirect_context_vtable; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) @@ -85,12 +80,12 @@ windowExistsErrorHandler(Display * dpy, XErrorEvent * xerr) * \param dpy Display to destroy drawables for * \param screen Screen number to destroy drawables for */ -static void -GarbageCollectDRIDrawables(__GLXscreenConfigs * sc) +_X_HIDDEN void +GarbageCollectDRIDrawables(struct glx_screen * sc) { XID draw; __GLXDRIdrawable *pdraw; - __GLXdisplayPrivate *priv = sc->display; + struct glx_display *priv = sc->display; XWindowAttributes xwa; int (*oldXErrorHandler) (Display *, XErrorEvent *); @@ -128,7 +123,7 @@ GarbageCollectDRIDrawables(__GLXscreenConfigs * sc) _X_HIDDEN __GLXDRIdrawable * GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable) { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); + struct glx_display *priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw; if (priv == NULL) @@ -157,20 +152,20 @@ GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable) * number range for \c dpy? */ -static __GLXscreenConfigs * +static struct glx_screen * GetGLXScreenConfigs(Display * dpy, int scrn) { - __GLXdisplayPrivate *const priv = __glXInitialize(dpy); + struct glx_display *const priv = __glXInitialize(dpy); return (priv - && priv->screenConfigs != - NULL) ? priv->screenConfigs[scrn] : NULL; + && priv->screens != + NULL) ? priv->screens[scrn] : NULL; } static int -GetGLXPrivScreenConfig(Display * dpy, int scrn, __GLXdisplayPrivate ** ppriv, - __GLXscreenConfigs ** ppsc) +GetGLXPrivScreenConfig(Display * dpy, int scrn, struct glx_display ** ppriv, + struct glx_screen ** ppsc) { /* Initialize the extension, if needed . This has the added value * of initializing/allocating the display private @@ -191,7 +186,7 @@ GetGLXPrivScreenConfig(Display * dpy, int scrn, __GLXdisplayPrivate ** ppriv, } /* Check to see if the GL is supported on this screen */ - *ppsc = (*ppriv)->screenConfigs[scrn]; + *ppsc = (*ppriv)->screens[scrn]; if ((*ppsc)->configs == NULL) { /* No support for GL on this screen regardless of visual */ return GLX_BAD_VISUAL; @@ -208,148 +203,34 @@ GetGLXPrivScreenConfig(Display * dpy, int scrn, __GLXdisplayPrivate ** ppriv, * \param config Application supplied \c GLXFBConfig. * * \returns If the \c GLXFBConfig is valid, the a pointer to the matching - * \c __GLcontextModes structure is returned. Otherwise, \c NULL + * \c struct glx_config structure is returned. Otherwise, \c NULL * is returned. */ -static __GLcontextModes * -ValidateGLXFBConfig(Display * dpy, GLXFBConfig config) +static struct glx_config * +ValidateGLXFBConfig(Display * dpy, GLXFBConfig fbconfig) { - __GLXdisplayPrivate *const priv = __glXInitialize(dpy); - const unsigned num_screens = ScreenCount(dpy); + struct glx_display *const priv = __glXInitialize(dpy); + int num_screens = ScreenCount(dpy); unsigned i; - const __GLcontextModes *modes; - + struct glx_config *config; if (priv != NULL) { for (i = 0; i < num_screens; i++) { - for (modes = priv->screenConfigs[i]->configs; modes != NULL; - modes = modes->next) { - if (modes == (__GLcontextModes *) config) { - return (__GLcontextModes *) config; - } - } + for (config = priv->screens[i]->configs; config != NULL; + config = config->next) { + if (config == (struct glx_config *) fbconfig) { + return config; + } + } } } return NULL; } - -/** - * \todo It should be possible to move the allocate of \c client_state_private - * later in the function for direct-rendering contexts. Direct-rendering - * contexts don't need to track client state, so they don't need that memory - * at all. - * - * \todo Eliminate \c __glXInitVertexArrayState. Replace it with a new - * function called \c __glXAllocateClientState that allocates the memory and - * does all the initialization (including the pixel pack / unpack). - */ -static GLXContext -AllocateGLXContext(Display * dpy) -{ - GLXContext gc; - int bufSize; - CARD8 opcode; - __GLXattribute *state; - - if (!dpy) - return NULL; - - opcode = __glXSetupForCommand(dpy); - if (!opcode) { - return NULL; - } - - /* Allocate our context record */ - gc = (GLXContext) Xmalloc(sizeof(struct __GLXcontextRec)); - if (!gc) { - /* Out of memory */ - return NULL; - } - memset(gc, 0, sizeof(struct __GLXcontextRec)); - - gc->vtable = &indirect_context_vtable; - state = Xmalloc(sizeof(struct __GLXattributeRec)); - if (state == NULL) { - /* Out of memory */ - Xfree(gc); - return NULL; - } - gc->client_state_private = state; - memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec)); - state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL); - - /* - ** Create a temporary buffer to hold GLX rendering commands. The size - ** of the buffer is selected so that the maximum number of GLX rendering - ** commands can fit in a single X packet and still have room in the X - ** packet for the GLXRenderReq header. - */ - - bufSize = (XMaxRequestSize(dpy) * 4) - sz_xGLXRenderReq; - gc->buf = (GLubyte *) Xmalloc(bufSize); - if (!gc->buf) { - Xfree(gc->client_state_private); - Xfree(gc); - return NULL; - } - gc->bufSize = bufSize; - - /* Fill in the new context */ - gc->renderMode = GL_RENDER; - - state->storePack.alignment = 4; - state->storeUnpack.alignment = 4; - - gc->attributes.stackPointer = &gc->attributes.stack[0]; - - /* - ** PERFORMANCE NOTE: A mode dependent fill image can speed things up. - ** Other code uses the fastImageUnpack bit, but it is never set - ** to GL_TRUE. - */ - gc->fastImageUnpack = GL_FALSE; - gc->fillImage = __glFillImage; - gc->pc = gc->buf; - gc->bufEnd = gc->buf + bufSize; - gc->isDirect = GL_FALSE; - if (__glXDebug) { - /* - ** Set limit register so that there will be one command per packet - */ - gc->limit = gc->buf; - } - else { - gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE; - } - gc->majorOpcode = opcode; - - /* - ** Constrain the maximum drawing command size allowed to be - ** transfered using the X_GLXRender protocol request. First - ** constrain by a software limit, then constrain by the protocl - ** limit. - */ - if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) { - bufSize = __GLX_RENDER_CMD_SIZE_LIMIT; - } - if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) { - bufSize = __GLX_MAX_RENDER_CMD_SIZE; - } - gc->maxSmallRenderCommandSize = bufSize; - -#ifdef GLX_USE_APPLEGL - gc->driContext = NULL; - gc->do_destroy = False; -#endif - - return gc; -} - _X_HIDDEN Bool -glx_context_init(__GLXcontext *gc, - __GLXscreenConfigs *psc, const __GLcontextModes *fbconfig) +glx_context_init(struct glx_context *gc, + struct glx_screen *psc, struct glx_config *config) { gc->majorOpcode = __glXSetupForCommand(psc->display->dpy); if (!gc->majorOpcode) @@ -357,8 +238,9 @@ glx_context_init(__GLXcontext *gc, gc->screen = psc->scr; gc->psc = psc; - gc->mode = fbconfig; + gc->config = config; gc->isDirect = GL_TRUE; + gc->currentContextTag = -1; return GL_TRUE; } @@ -375,34 +257,25 @@ glx_context_init(__GLXcontext *gc, static GLXContext CreateContext(Display * dpy, int generic_id, - const __GLcontextModes * const fbconfig, - GLXContext shareList, + struct glx_config *config, + GLXContext shareList_user, Bool allowDirect, unsigned code, int renderType, int screen) { - GLXContext gc = NULL; - __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen); -#if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_APPLEGL) - int errorcode; - bool x11error; -#endif - + struct glx_context *gc = NULL; + struct glx_screen *const psc = GetGLXScreenConfigs(dpy, screen); + struct glx_context *shareList = (struct glx_context *) shareList_user; if (dpy == NULL) return NULL; if (generic_id == None) return NULL; -#ifndef GLX_USE_APPLEGL /* TODO: darwin indirect */ -#ifdef GLX_DIRECT_RENDERING - if (allowDirect && psc->driScreen) { - gc = psc->driScreen->createContext(psc, fbconfig, - shareList, renderType); - } -#endif - + gc = NULL; + if (allowDirect && psc->vtable->create_context) + gc = psc->vtable->create_context(psc, config, shareList, renderType); if (!gc) - gc = AllocateGLXContext(dpy); + gc = indirect_create_context(psc, config, shareList, renderType); if (!gc) return NULL; @@ -419,7 +292,7 @@ CreateContext(Display * dpy, int generic_id, req->visual = generic_id; req->screen = screen; req->shareList = shareList ? shareList->xid : None; - req->isDirect = GC_IS_DIRECT(gc); + req->isDirect = gc->isDirect; break; } @@ -435,7 +308,7 @@ CreateContext(Display * dpy, int generic_id, req->screen = screen; req->renderType = renderType; req->shareList = shareList ? shareList->xid : None; - req->isDirect = GC_IS_DIRECT(gc); + req->isDirect = gc->isDirect; break; } @@ -456,7 +329,7 @@ CreateContext(Display * dpy, int generic_id, req->screen = screen; req->renderType = renderType; req->shareList = shareList ? shareList->xid : None; - req->isDirect = GC_IS_DIRECT(gc); + req->isDirect = gc->isDirect; break; } @@ -469,41 +342,25 @@ CreateContext(Display * dpy, int generic_id, UnlockDisplay(dpy); SyncHandle(); -#endif gc->imported = GL_FALSE; gc->renderType = renderType; - /* TODO: darwin: Integrate with above to do indirect */ -#ifdef GLX_USE_APPLEGL - if(apple_glx_create_context(&gc->driContext, dpy, screen, fbconfig, - shareList ? shareList->driContext : NULL, - &errorcode, &x11error)) { - __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error); - __glXFreeContext(gc); - return NULL; - } - - gc->currentContextTag = -1; - gc->mode = fbconfig; - gc->isDirect = allowDirect; -#endif - - return gc; + return (GLXContext) gc; } -PUBLIC GLXContext +_X_EXPORT GLXContext glXCreateContext(Display * dpy, XVisualInfo * vis, GLXContext shareList, Bool allowDirect) { - const __GLcontextModes *mode = NULL; + struct glx_config *config = NULL; int renderType = 0; #if defined(GLX_DIRECT_RENDERING) || defined(GLX_USE_APPLEGL) - __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, vis->screen); + struct glx_screen *const psc = GetGLXScreenConfigs(dpy, vis->screen); - mode = _gl_context_modes_find_visual(psc->visuals, vis->visualid); - if (mode == NULL) { + config = glx_config_find_visual(psc->visuals, vis->visualid); + if (config == NULL) { xError error; error.errorCode = BadValue; @@ -516,115 +373,59 @@ glXCreateContext(Display * dpy, XVisualInfo * vis, return None; } - renderType = mode->rgbMode ? GLX_RGBA_TYPE : GLX_COLOR_INDEX_TYPE; + renderType = config->rgbMode ? GLX_RGBA_TYPE : GLX_COLOR_INDEX_TYPE; #endif - return CreateContext(dpy, vis->visualid, mode, shareList, allowDirect, + return CreateContext(dpy, vis->visualid, config, shareList, allowDirect, X_GLXCreateContext, renderType, vis->screen); } _X_HIDDEN void -__glXFreeContext(__GLXcontext * gc) +glx_send_destroy_context(Display *dpy, XID xid) { - if (gc->vendor) - XFree((char *) gc->vendor); - if (gc->renderer) - XFree((char *) gc->renderer); - if (gc->version) - XFree((char *) gc->version); - if (gc->extensions) - XFree((char *) gc->extensions); - __glFreeAttributeState(gc); - XFree((char *) gc->buf); - Xfree((char *) gc->client_state_private); - XFree((char *) gc); + CARD8 opcode = __glXSetupForCommand(dpy); + xGLXDestroyContextReq *req; + LockDisplay(dpy); + GetReq(GLXDestroyContext, req); + req->reqType = opcode; + req->glxCode = X_GLXDestroyContext; + req->context = xid; + UnlockDisplay(dpy); + SyncHandle(); } /* ** Destroy the named context */ static void -DestroyContext(Display * dpy, GLXContext gc) +DestroyContext(Display * dpy, GLXContext ctx) { -#ifndef GLX_USE_APPLEGL /* TODO: darwin: indirect */ - xGLXDestroyContextReq *req; - GLXContextID xid; - CARD8 opcode; - GLboolean imported; + struct glx_context *gc = (struct glx_context *) ctx; - opcode = __glXSetupForCommand(dpy); - if (!opcode || !gc) { + if (!gc) return; - } __glXLock(); - xid = gc->xid; - imported = gc->imported; - gc->xid = None; - if (gc->currentDpy) { /* This context is bound to some thread. According to the man page, * we should not actually delete the context until it's unbound. * Note that we set gc->xid = None above. In MakeContextCurrent() * we check for that and delete the context there. */ + if (!gc->imported) + glx_send_destroy_context(dpy, gc->xid); + gc->xid = None; __glXUnlock(); return; } + __glXUnlock(); -#if defined(GLX_DIRECT_RENDERING) - /* Destroy the direct rendering context */ - if (gc->driContext) { - GarbageCollectDRIDrawables(gc->psc); - if (gc->extensions) - XFree((char *) gc->extensions); - (*gc->driContext->destroyContext) (gc); - } - else -#endif - { - __glXFreeVertexArrayState(gc); - __glXFreeContext(gc); - } - - if (!imported) { - /* - ** This dpy also created the server side part of the context. - ** Send the glXDestroyContext request. - */ - LockDisplay(dpy); - GetReq(GLXDestroyContext, req); - req->reqType = opcode; - req->glxCode = X_GLXDestroyContext; - req->context = xid; - UnlockDisplay(dpy); - SyncHandle(); - } - -#else - - __glXLock(); - if (gc->currentDpy) { - /* - * Set the Bool that indicates that we should destroy this GLX context - * when the context is no longer current. - */ - gc->do_destroy = True; - /* Have to free later cuz it's in use now */ - __glXUnlock(); - } - else { - /* Destroy the handle if not current to anybody */ - __glXUnlock(); - if(gc->driContext) - apple_glx_destroy_context(&gc->driContext, dpy); - __glXFreeContext(gc); - } -#endif + if (gc->vtable->destroy) + gc->vtable->destroy(gc); } -PUBLIC void +_X_EXPORT void glXDestroyContext(Display * dpy, GLXContext gc) { DestroyContext(dpy, gc); @@ -633,10 +434,10 @@ glXDestroyContext(Display * dpy, GLXContext gc) /* ** Return the major and minor version #s for the GLX extension */ -PUBLIC Bool +_X_EXPORT Bool glXQueryVersion(Display * dpy, int *major, int *minor) { - __GLXdisplayPrivate *priv; + struct glx_display *priv; /* Init the extension. This fetches the major and minor version. */ priv = __glXInitialize(dpy); @@ -653,7 +454,7 @@ glXQueryVersion(Display * dpy, int *major, int *minor) /* ** Query the existance of the GLX extension */ -PUBLIC Bool +_X_EXPORT Bool glXQueryExtension(Display * dpy, int *errorBase, int *eventBase) { int major_op, erb, evb; @@ -669,121 +470,36 @@ glXQueryExtension(Display * dpy, int *errorBase, int *eventBase) return rv; } -static void -indirect_wait_gl(__GLXcontext *gc) -{ - xGLXWaitGLReq *req; - Display *dpy = gc->currentDpy; - - /* Flush any pending commands out */ - __glXFlushRenderBuffer(gc, gc->pc); - - /* Send the glXWaitGL request */ - LockDisplay(dpy); - GetReq(GLXWaitGL, req); - req->reqType = gc->majorOpcode; - req->glxCode = X_GLXWaitGL; - req->contextTag = gc->currentContextTag; - UnlockDisplay(dpy); - SyncHandle(); -} - /* ** Put a barrier in the token stream that forces the GL to finish its ** work before X can proceed. */ -PUBLIC void +_X_EXPORT void glXWaitGL(void) { - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); - if (gc && gc->vtable->use_x_font) + if (gc && gc->vtable->wait_gl) gc->vtable->wait_gl(gc); } -static void -indirect_wait_x(__GLXcontext *gc) -{ - xGLXWaitXReq *req; - Display *dpy = gc->currentDpy; - - /* Flush any pending commands out */ - __glXFlushRenderBuffer(gc, gc->pc); - - LockDisplay(dpy); - GetReq(GLXWaitX, req); - req->reqType = gc->majorOpcode; - req->glxCode = X_GLXWaitX; - req->contextTag = gc->currentContextTag; - UnlockDisplay(dpy); - SyncHandle(); -} - /* ** Put a barrier in the token stream that forces X to finish its ** work before GL can proceed. */ -PUBLIC void +_X_EXPORT void glXWaitX(void) { - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); - if (gc && gc->vtable->use_x_font) + if (gc && gc->vtable->wait_x) gc->vtable->wait_x(gc); } -static void -indirect_use_x_font(__GLXcontext *gc, - Font font, int first, int count, int listBase) -{ - xGLXUseXFontReq *req; - Display *dpy = gc->currentDpy; - - /* Flush any pending commands out */ - __glXFlushRenderBuffer(gc, gc->pc); - - /* Send the glXUseFont request */ - LockDisplay(dpy); - GetReq(GLXUseXFont, req); - req->reqType = gc->majorOpcode; - req->glxCode = X_GLXUseXFont; - req->contextTag = gc->currentContextTag; - req->font = font; - req->first = first; - req->count = count; - req->listBase = listBase; - UnlockDisplay(dpy); - SyncHandle(); -} - -#ifdef GLX_USE_APPLEGL - -static void -applegl_wait_gl(__GLXcontext *gc) -{ - glFinish(); -} - -static void -applegl_wait_x(__GLXcontext *gc) -{ - apple_glx_waitx(gc->dpy, gc->driContext); -} - -static const struct glx_context_vtable applegl_context_vtable = { - applegl_wait_gl, - applegl_wait_x, - DRI_glXUseXFont, - NULL, /* bind_tex_image, */ - NULL, /* release_tex_image, */ -}; - -#endif - -PUBLIC void +_X_EXPORT void glXUseXFont(Font font, int first, int count, int listBase) { - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); if (gc && gc->vtable->use_x_font) gc->vtable->use_x_font(gc, font, first, count, listBase); @@ -795,12 +511,14 @@ glXUseXFont(Font font, int first, int count, int listBase) ** Copy the source context to the destination context using the ** attribute "mask". */ -PUBLIC void -glXCopyContext(Display * dpy, GLXContext source, - GLXContext dest, unsigned long mask) +_X_EXPORT void +glXCopyContext(Display * dpy, GLXContext source_user, + GLXContext dest_user, unsigned long mask) { + struct glx_context *source = (struct glx_context *) source_user; + struct glx_context *dest = (struct glx_context *) dest_user; #ifdef GLX_USE_APPLEGL - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); int errorcode; bool x11error; @@ -811,7 +529,7 @@ glXCopyContext(Display * dpy, GLXContext source, #else xGLXCopyContextReq *req; - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); GLXContextTag tag; CARD8 opcode; @@ -821,7 +539,7 @@ glXCopyContext(Display * dpy, GLXContext source, } #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { /* NOT_DONE: This does not work yet */ } #endif @@ -906,13 +624,15 @@ __glXIsDirect(Display * dpy, GLXContextID contextID) * \c GLX_DIRECT_RENDERING is not defined? Do we really need to bother with * the GLX protocol here at all? */ -PUBLIC Bool -glXIsDirect(Display * dpy, GLXContext gc) +_X_EXPORT Bool +glXIsDirect(Display * dpy, GLXContext gc_user) { + struct glx_context *gc = (struct glx_context *) gc_user; + if (!gc) { return GL_FALSE; } - else if (GC_IS_DIRECT(gc)) { + else if (gc->isDirect) { return GL_TRUE; } #ifdef GLX_USE_APPLEGL /* TODO: indirect on darwin */ @@ -922,17 +642,17 @@ glXIsDirect(Display * dpy, GLXContext gc) #endif } -PUBLIC GLXPixmap +_X_EXPORT GLXPixmap glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) { #ifdef GLX_USE_APPLEGL int screen = vis->screen; - __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen); - const __GLcontextModes *modes; + struct glx_screen *const psc = GetGLXScreenConfigs(dpy, screen); + const struct glx_config *config; - modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid); + config = _gl_context_modes_find_visual(psc->visuals, vis->visualid); - if(apple_glx_pixmap_create(dpy, vis->screen, pixmap, modes)) + if(apple_glx_pixmap_create(dpy, vis->screen, pixmap, config)) return None; return pixmap; @@ -963,16 +683,16 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) /* FIXME: Maybe delay __DRIdrawable creation until the drawable * is actually bound to a context... */ - __GLXdisplayPrivate *const priv = __glXInitialize(dpy); + struct glx_display *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw; - __GLXscreenConfigs *psc; - __GLcontextModes *modes; + struct glx_screen *psc; + struct glx_config *config; - psc = priv->screenConfigs[vis->screen]; + psc = priv->screens[vis->screen]; if (psc->driScreen == NULL) break; - modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid); - pdraw = psc->driScreen->createDrawable(psc, pixmap, req->glxpixmap, modes); + config = glx_config_find_visual(psc->visuals, vis->visualid); + pdraw = psc->driScreen->createDrawable(psc, pixmap, req->glxpixmap, config); if (pdraw == NULL) { fprintf(stderr, "failed to create pixmap\n"); break; @@ -992,7 +712,7 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap) /* ** Destroy the named pixmap */ -PUBLIC void +_X_EXPORT void glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap) { #ifdef GLX_USE_APPLEGL @@ -1018,7 +738,7 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap) #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) { - __GLXdisplayPrivate *const priv = __glXInitialize(dpy); + struct glx_display *const priv = __glXInitialize(dpy); __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap); if (pdraw != NULL) { @@ -1030,7 +750,7 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap) #endif /* GLX_USE_APPLEGL */ } -PUBLIC void +_X_EXPORT void glXSwapBuffers(Display * dpy, GLXDrawable drawable) { #ifdef GLX_USE_APPLEGL @@ -1041,7 +761,7 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable) __glXSendError(dpy, GLXBadCurrentWindow, 0, X_GLXSwapBuffers, false); } #else - GLXContext gc; + struct glx_context *gc; GLXContextTag tag; CARD8 opcode; #ifdef USE_XCB @@ -1103,22 +823,22 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable) ** Return configuration information for the given display, screen and ** visual combination. */ -PUBLIC int +_X_EXPORT int glXGetConfig(Display * dpy, XVisualInfo * vis, int attribute, int *value_return) { - __GLXdisplayPrivate *priv; - __GLXscreenConfigs *psc; - __GLcontextModes *modes; + struct glx_display *priv; + struct glx_screen *psc; + struct glx_config *config; int status; status = GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc); if (status == Success) { - modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid); + config = glx_config_find_visual(psc->visuals, vis->visualid); /* Lookup attribute after first finding a match on the visual */ - if (modes != NULL) { - return _gl_get_context_mode_data(modes, attribute, value_return); + if (config != NULL) { + return glx_config_get(config, attribute, value_return); } status = GLX_BAD_VISUAL; @@ -1139,10 +859,10 @@ glXGetConfig(Display * dpy, XVisualInfo * vis, int attribute, /************************************************************************/ static void -init_fbconfig_for_chooser(__GLcontextModes * config, +init_fbconfig_for_chooser(struct glx_config * config, GLboolean fbconfig_style_tags) { - memset(config, 0, sizeof(__GLcontextModes)); + memset(config, 0, sizeof(struct glx_config)); config->visualID = (XID) GLX_DONT_CARE; config->visualType = GLX_DONT_CARE; @@ -1208,8 +928,8 @@ init_fbconfig_for_chooser(__GLcontextModes * config, * \param b Server specified config to test against \c a. */ static Bool -fbconfigs_compatible(const __GLcontextModes * const a, - const __GLcontextModes * const b) +fbconfigs_compatible(const struct glx_config * const a, + const struct glx_config * const b) { MATCH_DONT_CARE(doubleBufferMode); MATCH_DONT_CARE(visualType); @@ -1328,8 +1048,7 @@ fbconfigs_compatible(const __GLcontextModes * const a, * \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX */ static int -fbconfig_compare(const __GLcontextModes * const *const a, - const __GLcontextModes * const *const b) +fbconfig_compare(struct glx_config **a, struct glx_config **b) { /* The order of these comparisons must NOT change. It is defined by * the GLX 1.3 spec and ARB_multisample. @@ -1414,10 +1133,10 @@ fbconfig_compare(const __GLcontextModes * const *const a, * \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX */ static int -choose_visual(__GLcontextModes ** configs, int num_configs, +choose_visual(struct glx_config ** configs, int num_configs, const int *attribList, GLboolean fbconfig_style_tags) { - __GLcontextModes test_config; + struct glx_config test_config; int base; int i; @@ -1453,7 +1172,7 @@ choose_visual(__GLcontextModes ** configs, int num_configs, * specifications. */ - qsort(configs, base, sizeof(__GLcontextModes *), + qsort(configs, base, sizeof(struct glx_config *), (int (*)(const void *, const void *)) fbconfig_compare); return base; } @@ -1465,15 +1184,15 @@ choose_visual(__GLcontextModes ** configs, int num_configs, ** Return the visual that best matches the template. Return None if no ** visual matches the template. */ -PUBLIC XVisualInfo * +_X_EXPORT XVisualInfo * glXChooseVisual(Display * dpy, int screen, int *attribList) { XVisualInfo *visualList = NULL; - __GLXdisplayPrivate *priv; - __GLXscreenConfigs *psc; - __GLcontextModes test_config; - __GLcontextModes *modes; - const __GLcontextModes *best_config = NULL; + struct glx_display *priv; + struct glx_screen *psc; + struct glx_config test_config; + struct glx_config *config; + struct glx_config *best_config = NULL; /* ** Get a list of all visuals, return if list is empty @@ -1500,26 +1219,23 @@ glXChooseVisual(Display * dpy, int screen, int *attribList) ** Otherwise, create an XVisualInfo list with just the selected X visual ** and return this. */ - for (modes = psc->visuals; modes != NULL; modes = modes->next) { - if (fbconfigs_compatible(&test_config, modes) - && ((best_config == NULL) - || - (fbconfig_compare - ((const __GLcontextModes * const *const) &modes, - &best_config) < 0))) { + for (config = psc->visuals; config != NULL; config = config->next) { + if (fbconfigs_compatible(&test_config, config) + && ((best_config == NULL) || + (fbconfig_compare (&config, &best_config) < 0))) { XVisualInfo visualTemplate; XVisualInfo *newList; int i; visualTemplate.screen = screen; - visualTemplate.visualid = modes->visualID; + visualTemplate.visualid = config->visualID; newList = XGetVisualInfo(dpy, VisualScreenMask | VisualIDMask, &visualTemplate, &i); if (newList) { Xfree(visualList); visualList = newList; - best_config = modes; + best_config = config; } } } @@ -1534,11 +1250,11 @@ glXChooseVisual(Display * dpy, int screen, int *attribList) } -PUBLIC const char * +_X_EXPORT const char * glXQueryExtensionsString(Display * dpy, int screen) { - __GLXscreenConfigs *psc; - __GLXdisplayPrivate *priv; + struct glx_screen *psc; + struct glx_display *priv; if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) { return NULL; @@ -1563,7 +1279,7 @@ glXQueryExtensionsString(Display * dpy, int screen) return psc->effectiveGLXexts; } -PUBLIC const char * +_X_EXPORT const char * glXGetClientString(Display * dpy, int name) { (void) dpy; @@ -1580,11 +1296,11 @@ glXGetClientString(Display * dpy, int name) } } -PUBLIC const char * +_X_EXPORT const char * glXQueryServerString(Display * dpy, int screen, int name) { - __GLXscreenConfigs *psc; - __GLXdisplayPrivate *priv; + struct glx_screen *psc; + struct glx_display *priv; const char **str; @@ -1650,175 +1366,141 @@ __glXClientInfo(Display * dpy, int opcode) ** EXT_import_context */ -PUBLIC Display * +_X_EXPORT Display * glXGetCurrentDisplay(void) { - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); if (NULL == gc) return NULL; return gc->currentDpy; } -PUBLIC +_X_EXPORT GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (), glXGetCurrentDisplay) #ifndef GLX_USE_APPLEGL -/** - * Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests - * to the X-server. - * - * \param dpy Display where \c ctx was created. - * \param ctx Context to query. - * \returns \c Success on success. \c GLX_BAD_CONTEXT if \c ctx is invalid, - * or zero if the request failed due to internal problems (i.e., - * unable to allocate temporary memory, etc.) - * - * \note - * This function dynamically determines whether to use the EXT_import_context - * version of the protocol or the GLX 1.3 version of the protocol. - */ -static int __glXQueryContextInfo(Display * dpy, GLXContext ctx) +_X_EXPORT GLXContext +glXImportContextEXT(Display *dpy, GLXContextID contextID) { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); + struct glx_display *priv = __glXInitialize(dpy); + struct glx_screen *psc; xGLXQueryContextReply reply; CARD8 opcode; - GLuint numValues; - int retval; + struct glx_context *ctx; + int propList[__GLX_MAX_CONTEXT_PROPS * 2], *pProp, nPropListBytes; + int i, renderType; + XID share; + struct glx_config *mode; + + if (contextID == None || __glXIsDirect(dpy, contextID)) + return NULL; - if (ctx == NULL) { - return GLX_BAD_CONTEXT; - } opcode = __glXSetupForCommand(dpy); - if (!opcode) { + if (!opcode) return 0; - } /* Send the glXQueryContextInfoEXT request */ LockDisplay(dpy); - if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { + if (priv->majorVersion > 1 || priv->minorVersion >= 3) { xGLXQueryContextReq *req; GetReq(GLXQueryContext, req); req->reqType = opcode; req->glxCode = X_GLXQueryContext; - req->context = (unsigned int) (ctx->xid); + req->context = contextID; } else { xGLXVendorPrivateReq *vpreq; xGLXQueryContextInfoEXTReq *req; GetReqExtra(GLXVendorPrivate, - sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq, - vpreq); + sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq, + vpreq); req = (xGLXQueryContextInfoEXTReq *) vpreq; req->reqType = opcode; req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_QueryContextInfoEXT; - req->context = (unsigned int) (ctx->xid); + req->context = contextID; } _XReply(dpy, (xReply *) & reply, 0, False); - numValues = reply.n; - if (numValues == 0) - retval = Success; - else if (numValues > __GLX_MAX_CONTEXT_PROPS) - retval = 0; - else { - int *propList, *pProp; - int nPropListBytes; - - nPropListBytes = numValues << 3; - propList = (int *) Xmalloc(nPropListBytes); - if (NULL == propList) { - retval = 0; - } - else { - unsigned i; - - _XRead(dpy, (char *) propList, nPropListBytes); - - /* Look up screen first so we can look up visuals/fbconfigs later */ - pProp = propList; - for (i = 0; i < numValues; i++, pProp += 2) - if (pProp[0] == GLX_SCREEN) { - ctx->screen = pProp[1]; - ctx->psc = GetGLXScreenConfigs(dpy, ctx->screen); - } - - pProp = propList; - for (i = 0; i < numValues; i++) { - switch (*pProp++) { - case GLX_SHARE_CONTEXT_EXT: - ctx->share_xid = *pProp++; - break; - case GLX_VISUAL_ID_EXT: - ctx->mode = - _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++); - break; - case GLX_FBCONFIG_ID: - ctx->mode = - _gl_context_modes_find_fbconfig(ctx->psc->configs, - *pProp++); - break; - case GLX_RENDER_TYPE: - ctx->renderType = *pProp++; - break; - case GLX_SCREEN: - default: - pProp++; - continue; - } - } - Xfree((char *) propList); - retval = Success; - } - } + if (reply.n <= __GLX_MAX_CONTEXT_PROPS) + nPropListBytes = reply.n * 2 * sizeof propList[0]; + else + nPropListBytes = 0; + _XRead(dpy, (char *) propList, nPropListBytes); UnlockDisplay(dpy); SyncHandle(); - return retval; + + /* Look up screen first so we can look up visuals/fbconfigs later */ + psc = NULL; + for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2) + if (pProp[0] == GLX_SCREEN) + psc = GetGLXScreenConfigs(dpy, pProp[1]); + if (psc == NULL) + return NULL; + + share = None; + mode = NULL; + renderType = 0; + pProp = propList; + + for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2) + switch (pProp[0]) { + case GLX_SHARE_CONTEXT_EXT: + share = pProp[1]; + break; + case GLX_VISUAL_ID_EXT: + mode = glx_config_find_visual(psc->visuals, pProp[1]); + break; + case GLX_FBCONFIG_ID: + mode = glx_config_find_fbconfig(psc->configs, pProp[1]); + break; + case GLX_RENDER_TYPE: + renderType = pProp[1]; + break; + } + + if (mode == NULL) + return NULL; + + ctx = indirect_create_context(psc, mode, NULL, renderType); + if (ctx == NULL) + return NULL; + + ctx->xid = contextID; + ctx->imported = GL_TRUE; + ctx->share_xid = share; + + return (GLXContext) ctx; } #endif -PUBLIC int -glXQueryContext(Display * dpy, GLXContext ctx, int attribute, int *value) +_X_EXPORT int +glXQueryContext(Display * dpy, GLXContext ctx_user, int attribute, int *value) { -#ifndef GLX_USE_APPLEGL - int retVal; - - /* get the information from the server if we don't have it already */ -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (!ctx->driContext && (ctx->mode == NULL)) { -#else - if (ctx->mode == NULL) { -#endif - retVal = __glXQueryContextInfo(dpy, ctx); - if (Success != retVal) - return retVal; - } -#endif + struct glx_context *ctx = (struct glx_context *) ctx_user; switch (attribute) { -#ifndef GLX_USE_APPLEGL case GLX_SHARE_CONTEXT_EXT: - *value = (int) (ctx->share_xid); + *value = ctx->share_xid; break; case GLX_VISUAL_ID_EXT: - *value = ctx->mode ? ctx->mode->visualID : None; + *value = ctx->config ? ctx->config->visualID : None; break; -#endif case GLX_SCREEN: - *value = (int) (ctx->screen); + *value = ctx->screen; break; case GLX_FBCONFIG_ID: - *value = ctx->mode ? ctx->mode->fbconfigID : None; + *value = ctx->config ? ctx->config->fbconfigID : None; break; case GLX_RENDER_TYPE: - *value = (int) (ctx->renderType); + *value = ctx->renderType; break; default: return GLX_BAD_ATTRIBUTE; @@ -1826,66 +1508,34 @@ glXQueryContext(Display * dpy, GLXContext ctx, int attribute, int *value) return Success; } -PUBLIC +_X_EXPORT GLX_ALIAS(int, glXQueryContextInfoEXT, (Display * dpy, GLXContext ctx, int attribute, int *value), (dpy, ctx, attribute, value), glXQueryContext) -PUBLIC GLXContextID glXGetContextIDEXT(const GLXContext ctx) +_X_EXPORT GLXContextID glXGetContextIDEXT(const GLXContext ctx_user) { - return ctx->xid; -} + struct glx_context *ctx = (struct glx_context *) ctx_user; -PUBLIC GLXContext -glXImportContextEXT(Display * dpy, GLXContextID contextID) -{ -#ifdef GLX_USE_APPLEGL - return NULL; -#else - GLXContext ctx; - - if (contextID == None) { - return NULL; - } - if (__glXIsDirect(dpy, contextID)) { - return NULL; - } - - ctx = AllocateGLXContext(dpy); - if (NULL != ctx) { - ctx->xid = contextID; - ctx->imported = GL_TRUE; - - if (Success != __glXQueryContextInfo(dpy, ctx)) { - __glXFreeContext(ctx); - ctx = NULL; - } - } - return ctx; -#endif + return ctx->xid; } -PUBLIC void +_X_EXPORT void glXFreeContextEXT(Display * dpy, GLXContext ctx) { DestroyContext(dpy, ctx); } - -/* - * GLX 1.3 functions - these are just stubs for now! - */ - -PUBLIC GLXFBConfig * +_X_EXPORT GLXFBConfig * glXChooseFBConfig(Display * dpy, int screen, const int *attribList, int *nitems) { - __GLcontextModes **config_list; + struct glx_config **config_list; int list_size; - config_list = (__GLcontextModes **) + config_list = (struct glx_config **) glXGetFBConfigs(dpy, screen, &list_size); if ((config_list != NULL) && (list_size > 0) && (attribList != NULL)) { @@ -1901,92 +1551,92 @@ glXChooseFBConfig(Display * dpy, int screen, } -PUBLIC GLXContext -glXCreateNewContext(Display * dpy, GLXFBConfig config, +_X_EXPORT GLXContext +glXCreateNewContext(Display * dpy, GLXFBConfig fbconfig, int renderType, GLXContext shareList, Bool allowDirect) { - const __GLcontextModes *const fbconfig = - (const __GLcontextModes *const) config; + struct glx_config *config = (struct glx_config *) fbconfig; - return CreateContext(dpy, fbconfig->fbconfigID, fbconfig, shareList, - allowDirect, X_GLXCreateNewContext, renderType, - fbconfig->screen); + return CreateContext(dpy, config->fbconfigID, config, shareList, + allowDirect, X_GLXCreateNewContext, renderType, + config->screen); } -PUBLIC GLXDrawable +_X_EXPORT GLXDrawable glXGetCurrentReadDrawable(void) { - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); + return gc->currentReadable; } -PUBLIC GLXFBConfig * +_X_EXPORT GLXFBConfig * glXGetFBConfigs(Display * dpy, int screen, int *nelements) { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); - __GLcontextModes **config = NULL; + struct glx_display *priv = __glXInitialize(dpy); + struct glx_config **config_list = NULL; + struct glx_config *config; + unsigned num_configs = 0; int i; *nelements = 0; - if (priv && (priv->screenConfigs != NULL) + if (priv && (priv->screens != NULL) && (screen >= 0) && (screen <= ScreenCount(dpy)) - && (priv->screenConfigs[screen]->configs != NULL) - && (priv->screenConfigs[screen]->configs->fbconfigID + && (priv->screens[screen]->configs != NULL) + && (priv->screens[screen]->configs->fbconfigID != (int) GLX_DONT_CARE)) { - unsigned num_configs = 0; - __GLcontextModes *modes; - - for (modes = priv->screenConfigs[screen]->configs; modes != NULL; - modes = modes->next) { - if (modes->fbconfigID != (int) GLX_DONT_CARE) { + for (config = priv->screens[screen]->configs; config != NULL; + config = config->next) { + if (config->fbconfigID != (int) GLX_DONT_CARE) { num_configs++; } } - config = (__GLcontextModes **) Xmalloc(sizeof(__GLcontextModes *) - * num_configs); - if (config != NULL) { + config_list = Xmalloc(num_configs * sizeof *config_list); + if (config_list != NULL) { *nelements = num_configs; i = 0; - for (modes = priv->screenConfigs[screen]->configs; modes != NULL; - modes = modes->next) { - if (modes->fbconfigID != (int) GLX_DONT_CARE) { - config[i] = modes; + for (config = priv->screens[screen]->configs; config != NULL; + config = config->next) { + if (config->fbconfigID != (int) GLX_DONT_CARE) { + config_list[i] = config; i++; } } } } - return (GLXFBConfig *) config; + + return (GLXFBConfig *) config_list; } -PUBLIC int -glXGetFBConfigAttrib(Display * dpy, GLXFBConfig config, +_X_EXPORT int +glXGetFBConfigAttrib(Display * dpy, GLXFBConfig fbconfig, int attribute, int *value) { - __GLcontextModes *const modes = ValidateGLXFBConfig(dpy, config); + struct glx_config *config = ValidateGLXFBConfig(dpy, fbconfig); - return (modes != NULL) - ? _gl_get_context_mode_data(modes, attribute, value) - : GLXBadFBConfig; + if (config == NULL) + return GLXBadFBConfig; + + return glx_config_get(config, attribute, value); } -PUBLIC XVisualInfo * -glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig config) +_X_EXPORT XVisualInfo * +glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig fbconfig) { XVisualInfo visualTemplate; - __GLcontextModes *fbconfig = (__GLcontextModes *) config; + struct glx_config *config = (struct glx_config *) fbconfig; int count; /* ** Get a list of all visuals, return if list is empty */ - visualTemplate.visualid = fbconfig->visualID; + visualTemplate.visualid = config->visualID; return XGetVisualInfo(dpy, VisualIDMask, &visualTemplate, &count); } @@ -1998,8 +1648,8 @@ static int __glXSwapIntervalSGI(int interval) { xGLXVendorPrivateReq *req; - GLXContext gc = __glXGetCurrentContext(); - __GLXscreenConfigs *psc; + struct glx_context *gc = __glXGetCurrentContext(); + struct glx_screen *psc; Display *dpy; CARD32 *interval_ptr; CARD8 opcode; @@ -2015,7 +1665,7 @@ __glXSwapIntervalSGI(int interval) psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); #ifdef GLX_DIRECT_RENDERING - if (gc->driContext && psc->driScreen && psc->driScreen->setSwapInterval) { + if (gc->isDirect && psc->driScreen && psc->driScreen->setSwapInterval) { __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable); psc->driScreen->setSwapInterval(pdraw, interval); @@ -2055,10 +1705,10 @@ static int __glXSwapIntervalMESA(unsigned int interval) { #ifdef GLX_DIRECT_RENDERING - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); - if (gc != NULL && gc->driContext) { - __GLXscreenConfigs *psc; + if (gc != NULL && gc->isDirect) { + struct glx_screen *psc; psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); if (psc->driScreen && psc->driScreen->setSwapInterval) { @@ -2077,10 +1727,10 @@ static int __glXGetSwapIntervalMESA(void) { #ifdef GLX_DIRECT_RENDERING - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); - if (gc != NULL && gc->driContext) { - __GLXscreenConfigs *psc; + if (gc != NULL && gc->isDirect) { + struct glx_screen *psc; psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); if (psc->driScreen && psc->driScreen->getSwapInterval) { @@ -2103,8 +1753,8 @@ __glXGetVideoSyncSGI(unsigned int *count) { int64_t ust, msc, sbc; int ret; - GLXContext gc = __glXGetCurrentContext(); - __GLXscreenConfigs *psc; + struct glx_context *gc = __glXGetCurrentContext(); + struct glx_screen *psc; #ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw; #endif @@ -2113,7 +1763,7 @@ __glXGetVideoSyncSGI(unsigned int *count) return GLX_BAD_CONTEXT; #ifdef GLX_DIRECT_RENDERING - if (!gc->driContext) + if (!gc->isDirect) return GLX_BAD_CONTEXT; #endif @@ -2140,8 +1790,8 @@ __glXGetVideoSyncSGI(unsigned int *count) static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) { - GLXContext gc = __glXGetCurrentContext(); - __GLXscreenConfigs *psc; + struct glx_context *gc = __glXGetCurrentContext(); + struct glx_screen *psc; #ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw; #endif @@ -2155,7 +1805,7 @@ __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) return GLX_BAD_CONTEXT; #ifdef GLX_DIRECT_RENDERING - if (!gc->driContext) + if (!gc->isDirect) return GLX_BAD_CONTEXT; #endif @@ -2184,23 +1834,23 @@ __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) ** GLX_functions table. */ -PUBLIC +_X_EXPORT GLX_ALIAS(int, glXGetFBConfigAttribSGIX, (Display * dpy, GLXFBConfigSGIX config, int attribute, int *value), (dpy, config, attribute, value), glXGetFBConfigAttrib) -PUBLIC GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX, +_X_EXPORT GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX, (Display * dpy, int screen, int *attrib_list, int *nelements), (dpy, screen, attrib_list, nelements), glXChooseFBConfig) -PUBLIC GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX, +_X_EXPORT GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX, (Display * dpy, GLXFBConfigSGIX config), (dpy, config), glXGetVisualFromFBConfig) -PUBLIC GLXPixmap +_X_EXPORT GLXPixmap glXCreateGLXPixmapWithConfigSGIX(Display * dpy, - GLXFBConfigSGIX config, + GLXFBConfigSGIX fbconfig, Pixmap pixmap) { #ifndef GLX_USE_APPLEGL @@ -2208,21 +1858,21 @@ glXCreateGLXPixmapWithConfigSGIX(Display * dpy, xGLXCreateGLXPixmapWithConfigSGIXReq *req; GLXPixmap xid = None; CARD8 opcode; - __GLXscreenConfigs *psc; + struct glx_screen *psc; #endif - const __GLcontextModes *const fbconfig = (__GLcontextModes *) config; + struct glx_config *config = (struct glx_config *) fbconfig; if ((dpy == NULL) || (config == NULL)) { return None; } #ifdef GLX_USE_APPLEGL - if(apple_glx_pixmap_create(dpy, fbconfig->screen, pixmap, fbconfig)) + if(apple_glx_pixmap_create(dpy, config->screen, pixmap, config)) return None; return pixmap; #else - psc = GetGLXScreenConfigs(dpy, fbconfig->screen); + psc = GetGLXScreenConfigs(dpy, config->screen); if ((psc != NULL) && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) { opcode = __glXSetupForCommand(dpy); @@ -2239,8 +1889,8 @@ glXCreateGLXPixmapWithConfigSGIX(Display * dpy, req->reqType = opcode; req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX; - req->screen = fbconfig->screen; - req->fbconfig = fbconfig->fbconfigID; + req->screen = config->screen; + req->fbconfig = config->fbconfigID; req->pixmap = pixmap; req->glxpixmap = xid = XAllocID(dpy); UnlockDisplay(dpy); @@ -2251,44 +1901,44 @@ glXCreateGLXPixmapWithConfigSGIX(Display * dpy, #endif } -PUBLIC GLXContext +_X_EXPORT GLXContext glXCreateContextWithConfigSGIX(Display * dpy, - GLXFBConfigSGIX config, int renderType, + GLXFBConfigSGIX fbconfig, int renderType, GLXContext shareList, Bool allowDirect) { GLXContext gc = NULL; - const __GLcontextModes *const fbconfig = (__GLcontextModes *) config; - __GLXscreenConfigs *psc; + struct glx_config *config = (struct glx_config *) fbconfig; + struct glx_screen *psc; if ((dpy == NULL) || (config == NULL)) { return None; } - psc = GetGLXScreenConfigs(dpy, fbconfig->screen); + psc = GetGLXScreenConfigs(dpy, config->screen); if ((psc != NULL) && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) { - gc = CreateContext(dpy, fbconfig->fbconfigID, fbconfig, shareList, + gc = CreateContext(dpy, config->fbconfigID, config, shareList, allowDirect, X_GLXvop_CreateContextWithConfigSGIX, renderType, - fbconfig->screen); + config->screen); } return gc; } -PUBLIC GLXFBConfigSGIX +_X_EXPORT GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis) { - __GLXdisplayPrivate *priv; - __GLXscreenConfigs *psc = NULL; + struct glx_display *priv; + struct glx_screen *psc = NULL; if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) != Success) && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit) && (psc->configs->fbconfigID != (int) GLX_DONT_CARE)) { - return (GLXFBConfigSGIX) _gl_context_modes_find_visual(psc->configs, - vis->visualid); + return (GLXFBConfigSGIX) glx_config_find_visual(psc->configs, + vis->visualid); } return NULL; @@ -2336,12 +1986,12 @@ static Bool __glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable, int64_t * ust, int64_t * msc, int64_t * sbc) { - __GLXdisplayPrivate * const priv = __glXInitialize(dpy); + struct glx_display * const priv = __glXInitialize(dpy); int ret; #ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw; #endif - __GLXscreenConfigs *psc; + struct glx_screen *psc; if (!priv) return False; @@ -2364,7 +2014,7 @@ __glxGetMscRate(__GLXDRIdrawable *glxDraw, int32_t * numerator, int32_t * denominator) { #ifdef XF86VIDMODE - __GLXscreenConfigs *psc; + struct glx_screen *psc; XF86VidModeModeLine mode_line; int dot_clock; int i; @@ -2466,17 +2116,17 @@ static int64_t __glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder) { - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); #ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); - __GLXscreenConfigs *psc = pdraw ? pdraw->psc : NULL; + struct glx_screen *psc = pdraw ? pdraw->psc : NULL; #endif if (!gc) /* no GLX for this */ return -1; #ifdef GLX_DIRECT_RENDERING - if (!pdraw || !gc->driContext) + if (!pdraw || !gc->isDirect) return -1; #endif @@ -2512,7 +2162,7 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable, #ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); #endif - __GLXscreenConfigs *psc = pdraw ? pdraw->psc : NULL; + struct glx_screen *psc = pdraw ? pdraw->psc : NULL; int ret; @@ -2544,7 +2194,7 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable, #ifdef GLX_DIRECT_RENDERING __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); #endif - __GLXscreenConfigs *psc = pdraw ? pdraw->psc : NULL; + struct glx_screen *psc = pdraw ? pdraw->psc : NULL; int ret; /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE @@ -2602,7 +2252,7 @@ __glXReleaseBuffersMESA(Display * dpy, GLXDrawable d) } -PUBLIC GLXPixmap +_X_EXPORT GLXPixmap glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual, Pixmap pixmap, Colormap cmap) { @@ -2625,16 +2275,16 @@ __glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable, int x, int y, int width, int height) { xGLXVendorPrivateReq *req; - GLXContext gc; + struct glx_context *gc; GLXContextTag tag; CARD32 *drawable_ptr; INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr; CARD8 opcode; -#ifdef __DRI_COPY_SUB_BUFFER +#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable); if (pdraw != NULL) { - __GLXscreenConfigs *psc = pdraw->psc; + struct glx_screen *psc = pdraw->psc; if (psc->driScreen->copySubBuffer != NULL) { glFlush(); (*psc->driScreen->copySubBuffer) (pdraw, x, y, width, height); @@ -2685,107 +2335,12 @@ __glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable, SyncHandle(); } - -/** - * GLX_EXT_texture_from_pixmap - */ -static void -indirect_bind_tex_image(Display * dpy, - GLXDrawable drawable, - int buffer, const int *attrib_list) -{ - xGLXVendorPrivateReq *req; - GLXContext gc = __glXGetCurrentContext(); - CARD32 *drawable_ptr; - INT32 *buffer_ptr; - CARD32 *num_attrib_ptr; - CARD32 *attrib_ptr; - CARD8 opcode; - unsigned int i; - - i = 0; - if (attrib_list) { - while (attrib_list[i * 2] != None) - i++; - } - - opcode = __glXSetupForCommand(dpy); - if (!opcode) - return; - - LockDisplay(dpy); - GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req); - req->reqType = opcode; - req->glxCode = X_GLXVendorPrivate; - req->vendorCode = X_GLXvop_BindTexImageEXT; - req->contextTag = gc->currentContextTag; - - drawable_ptr = (CARD32 *) (req + 1); - buffer_ptr = (INT32 *) (drawable_ptr + 1); - num_attrib_ptr = (CARD32 *) (buffer_ptr + 1); - attrib_ptr = (CARD32 *) (num_attrib_ptr + 1); - - *drawable_ptr = drawable; - *buffer_ptr = buffer; - *num_attrib_ptr = (CARD32) i; - - i = 0; - if (attrib_list) { - while (attrib_list[i * 2] != None) { - *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0]; - *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1]; - i++; - } - } - - UnlockDisplay(dpy); - SyncHandle(); -} - -static void -indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer) -{ - xGLXVendorPrivateReq *req; - GLXContext gc = __glXGetCurrentContext(); - CARD32 *drawable_ptr; - INT32 *buffer_ptr; - CARD8 opcode; - - opcode = __glXSetupForCommand(dpy); - if (!opcode) - return; - - LockDisplay(dpy); - GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req); - req->reqType = opcode; - req->glxCode = X_GLXVendorPrivate; - req->vendorCode = X_GLXvop_ReleaseTexImageEXT; - req->contextTag = gc->currentContextTag; - - drawable_ptr = (CARD32 *) (req + 1); - buffer_ptr = (INT32 *) (drawable_ptr + 1); - - *drawable_ptr = drawable; - *buffer_ptr = buffer; - - UnlockDisplay(dpy); - SyncHandle(); -} - -static const struct glx_context_vtable indirect_context_vtable = { - indirect_wait_gl, - indirect_wait_x, - indirect_use_x_font, - indirect_bind_tex_image, - indirect_release_tex_image, -}; - /*@{*/ static void __glXBindTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer, const int *attrib_list) { - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); if (gc == NULL || gc->vtable->bind_tex_image == NULL) return; @@ -2796,7 +2351,7 @@ __glXBindTexImageEXT(Display * dpy, static void __glXReleaseTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer) { - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); if (gc == NULL || gc->vtable->release_tex_image == NULL) return; @@ -2995,7 +2550,7 @@ get_glx_proc_address(const char *funcName) * * \sa glXGetProcAddress */ -PUBLIC void (*glXGetProcAddressARB(const GLubyte * procName)) (void) +_X_EXPORT void (*glXGetProcAddressARB(const GLubyte * procName)) (void) { typedef void (*gl_function) (void); gl_function f; @@ -3028,7 +2583,7 @@ PUBLIC void (*glXGetProcAddressARB(const GLubyte * procName)) (void) * * \sa glXGetProcAddressARB */ -PUBLIC void (*glXGetProcAddress(const GLubyte * procName)) (void) +_X_EXPORT void (*glXGetProcAddress(const GLubyte * procName)) (void) #if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED) __attribute__ ((alias("glXGetProcAddressARB"))); #else diff --git a/src/glx/glxconfig.c b/src/glx/glxconfig.c new file mode 100644 index 00000000000..1d9678f48cd --- /dev/null +++ b/src/glx/glxconfig.c @@ -0,0 +1,304 @@ +/* + * (C) Copyright IBM Corporation 2003 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file glxconfig.c + * Utility routines for working with \c struct glx_config structures. At + * some point most or all of these functions will be moved to the Mesa + * code base. + * + * \author Ian Romanick <[email protected]> + */ + +#include <GL/glx.h> +#include "GL/glxint.h" +#include <stdlib.h> +#include <string.h> + +#include "glxconfig.h" + +#define NUM_VISUAL_TYPES 6 + +/** + * Get data from a GLX config + * + * \param mode GL context mode whose data is to be returned. + * \param attribute Attribute of \c mode that is to be returned. + * \param value_return Location to store the data member of \c mode. + * \return If \c attribute is a valid attribute of \c mode, zero is + * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned. + */ +_X_HIDDEN int +glx_config_get(struct glx_config * mode, int attribute, int *value_return) +{ + switch (attribute) { + case GLX_USE_GL: + *value_return = GL_TRUE; + return 0; + case GLX_BUFFER_SIZE: + *value_return = mode->rgbBits; + return 0; + case GLX_RGBA: + *value_return = mode->rgbMode; + return 0; + case GLX_RED_SIZE: + *value_return = mode->redBits; + return 0; + case GLX_GREEN_SIZE: + *value_return = mode->greenBits; + return 0; + case GLX_BLUE_SIZE: + *value_return = mode->blueBits; + return 0; + case GLX_ALPHA_SIZE: + *value_return = mode->alphaBits; + return 0; + case GLX_DOUBLEBUFFER: + *value_return = mode->doubleBufferMode; + return 0; + case GLX_STEREO: + *value_return = mode->stereoMode; + return 0; + case GLX_AUX_BUFFERS: + *value_return = mode->numAuxBuffers; + return 0; + case GLX_DEPTH_SIZE: + *value_return = mode->depthBits; + return 0; + case GLX_STENCIL_SIZE: + *value_return = mode->stencilBits; + return 0; + case GLX_ACCUM_RED_SIZE: + *value_return = mode->accumRedBits; + return 0; + case GLX_ACCUM_GREEN_SIZE: + *value_return = mode->accumGreenBits; + return 0; + case GLX_ACCUM_BLUE_SIZE: + *value_return = mode->accumBlueBits; + return 0; + case GLX_ACCUM_ALPHA_SIZE: + *value_return = mode->accumAlphaBits; + return 0; + case GLX_LEVEL: + *value_return = mode->level; + return 0; +#ifndef GLX_USE_APPLEGL /* This isn't supported by CGL. */ + case GLX_TRANSPARENT_TYPE_EXT: + *value_return = mode->transparentPixel; + return 0; +#endif + case GLX_TRANSPARENT_RED_VALUE: + *value_return = mode->transparentRed; + return 0; + case GLX_TRANSPARENT_GREEN_VALUE: + *value_return = mode->transparentGreen; + return 0; + case GLX_TRANSPARENT_BLUE_VALUE: + *value_return = mode->transparentBlue; + return 0; + case GLX_TRANSPARENT_ALPHA_VALUE: + *value_return = mode->transparentAlpha; + return 0; + case GLX_TRANSPARENT_INDEX_VALUE: + *value_return = mode->transparentIndex; + return 0; + case GLX_X_VISUAL_TYPE: + *value_return = mode->visualType; + return 0; + case GLX_CONFIG_CAVEAT: + *value_return = mode->visualRating; + return 0; + case GLX_VISUAL_ID: + *value_return = mode->visualID; + return 0; + case GLX_DRAWABLE_TYPE: + *value_return = mode->drawableType; + return 0; + case GLX_RENDER_TYPE: + *value_return = mode->renderType; + return 0; + case GLX_X_RENDERABLE: + *value_return = mode->xRenderable; + return 0; + case GLX_FBCONFIG_ID: + *value_return = mode->fbconfigID; + return 0; + case GLX_MAX_PBUFFER_WIDTH: + *value_return = mode->maxPbufferWidth; + return 0; + case GLX_MAX_PBUFFER_HEIGHT: + *value_return = mode->maxPbufferHeight; + return 0; + case GLX_MAX_PBUFFER_PIXELS: + *value_return = mode->maxPbufferPixels; + return 0; +#ifndef GLX_USE_APPLEGL /* These aren't supported by CGL. */ + case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX: + *value_return = mode->optimalPbufferWidth; + return 0; + case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX: + *value_return = mode->optimalPbufferHeight; + return 0; + case GLX_SWAP_METHOD_OML: + *value_return = mode->swapMethod; + return 0; +#endif + case GLX_SAMPLE_BUFFERS_SGIS: + *value_return = mode->sampleBuffers; + return 0; + case GLX_SAMPLES_SGIS: + *value_return = mode->samples; + return 0; + case GLX_BIND_TO_TEXTURE_RGB_EXT: + *value_return = mode->bindToTextureRgb; + return 0; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + *value_return = mode->bindToTextureRgba; + return 0; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE : + GL_FALSE; + return 0; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + *value_return = mode->bindToTextureTargets; + return 0; + case GLX_Y_INVERTED_EXT: + *value_return = mode->yInverted; + return 0; + + /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX. + * It is ONLY for communication between the GLX client and the GLX + * server. + */ + case GLX_VISUAL_SELECT_GROUP_SGIX: + default: + return GLX_BAD_ATTRIBUTE; + } +} + + +/** + * Allocate a linked list of \c struct glx_config structures. The fields of + * each structure will be initialized to "reasonable" default values. In + * most cases this is the default value defined by table 3.4 of the GLX + * 1.3 specification. This means that most values are either initialized to + * zero or \c GLX_DONT_CARE (which is -1). As support for additional + * extensions is added, the new values will be initialized to appropriate + * values from the extension specification. + * + * \param count Number of structures to allocate. + * \param minimum_size Minimum size of a structure to allocate. This allows + * for differences in the version of the + * \c struct glx_config stucture used in libGL and in a + * DRI-based driver. + * \returns A pointer to the first element in a linked list of \c count + * stuctures on success, or \c NULL on failure. + */ +_X_HIDDEN struct glx_config * +glx_config_create_list(unsigned count) +{ + const size_t size = sizeof(struct glx_config); + struct glx_config *base = NULL; + struct glx_config **next; + unsigned i; + + next = &base; + for (i = 0; i < count; i++) { + *next = (struct glx_config *) malloc(size); + if (*next == NULL) { + glx_config_destroy_list(base); + base = NULL; + break; + } + + (void) memset(*next, 0, size); + (*next)->visualID = GLX_DONT_CARE; + (*next)->visualType = GLX_DONT_CARE; + (*next)->visualRating = GLX_NONE; + (*next)->transparentPixel = GLX_NONE; + (*next)->transparentRed = GLX_DONT_CARE; + (*next)->transparentGreen = GLX_DONT_CARE; + (*next)->transparentBlue = GLX_DONT_CARE; + (*next)->transparentAlpha = GLX_DONT_CARE; + (*next)->transparentIndex = GLX_DONT_CARE; + (*next)->xRenderable = GLX_DONT_CARE; + (*next)->fbconfigID = GLX_DONT_CARE; + (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML; + (*next)->bindToTextureRgb = GLX_DONT_CARE; + (*next)->bindToTextureRgba = GLX_DONT_CARE; + (*next)->bindToMipmapTexture = GLX_DONT_CARE; + (*next)->bindToTextureTargets = GLX_DONT_CARE; + (*next)->yInverted = GLX_DONT_CARE; + + next = &((*next)->next); + } + + return base; +} + +_X_HIDDEN void +glx_config_destroy_list(struct glx_config *configs) +{ + while (configs != NULL) { + struct glx_config *const next = configs->next; + + free(configs); + configs = next; + } +} + + +/** + * Find a context mode matching a Visual ID. + * + * \param modes List list of context-mode structures to be searched. + * \param vid Visual ID to be found. + * \returns A pointer to a context-mode in \c modes if \c vid was found in + * the list, or \c NULL if it was not. + */ + +_X_HIDDEN struct glx_config * +glx_config_find_visual(struct glx_config *configs, int vid) +{ + struct glx_config *c; + + for (c = configs; c != NULL; c = c->next) + if (c->visualID == vid) + return c; + + return NULL; +} + +_X_HIDDEN struct glx_config * +glx_config_find_fbconfig(struct glx_config *configs, int fbid) +{ + struct glx_config *c; + + for (c = configs; c != NULL; c = c->next) + if (c->fbconfigID == fbid) + return c; + + return NULL; +} diff --git a/src/glx/glxconfig.h b/src/glx/glxconfig.h new file mode 100644 index 00000000000..f7ee958e4be --- /dev/null +++ b/src/glx/glxconfig.h @@ -0,0 +1,133 @@ +/* + * (C) Copyright IBM Corporation 2003 + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file glcontextmodes.h + * \author Ian Romanick <[email protected]> + */ + +#ifndef GLCONTEXTMODES_H +#define GLCONTEXTMODES_H + +struct glx_config { + struct glx_config * next; + + GLboolean rgbMode; + GLboolean floatMode; + GLboolean colorIndexMode; + GLuint doubleBufferMode; + GLuint stereoMode; + + GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ + GLuint redMask, greenMask, blueMask, alphaMask; + GLint rgbBits; /* total bits for rgb */ + GLint indexBits; /* total bits for colorindex */ + + GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; + GLint depthBits; + GLint stencilBits; + + GLint numAuxBuffers; + + GLint level; + + GLint pixmapMode; + + /* GLX */ + GLint visualID; + GLint visualType; /**< One of the GLX X visual types. (i.e., + * \c GLX_TRUE_COLOR, etc.) + */ + + /* EXT_visual_rating / GLX 1.2 */ + GLint visualRating; + + /* EXT_visual_info / GLX 1.2 */ + GLint transparentPixel; + /* colors are floats scaled to ints */ + GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha; + GLint transparentIndex; + + /* ARB_multisample / SGIS_multisample */ + GLint sampleBuffers; + GLint samples; + + /* SGIX_fbconfig / GLX 1.3 */ + GLint drawableType; + GLint renderType; + GLint xRenderable; + GLint fbconfigID; + + /* SGIX_pbuffer / GLX 1.3 */ + GLint maxPbufferWidth; + GLint maxPbufferHeight; + GLint maxPbufferPixels; + GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */ + GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */ + + /* SGIX_visual_select_group */ + GLint visualSelectGroup; + + /* OML_swap_method */ + GLint swapMethod; + + GLint screen; + + /* EXT_texture_from_pixmap */ + GLint bindToTextureRgb; + GLint bindToTextureRgba; + GLint bindToMipmapTexture; + GLint bindToTextureTargets; + GLint yInverted; +}; + +#define __GLX_MIN_CONFIG_PROPS 18 +#define __GLX_MAX_CONFIG_PROPS 500 +#define __GLX_EXT_CONFIG_PROPS 10 + +/* +** Since we send all non-core visual properties as token, value pairs, +** we require 2 words across the wire. In order to maintain backwards +** compatibility, we need to send the total number of words that the +** VisualConfigs are sent back in so old libraries can simply "ignore" +** the new properties. +*/ +#define __GLX_TOTAL_CONFIG \ + (__GLX_MIN_CONFIG_PROPS + 2 * __GLX_EXT_CONFIG_PROPS) + +extern GLint _gl_convert_from_x_visual_type(int visualType); + +extern int +glx_config_get(struct glx_config * mode, int attribute, int *value_return); +extern struct glx_config * +glx_config_create_list(unsigned count); +extern void +glx_config_destroy_list(struct glx_config *configs); +extern struct glx_config * +glx_config_find_visual(struct glx_config *configs, int vid); +extern struct glx_config * +glx_config_find_fbconfig(struct glx_config *configs, int fbid); + +#endif /* GLCONTEXTMODES_H */ + diff --git a/src/glx/glxcurrent.c b/src/glx/glxcurrent.c index 0bf61779c4a..e2569974c2f 100644 --- a/src/glx/glxcurrent.c +++ b/src/glx/glxcurrent.c @@ -45,7 +45,6 @@ #include "apple_glx_context.h" #else #include "glapi.h" -#include "indirect_init.h" #endif /* @@ -61,7 +60,7 @@ static GLubyte dummyBuffer[__GLX_BUFFER_LIMIT_SIZE]; ** gl and glx entry points are designed to operate as nop's when using ** the dummy context structure. */ -static __GLXcontext dummyContext = { +struct glx_context dummyContext = { &dummyBuffer[0], &dummyBuffer[0], &dummyBuffer[0], @@ -69,14 +68,6 @@ static __GLXcontext dummyContext = { sizeof(dummyBuffer), }; - -#ifndef GLX_USE_APPLEGL -/* -** All indirect rendering contexts will share the same indirect dispatch table. -*/ -static __GLapi *IndirectAPI = NULL; -#endif - /* * Current context management and locking */ @@ -98,7 +89,7 @@ __thread void *__glX_tls_Context __attribute__ ((tls_model("initial-exec"))) = &dummyContext; _X_HIDDEN void -__glXSetCurrentContext(__GLXcontext * c) +__glXSetCurrentContext(struct glx_context * c) { __glX_tls_Context = (c != NULL) ? c : &dummyContext; } @@ -133,13 +124,13 @@ init_thread_data(void) } _X_HIDDEN void -__glXSetCurrentContext(__GLXcontext * c) +__glXSetCurrentContext(struct glx_context * c) { pthread_once(&once_control, init_thread_data); pthread_setspecific(ContextTSD, c); } -_X_HIDDEN __GLXcontext * +_X_HIDDEN struct glx_context * __glXGetCurrentContext(void) { void *v; @@ -147,7 +138,7 @@ __glXGetCurrentContext(void) pthread_once(&once_control, init_thread_data); v = pthread_getspecific(ContextTSD); - return (v == NULL) ? &dummyContext : (__GLXcontext *) v; + return (v == NULL) ? &dummyContext : (struct glx_context *) v; } # endif /* defined( GLX_USE_TLS ) */ @@ -159,7 +150,7 @@ __glXGetCurrentContext(void) #else /* not thread safe */ -_X_HIDDEN __GLXcontext *__glXcurrentContext = &dummyContext; +_X_HIDDEN struct glx_context *__glXcurrentContext = &dummyContext; #endif @@ -176,145 +167,28 @@ __glXSetCurrentContextNull(void) #endif } - -/************************************************************************/ - -PUBLIC GLXContext +_X_EXPORT GLXContext glXGetCurrentContext(void) { - GLXContext cx = __glXGetCurrentContext(); + struct glx_context *cx = __glXGetCurrentContext(); if (cx == &dummyContext) { return NULL; } else { - return cx; + return (GLXContext) cx; } } -PUBLIC GLXDrawable +_X_EXPORT GLXDrawable glXGetCurrentDrawable(void) { - GLXContext gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); return gc->currentDrawable; } - -#ifndef GLX_USE_APPLEGL -/************************************************************************/ - -/** - * Sends a GLX protocol message to the specified display to make the context - * and the drawables current. - * - * \param dpy Display to send the message to. - * \param opcode Major opcode value for the display. - * \param gc_id Context tag for the context to be made current. - * \param draw Drawable ID for the "draw" drawable. - * \param read Drawable ID for the "read" drawable. - * \param reply Space to store the X-server's reply. - * - * \warning - * This function assumes that \c dpy is locked with \c LockDisplay on entry. - */ -static Bool -SendMakeCurrentRequest(Display * dpy, CARD8 opcode, - GLXContextID gc_id, GLXContextTag gc_tag, - GLXDrawable draw, GLXDrawable read, - xGLXMakeCurrentReply * reply) -{ - Bool ret; - - - LockDisplay(dpy); - - if (draw == read) { - xGLXMakeCurrentReq *req; - - GetReq(GLXMakeCurrent, req); - req->reqType = opcode; - req->glxCode = X_GLXMakeCurrent; - req->drawable = draw; - req->context = gc_id; - req->oldContextTag = gc_tag; - } - else { - __GLXdisplayPrivate *priv = __glXInitialize(dpy); - - /* If the server can support the GLX 1.3 version, we should - * perfer that. Not only that, some servers support GLX 1.3 but - * not the SGI extension. - */ - - if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { - xGLXMakeContextCurrentReq *req; - - GetReq(GLXMakeContextCurrent, req); - req->reqType = opcode; - req->glxCode = X_GLXMakeContextCurrent; - req->drawable = draw; - req->readdrawable = read; - req->context = gc_id; - req->oldContextTag = gc_tag; - } - else { - xGLXVendorPrivateWithReplyReq *vpreq; - xGLXMakeCurrentReadSGIReq *req; - - GetReqExtra(GLXVendorPrivateWithReply, - sz_xGLXMakeCurrentReadSGIReq - - sz_xGLXVendorPrivateWithReplyReq, vpreq); - req = (xGLXMakeCurrentReadSGIReq *) vpreq; - req->reqType = opcode; - req->glxCode = X_GLXVendorPrivateWithReply; - req->vendorCode = X_GLXvop_MakeCurrentReadSGI; - req->drawable = draw; - req->readable = read; - req->context = gc_id; - req->oldContextTag = gc_tag; - } - } - - ret = _XReply(dpy, (xReply *) reply, 0, False); - - UnlockDisplay(dpy); - SyncHandle(); - - return ret; -} - - -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) -static __GLXDRIdrawable * -FetchDRIDrawable(Display * dpy, GLXDrawable glxDrawable, GLXContext gc) -{ - __GLXdisplayPrivate *const priv = __glXInitialize(dpy); - __GLXDRIdrawable *pdraw; - __GLXscreenConfigs *psc; - - if (priv == NULL) - return NULL; - - psc = priv->screenConfigs[gc->screen]; - if (priv->drawHash == NULL) - return NULL; - - if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0) - return pdraw; - - pdraw = psc->driScreen->createDrawable(psc, glxDrawable, - glxDrawable, gc->mode); - if (__glxHashInsert(priv->drawHash, glxDrawable, pdraw)) { - (*pdraw->destroyDrawable) (pdraw); - return NULL; - } - - return pdraw; -} -#endif /* GLX_DIRECT_RENDERING */ - static void -__glXGenerateError(Display * dpy, GLXContext gc, XID resource, +__glXGenerateError(Display * dpy, struct glx_context *gc, XID resource, BYTE errorCode, CARD16 minorCode) { xError error; @@ -328,8 +202,6 @@ __glXGenerateError(Display * dpy, GLXContext gc, XID resource, _XError(dpy, &error); } -#endif /* GLX_USE_APPLEGL */ - /** * Make a particular context current. * @@ -337,28 +209,11 @@ __glXGenerateError(Display * dpy, GLXContext gc, XID resource, */ static Bool MakeContextCurrent(Display * dpy, GLXDrawable draw, - GLXDrawable read, GLXContext gc) + GLXDrawable read, GLXContext gc_user) { - const GLXContext oldGC = __glXGetCurrentContext(); -#ifdef GLX_USE_APPLEGL - bool error = apple_glx_make_current_context(dpy, - (oldGC && oldGC != &dummyContext) ? oldGC->driContext : NULL, - gc ? gc->driContext : NULL, draw); - - apple_glx_diagnostic("%s: error %s\n", __func__, error ? "YES" : "NO"); - if(error) - return GL_FALSE; -#else - xGLXMakeCurrentReply reply; - const CARD8 opcode = __glXSetupForCommand(dpy); - const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext)) - ? opcode : __glXSetupForCommand(oldGC->currentDpy); - Bool bindReturnValue; - __GLXattribute *state; - - if (!opcode || !oldOpcode) { - return GL_FALSE; - } + struct glx_context *gc = (struct glx_context *) gc_user; + struct glx_context *oldGC = __glXGetCurrentContext(); + int ret = Success; /* Make sure that the new context has a nonzero ID. In the request, * a zero context ID is used only to mean that we bind to no current @@ -386,169 +241,52 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw, return False; } -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - /* Bind the direct rendering context to the drawable */ - if (gc && gc->driContext) { - __GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc); - __GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc); - - if ((pdraw == NULL) || (pread == NULL)) { - __glXGenerateError(dpy, gc, (pdraw == NULL) ? draw : read, - GLXBadDrawable, X_GLXMakeContextCurrent); - return False; - } - - bindReturnValue = - (gc->driContext->bindContext) (gc, pdraw, pread); - } - else if (!gc && oldGC && oldGC->driContext) { - bindReturnValue = True; - } - else -#endif - { - /* Send a glXMakeCurrent request to bind the new context. */ - bindReturnValue = - SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None, - ((dpy != oldGC->currentDpy) - || oldGC->isDirect) - ? None : oldGC->currentContextTag, draw, read, - &reply); + if (oldGC != &dummyContext && oldGC != gc) { + oldGC->vtable->unbind(oldGC, gc); + oldGC->currentDpy = 0; + oldGC->currentDrawable = None; + oldGC->currentReadable = None; + oldGC->thread_id = 0; + if (oldGC->xid == None) + /* We are switching away from a context that was + * previously destroyed, so we need to free the memory + * for the old handle. + */ + oldGC->vtable->destroy(oldGC); } - - if (!bindReturnValue) { - return False; + if (gc) { + ret = gc->vtable->bind(gc, oldGC, draw, read); + gc->currentDpy = dpy; + gc->currentDrawable = draw; + gc->currentReadable = read; + gc->thread_id = _glthread_GetID(); + __glXSetCurrentContext(gc); + } else { + __glXSetCurrentContextNull(); } -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if ((dpy != oldGC->currentDpy || (gc && gc->driContext)) && - !oldGC->isDirect && oldGC != &dummyContext) { -#else - if ((dpy != oldGC->currentDpy) && oldGC != &dummyContext) { -#endif - xGLXMakeCurrentReply dummy_reply; - - /* We are either switching from one dpy to another and have to - * send a request to the previous dpy to unbind the previous - * context, or we are switching away from a indirect context to - * a direct context and have to send a request to the dpy to - * unbind the previous context. - */ - (void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None, - oldGC->currentContextTag, None, None, - &dummy_reply); - } -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - else if (oldGC->driContext && oldGC != gc) { - oldGC->driContext->unbindContext(oldGC); - } -#endif - -#endif /* GLX_USE_APPLEGL */ - - /* Update our notion of what is current */ - __glXLock(); - if (gc == oldGC) { - /* Even though the contexts are the same the drawable might have - * changed. Note that gc cannot be the dummy, and that oldGC - * cannot be NULL, therefore if they are the same, gc is not - * NULL and not the dummy. - */ - if(gc) { - gc->currentDrawable = draw; - gc->currentReadable = read; - } + if (ret) { + __glXGenerateError(dpy, gc, None, ret, X_GLXMakeContextCurrent); + return GL_FALSE; } - else { - if (oldGC != &dummyContext) { - /* Old current context is no longer current to anybody */ - oldGC->currentDpy = 0; - oldGC->currentDrawable = None; - oldGC->currentReadable = None; - oldGC->currentContextTag = 0; - oldGC->thread_id = 0; -#ifdef GLX_USE_APPLEGL - - /* - * At this point we should check if the context has been - * through glXDestroyContext, and redestroy it if so. - */ - if(oldGC->do_destroy) { - __glXUnlock(); - /* glXDestroyContext uses the same global lock. */ - glXDestroyContext(dpy, oldGC); - __glXLock(); -#else - if (oldGC->xid == None) { - /* We are switching away from a context that was - * previously destroyed, so we need to free the memory - * for the old handle. - */ -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - /* Destroy the old direct rendering context */ - if (oldGC->driContext) { - oldGC->driContext->destroyContext(oldGC); - oldGC->driContext = NULL; - } -#endif - __glXFreeContext(oldGC); -#endif /* GLX_USE_APPLEGL */ - } - } - if (gc) { - __glXSetCurrentContext(gc); - - gc->currentDpy = dpy; - gc->currentDrawable = draw; - gc->currentReadable = read; -#ifndef GLX_USE_APPLEGL - gc->thread_id = _glthread_GetID(); -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (!gc->driContext) { -#endif - if (!IndirectAPI) - IndirectAPI = __glXNewIndirectAPI(); - _glapi_set_dispatch(IndirectAPI); - - state = (__GLXattribute *) (gc->client_state_private); - - gc->currentContextTag = reply.contextTag; - if (state->array_state == NULL) { - (void) glGetString(GL_EXTENSIONS); - (void) glGetString(GL_VERSION); - __glXInitVertexArrayState(gc); - } -#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - } - else { - gc->currentContextTag = -1; - } -#endif -#endif /* GLX_USE_APPLEGL */ - } - else { - __glXSetCurrentContextNull(); - } - } - __glXUnlock(); return GL_TRUE; } -PUBLIC Bool +_X_EXPORT Bool glXMakeCurrent(Display * dpy, GLXDrawable draw, GLXContext gc) { return MakeContextCurrent(dpy, draw, draw, gc); } -PUBLIC +_X_EXPORT GLX_ALIAS(Bool, glXMakeCurrentReadSGI, (Display * dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), (dpy, d, r, ctx), MakeContextCurrent) -PUBLIC +_X_EXPORT GLX_ALIAS(Bool, glXMakeContextCurrent, (Display * dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx), (dpy, d, r, ctx), MakeContextCurrent) diff --git a/src/glx/glxext.c b/src/glx/glxext.c index 88e74c2a386..9e42d83c4d5 100644 --- a/src/glx/glxext.c +++ b/src/glx/glxext.c @@ -47,7 +47,6 @@ #include "apple_visual.h" #endif #include "glxextensions.h" -#include "glcontextmodes.h" #ifdef USE_XCB #include <X11/Xlib-xcb.h> @@ -57,7 +56,7 @@ #ifdef DEBUG -void __glXDumpDrawBuffer(__GLXcontext * ctx); +void __glXDumpDrawBuffer(struct glx_context * ctx); #endif /* @@ -69,7 +68,7 @@ _X_HIDDEN int __glXDebug = 0; /* Extension required boiler plate */ static const char __glXExtensionName[] = GLX_EXTENSION_NAME; -static __GLXdisplayPrivate *glx_displays; + static struct glx_display *glx_displays; static /* const */ char *error_list[] = { "GLXBadContext", @@ -96,13 +95,6 @@ static XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName, __GLX_NUMBER_ERRORS, error_list) -static int -__glXCloseDisplay(Display * dpy, XExtCodes * codes); -static Bool -__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire); -static Status -__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire); - /* * GLX events are a bit funky. We don't stuff the X event code into * our user exposed (via XNextEvent) structure. Instead we use the GLX @@ -115,7 +107,7 @@ __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire); static Bool __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire) { - __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy); + struct glx_display *glx_dpy = __glXInitialize(dpy); if (glx_dpy == NULL) return False; @@ -175,7 +167,7 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire) static Status __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire) { - __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy); + struct glx_display *glx_dpy = __glXInitialize(dpy); if (glx_dpy == NULL) return False; @@ -205,31 +197,30 @@ __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire) ** __glXScreenConfigs. */ static void -FreeScreenConfigs(__GLXdisplayPrivate * priv) +FreeScreenConfigs(struct glx_display * priv) { - __GLXscreenConfigs *psc; + struct glx_screen *psc; GLint i, screens; /* Free screen configuration information */ screens = ScreenCount(priv->dpy); for (i = 0; i < screens; i++) { - psc = priv->screenConfigs[i]; + psc = priv->screens[i]; if (psc->configs) { - _gl_context_modes_destroy(psc->configs); + glx_config_destroy_list(psc->configs); if (psc->effectiveGLXexts) Xfree(psc->effectiveGLXexts); psc->configs = NULL; /* NOTE: just for paranoia */ } if (psc->visuals) { - _gl_context_modes_destroy(psc->visuals); - psc->visuals = NULL; /* NOTE: just for paranoia */ + glx_config_destroy_list(psc->visuals); + psc->visuals = NULL; /* NOTE: just for paranoia */ } Xfree((char *) psc->serverGLXexts); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) if (psc->driScreen) { psc->driScreen->destroyScreen(psc); - psc->driScreen = NULL; } else { Xfree(psc); } @@ -237,34 +228,19 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv) Xfree(psc); #endif } - XFree((char *) priv->screenConfigs); - priv->screenConfigs = NULL; + XFree((char *) priv->screens); + priv->screens = NULL; } -/* -** Release the private memory referred to in a display private -** structure. The caller will free the extension structure. -*/ -static int -__glXCloseDisplay(Display * dpy, XExtCodes * codes) +static void +glx_display_free(struct glx_display *priv) { - __GLXdisplayPrivate *priv, **prev; - GLXContext gc; - - _XLockMutex(_Xglobal_lock); - prev = &glx_displays; - for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) { - if (priv->dpy == dpy) { - (*prev)->next = priv->next; - break; - } - } - _XUnlockMutex(_Xglobal_lock); + struct glx_context *gc; gc = __glXGetCurrentContext(); - if (dpy == gc->currentDpy) { + if (priv->dpy == gc->currentDpy) { + gc->vtable->destroy(gc); __glXSetCurrentContextNull(); - __glXFreeContext(gc); } FreeScreenConfigs(priv); @@ -291,6 +267,24 @@ __glXCloseDisplay(Display * dpy, XExtCodes * codes) #endif Xfree((char *) priv); +} + +static int +__glXCloseDisplay(Display * dpy, XExtCodes * codes) +{ + struct glx_display *priv, **prev; + + _XLockMutex(_Xglobal_lock); + prev = &glx_displays; + for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) { + if (priv->dpy == dpy) { + (*prev) = priv->next; + break; + } + } + _XUnlockMutex(_Xglobal_lock); + + glx_display_free(priv); return 1; } @@ -357,12 +351,27 @@ enum { }; +static GLint +convert_from_x_visual_type(int visualType) +{ + static const int glx_visual_types[] = { + GLX_STATIC_GRAY, GLX_GRAY_SCALE, + GLX_STATIC_COLOR, GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, GLX_DIRECT_COLOR + }; + + if (visualType < ARRAY_SIZE(glx_visual_types)) + return glx_visual_types[visualType]; + + return GLX_NONE; +} + /* * getVisualConfigs uses the !tagged_only path. * getFBConfigs uses the tagged_only path. */ _X_HIDDEN void -__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count, +__glXInitializeVisualConfigFromTags(struct glx_config * config, int count, const INT32 * bp, Bool tagged_only, Bool fbconfig_style_tags) { @@ -372,7 +381,7 @@ __glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count, /* Copy in the first set of properties */ config->visualID = *bp++; - config->visualType = _gl_convert_from_x_visual_type(*bp++); + config->visualType = convert_from_x_visual_type(*bp++); config->rgbMode = *bp++; @@ -581,22 +590,15 @@ __glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count, config->renderType = (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; - - config->haveAccumBuffer = ((config->accumRedBits + - config->accumGreenBits + - config->accumBlueBits + - config->accumAlphaBits) > 0); - config->haveDepthBuffer = (config->depthBits > 0); - config->haveStencilBuffer = (config->stencilBits > 0); } -static __GLcontextModes * +static struct glx_config * createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, int screen, GLboolean tagged_only) { INT32 buf[__GLX_TOTAL_CONFIG], *props; unsigned prop_size; - __GLcontextModes *modes, *m; + struct glx_config *modes, *m; int i; if (nprops == 0) @@ -609,7 +611,7 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, return NULL; /* Allocate memory for our config structure */ - modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes)); + modes = glx_config_create_list(nvisuals); if (!modes) return NULL; @@ -647,8 +649,8 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops, } static GLboolean -getVisualConfigs(__GLXscreenConfigs *psc, - __GLXdisplayPrivate *priv, int screen) +getVisualConfigs(struct glx_screen *psc, + struct glx_display *priv, int screen) { xGLXGetVisualConfigsReq *req; xGLXGetVisualConfigsReply reply; @@ -676,7 +678,7 @@ getVisualConfigs(__GLXscreenConfigs *psc, } static GLboolean -getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen) + getFBConfigs(struct glx_screen *psc, struct glx_display *priv, int screen) { xGLXGetFBConfigsReq *fb_req; xGLXGetFBConfigsSGIXReq *sgi_req; @@ -723,8 +725,8 @@ getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen) } _X_HIDDEN Bool -glx_screen_init(__GLXscreenConfigs *psc, - int screen, __GLXdisplayPrivate * priv) +glx_screen_init(struct glx_screen *psc, + int screen, struct glx_display * priv) { /* Initialize per screen dynamic client GLX extensions */ psc->ext_list_first_time = GL_TRUE; @@ -738,33 +740,22 @@ glx_screen_init(__GLXscreenConfigs *psc, return GL_TRUE; } -static __GLXscreenConfigs * -createIndirectScreen() -{ - __GLXscreenConfigs *psc; - - psc = Xmalloc(sizeof *psc); - memset(psc, 0, sizeof *psc); - - return psc; -} - /* ** Allocate the memory for the per screen configs for each screen. ** If that works then fetch the per screen configs data. */ static Bool -AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) +AllocAndFetchScreenConfigs(Display * dpy, struct glx_display * priv) { - __GLXscreenConfigs *psc; + struct glx_screen *psc; GLint i, screens; /* ** First allocate memory for the array of per screen configs. */ screens = ScreenCount(dpy); - priv->screenConfigs = Xmalloc(screens * sizeof *priv->screenConfigs); - if (!priv->screenConfigs) + priv->screens = Xmalloc(screens * sizeof *priv->screens); + if (!priv->screens) return GL_FALSE; priv->serverGLXversion = @@ -775,6 +766,7 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) } for (i = 0; i < screens; i++, psc++) { + psc = NULL; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) if (priv->dri2Display) psc = (*priv->dri2Display->createScreen) (i, priv); @@ -782,10 +774,14 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) psc = (*priv->driDisplay->createScreen) (i, priv); if (psc == NULL && priv->driswDisplay) psc = (*priv->driswDisplay->createScreen) (i, priv); - if (psc == NULL) - psc = createIndirectScreen (i, priv); #endif - priv->screenConfigs[i] = psc; +#if defined(GLX_USE_APPLEGL) + if (psc == NULL && priv->appleglDisplay) + psc = (*priv->appleglDisplay->createScreen) (i, priv); +#endif + if (psc == NULL) + psc = indirect_create_screen(i, priv); + priv->screens[i] = psc; } SyncHandle(); return GL_TRUE; @@ -794,10 +790,10 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv) /* ** Initialize the client side extension code. */ -_X_HIDDEN __GLXdisplayPrivate * + _X_HIDDEN struct glx_display * __glXInitialize(Display * dpy) { - __GLXdisplayPrivate *dpyPriv; + struct glx_display *dpyPriv, *d; #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) Bool glx_direct, glx_accel; #endif @@ -812,6 +808,9 @@ __glXInitialize(Display * dpy) } } + /* Drop the lock while we create the display private. */ + _XUnlockMutex(_Xglobal_lock); + dpyPriv = Xcalloc(1, sizeof *dpyPriv); if (!dpyPriv) return NULL; @@ -864,7 +863,7 @@ __glXInitialize(Display * dpy) #endif #ifdef GLX_USE_APPLEGL - if (apple_init_glx(dpy)) { + if (!applegl_create_display(dpyPriv)) { Xfree(dpyPriv); return NULL; } @@ -877,6 +876,18 @@ __glXInitialize(Display * dpy) if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1) __glXClientInfo(dpy, dpyPriv->majorOpcode); + /* Grab the lock again and add the dispay private, unless somebody + * beat us to initializing on this display in the meantime. */ + _XLockMutex(_Xglobal_lock); + + for (d = glx_displays; d; d = d->next) { + if (d->dpy == dpy) { + _XUnlockMutex(_Xglobal_lock); + glx_display_free(dpyPriv); + return d; + } + } + dpyPriv->next = glx_displays; glx_displays = dpyPriv; @@ -892,8 +903,8 @@ __glXInitialize(Display * dpy) _X_HIDDEN CARD8 __glXSetupForCommand(Display * dpy) { - GLXContext gc; - __GLXdisplayPrivate *priv; + struct glx_context *gc; + struct glx_display *priv; /* If this thread has a current context, flush its rendering commands */ gc = __glXGetCurrentContext(); @@ -932,7 +943,7 @@ __glXSetupForCommand(Display * dpy) * \c pc parameter. */ _X_HIDDEN GLubyte * -__glXFlushRenderBuffer(__GLXcontext * ctx, GLubyte * pc) +__glXFlushRenderBuffer(struct glx_context * ctx, GLubyte * pc) { Display *const dpy = ctx->currentDpy; #ifdef USE_XCB @@ -983,7 +994,7 @@ __glXFlushRenderBuffer(__GLXcontext * ctx, GLubyte * pc) * \param dataLen Size, in bytes, of the command data. */ _X_HIDDEN void -__glXSendLargeChunk(__GLXcontext * gc, GLint requestNumber, +__glXSendLargeChunk(struct glx_context * gc, GLint requestNumber, GLint totalRequests, const GLvoid * data, GLint dataLen) { Display *dpy = gc->currentDpy; @@ -1032,7 +1043,7 @@ __glXSendLargeChunk(__GLXcontext * gc, GLint requestNumber, * \param dataLen Size, in bytes, of the command data. */ _X_HIDDEN void -__glXSendLargeCommand(__GLXcontext * ctx, +__glXSendLargeCommand(struct glx_context * ctx, const GLvoid * header, GLint headerLen, const GLvoid * data, GLint dataLen) { @@ -1074,7 +1085,7 @@ __glXSendLargeCommand(__GLXcontext * ctx, #ifdef DEBUG _X_HIDDEN void -__glXDumpDrawBuffer(__GLXcontext * ctx) +__glXDumpDrawBuffer(struct glx_context * ctx) { GLubyte *p = ctx->buf; GLubyte *end = ctx->pc; diff --git a/src/glx/glxextensions.c b/src/glx/glxextensions.c index 4eb6a5536ab..23161ef49a1 100644 --- a/src/glx/glxextensions.c +++ b/src/glx/glxextensions.c @@ -312,7 +312,7 @@ static const unsigned gl_minor = 4; static const char *__glXGLXClientExtensions = NULL; static void __glXExtensionsCtr(void); -static void __glXExtensionsCtrScreen(__GLXscreenConfigs * psc); +static void __glXExtensionsCtrScreen(struct glx_screen * psc); static void __glXProcessServerString(const struct extension_info *ext, const char *server_string, unsigned char *server_support); @@ -396,7 +396,7 @@ __glXProcessServerString(const struct extension_info *ext, } void -__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name) +__glXEnableDirectExtension(struct glx_screen * psc, const char *name) { __glXExtensionsCtr(); __glXExtensionsCtrScreen(psc); @@ -474,7 +474,7 @@ __glXExtensionsCtr(void) */ static void -__glXExtensionsCtrScreen(__GLXscreenConfigs * psc) +__glXExtensionsCtrScreen(struct glx_screen * psc) { if (psc->ext_list_first_time) { psc->ext_list_first_time = GL_FALSE; @@ -494,7 +494,7 @@ __glXExtensionsCtrScreen(__GLXscreenConfigs * psc) * \c NULL, then \c GL_FALSE is returned. */ GLboolean -__glXExtensionBitIsEnabled(__GLXscreenConfigs * psc, unsigned bit) +__glXExtensionBitIsEnabled(struct glx_screen * psc, unsigned bit) { GLboolean enabled = GL_FALSE; @@ -513,7 +513,7 @@ __glXExtensionBitIsEnabled(__GLXscreenConfigs * psc, unsigned bit) * */ GLboolean -__glExtensionBitIsEnabled(const __GLXcontext * gc, unsigned bit) +__glExtensionBitIsEnabled(struct glx_context *gc, unsigned bit) { GLboolean enabled = GL_FALSE; @@ -594,7 +594,7 @@ __glXGetClientExtensions(void) */ void -__glXCalculateUsableExtensions(__GLXscreenConfigs * psc, +__glXCalculateUsableExtensions(struct glx_screen * psc, GLboolean display_is_direct_capable, int minor_version) { @@ -675,7 +675,7 @@ __glXCalculateUsableExtensions(__GLXscreenConfigs * psc, */ void -__glXCalculateUsableGLExtensions(__GLXcontext * gc, +__glXCalculateUsableGLExtensions(struct glx_context * gc, const char *server_string, int major_version, int minor_version) { diff --git a/src/glx/glxextensions.h b/src/glx/glxextensions.h index 4f1b6619d65..a11fe88ffc9 100644 --- a/src/glx/glxextensions.h +++ b/src/glx/glxextensions.h @@ -234,30 +234,29 @@ enum #define __GL_EXT_BYTES ((__NUM_GL_EXTS + 7) / 8) -struct __GLXscreenConfigsRec; -struct __GLXcontextRec; +struct glx_screen; +struct glx_context; -extern GLboolean __glXExtensionBitIsEnabled(struct __GLXscreenConfigsRec *psc, +extern GLboolean __glXExtensionBitIsEnabled(struct glx_screen *psc, unsigned bit); extern const char *__glXGetClientExtensions(void); -extern void __glXCalculateUsableExtensions(struct __GLXscreenConfigsRec *psc, +extern void __glXCalculateUsableExtensions(struct glx_screen *psc, GLboolean display_is_direct_capable, int server_minor_version); -extern void __glXCalculateUsableGLExtensions(struct __GLXcontextRec *gc, +extern void __glXCalculateUsableGLExtensions(struct glx_context *gc, const char *server_string, int major_version, int minor_version); extern void __glXGetGLVersion(int *major_version, int *minor_version); extern char *__glXGetClientGLExtensionString(void); -extern GLboolean __glExtensionBitIsEnabled(const struct __GLXcontextRec *gc, +extern GLboolean __glExtensionBitIsEnabled(struct glx_context *gc, unsigned bit); extern void -__glXEnableDirectExtension(struct __GLXscreenConfigsRec *psc, - const char *name); +__glXEnableDirectExtension(struct glx_screen *psc, const char *name); /* Source-level backwards compatibility with old drivers. They won't * find the respective functions, though. diff --git a/src/glx/indirect.c b/src/glx/indirect.c index 172727860e8..c0fff6c4dcf 100644 --- a/src/glx/indirect.c +++ b/src/glx/indirect.c @@ -91,7 +91,7 @@ __glXReadReply(Display * dpy, size_t size, void *dest, } NOINLINE void -__glXReadPixelReply(Display * dpy, __GLXcontext * gc, unsigned max_dim, +__glXReadPixelReply(Display * dpy, struct glx_context * gc, unsigned max_dim, GLint width, GLint height, GLint depth, GLenum format, GLenum type, void *dest, GLboolean dimensions_in_reply) { @@ -138,7 +138,7 @@ __glXReadPixelReply(Display * dpy, __GLXcontext * gc, unsigned max_dim, #define X_GLXSingle 0 NOINLINE FASTCALL GLubyte * -__glXSetupSingleRequest(__GLXcontext * gc, GLint sop, GLint cmdlen) +__glXSetupSingleRequest(struct glx_context * gc, GLint sop, GLint cmdlen) { xGLXSingleReq *req; Display *const dpy = gc->currentDpy; @@ -153,7 +153,7 @@ __glXSetupSingleRequest(__GLXcontext * gc, GLint sop, GLint cmdlen) } NOINLINE FASTCALL GLubyte * -__glXSetupVendorRequest(__GLXcontext * gc, GLint code, GLint vop, +__glXSetupVendorRequest(struct glx_context * gc, GLint code, GLint vop, GLint cmdlen) { xGLXVendorPrivateReq *req; @@ -185,7 +185,7 @@ const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; static FASTCALL NOINLINE void generic_3_byte(GLint rop, const void *ptr) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, rop, cmdlen); @@ -199,7 +199,7 @@ generic_3_byte(GLint rop, const void *ptr) static FASTCALL NOINLINE void generic_4_byte(GLint rop, const void *ptr) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, rop, cmdlen); @@ -213,7 +213,7 @@ generic_4_byte(GLint rop, const void *ptr) static FASTCALL NOINLINE void generic_6_byte(GLint rop, const void *ptr) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, rop, cmdlen); @@ -227,7 +227,7 @@ generic_6_byte(GLint rop, const void *ptr) static FASTCALL NOINLINE void generic_8_byte(GLint rop, const void *ptr) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, rop, cmdlen); @@ -241,7 +241,7 @@ generic_8_byte(GLint rop, const void *ptr) static FASTCALL NOINLINE void generic_12_byte(GLint rop, const void *ptr) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, rop, cmdlen); @@ -255,7 +255,7 @@ generic_12_byte(GLint rop, const void *ptr) static FASTCALL NOINLINE void generic_16_byte(GLint rop, const void *ptr) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, rop, cmdlen); @@ -269,7 +269,7 @@ generic_16_byte(GLint rop, const void *ptr) static FASTCALL NOINLINE void generic_24_byte(GLint rop, const void *ptr) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, rop, cmdlen); @@ -283,7 +283,7 @@ generic_24_byte(GLint rop, const void *ptr) static FASTCALL NOINLINE void generic_32_byte(GLint rop, const void *ptr) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 36; emit_header(gc->pc, rop, cmdlen); @@ -298,7 +298,7 @@ generic_32_byte(GLint rop, const void *ptr) void __indirect_glNewList(GLuint list, GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -324,7 +324,7 @@ __indirect_glNewList(GLuint list, GLenum mode) void __indirect_glEndList(void) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 0; @@ -347,7 +347,7 @@ __indirect_glEndList(void) void __indirect_glCallList(GLuint list) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_CallList, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&list), 4); @@ -361,7 +361,7 @@ __indirect_glCallList(GLuint list) void __indirect_glCallLists(GLsizei n, GLenum type, const GLvoid * lists) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glCallLists_size(type); const GLuint cmdlen = 12 + __GLX_PAD((compsize * n)); if (n < 0) { @@ -399,7 +399,7 @@ __indirect_glCallLists(GLsizei n, GLenum type, const GLvoid * lists) void __indirect_glDeleteLists(GLuint list, GLsizei range) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -425,7 +425,7 @@ __indirect_glDeleteLists(GLuint list, GLsizei range) GLuint __indirect_glGenLists(GLsizei range) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLuint retval = (GLuint) 0; #ifndef USE_XCB @@ -458,7 +458,7 @@ __indirect_glGenLists(GLsizei range) void __indirect_glListBase(GLuint base) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_ListBase, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&base), 4); @@ -472,7 +472,7 @@ __indirect_glListBase(GLuint base) void __indirect_glBegin(GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Begin, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mode), 4); @@ -488,7 +488,7 @@ __indirect_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = (bitmap != NULL) ? __glImageSize(width, height, 1, GL_COLOR_INDEX, GL_BITMAP, 0) : 0; @@ -539,7 +539,7 @@ __indirect_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, void __indirect_glColor3b(GLbyte red, GLbyte green, GLbyte blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Color3bv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 1); @@ -562,7 +562,7 @@ __indirect_glColor3bv(const GLbyte *v) void __indirect_glColor3d(GLdouble red, GLdouble green, GLdouble blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_Color3dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 8); @@ -585,7 +585,7 @@ __indirect_glColor3dv(const GLdouble * v) void __indirect_glColor3f(GLfloat red, GLfloat green, GLfloat blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Color3fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -608,7 +608,7 @@ __indirect_glColor3fv(const GLfloat * v) void __indirect_glColor3i(GLint red, GLint green, GLint blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Color3iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -631,7 +631,7 @@ __indirect_glColor3iv(const GLint * v) void __indirect_glColor3s(GLshort red, GLshort green, GLshort blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Color3sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 2); @@ -654,7 +654,7 @@ __indirect_glColor3sv(const GLshort * v) void __indirect_glColor3ub(GLubyte red, GLubyte green, GLubyte blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Color3ubv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 1); @@ -677,7 +677,7 @@ __indirect_glColor3ubv(const GLubyte *v) void __indirect_glColor3ui(GLuint red, GLuint green, GLuint blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Color3uiv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -700,7 +700,7 @@ __indirect_glColor3uiv(const GLuint * v) void __indirect_glColor3us(GLushort red, GLushort green, GLushort blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Color3usv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 2); @@ -723,7 +723,7 @@ __indirect_glColor3usv(const GLushort * v) void __indirect_glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Color4bv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 1); @@ -748,7 +748,7 @@ void __indirect_glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 36; emit_header(gc->pc, X_GLrop_Color4dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 8); @@ -772,7 +772,7 @@ __indirect_glColor4dv(const GLdouble * v) void __indirect_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Color4fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -796,7 +796,7 @@ __indirect_glColor4fv(const GLfloat * v) void __indirect_glColor4i(GLint red, GLint green, GLint blue, GLint alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Color4iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -820,7 +820,7 @@ __indirect_glColor4iv(const GLint * v) void __indirect_glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Color4sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 2); @@ -844,7 +844,7 @@ __indirect_glColor4sv(const GLshort * v) void __indirect_glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Color4ubv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 1); @@ -868,7 +868,7 @@ __indirect_glColor4ubv(const GLubyte *v) void __indirect_glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Color4uiv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -893,7 +893,7 @@ void __indirect_glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Color4usv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 2); @@ -917,7 +917,7 @@ __indirect_glColor4usv(const GLushort * v) void __indirect_glEdgeFlag(GLboolean flag) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_EdgeFlagv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&flag), 1); @@ -931,7 +931,7 @@ __indirect_glEdgeFlag(GLboolean flag) void __indirect_glEdgeFlagv(const GLboolean * flag) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_EdgeFlagv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (flag), 1); @@ -945,7 +945,7 @@ __indirect_glEdgeFlagv(const GLboolean * flag) void __indirect_glEnd(void) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 4; emit_header(gc->pc, X_GLrop_End, cmdlen); gc->pc += cmdlen; @@ -958,7 +958,7 @@ __indirect_glEnd(void) void __indirect_glIndexd(GLdouble c) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Indexdv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&c), 8); @@ -979,7 +979,7 @@ __indirect_glIndexdv(const GLdouble * c) void __indirect_glIndexf(GLfloat c) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Indexfv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&c), 4); @@ -1000,7 +1000,7 @@ __indirect_glIndexfv(const GLfloat * c) void __indirect_glIndexi(GLint c) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Indexiv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&c), 4); @@ -1021,7 +1021,7 @@ __indirect_glIndexiv(const GLint * c) void __indirect_glIndexs(GLshort c) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Indexsv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&c), 2); @@ -1035,7 +1035,7 @@ __indirect_glIndexs(GLshort c) void __indirect_glIndexsv(const GLshort * c) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Indexsv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (c), 2); @@ -1049,7 +1049,7 @@ __indirect_glIndexsv(const GLshort * c) void __indirect_glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Normal3bv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&nx), 1); @@ -1072,7 +1072,7 @@ __indirect_glNormal3bv(const GLbyte *v) void __indirect_glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_Normal3dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&nx), 8); @@ -1095,7 +1095,7 @@ __indirect_glNormal3dv(const GLdouble * v) void __indirect_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Normal3fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&nx), 4); @@ -1118,7 +1118,7 @@ __indirect_glNormal3fv(const GLfloat * v) void __indirect_glNormal3i(GLint nx, GLint ny, GLint nz) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Normal3iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&nx), 4); @@ -1141,7 +1141,7 @@ __indirect_glNormal3iv(const GLint * v) void __indirect_glNormal3s(GLshort nx, GLshort ny, GLshort nz) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Normal3sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&nx), 2); @@ -1164,7 +1164,7 @@ __indirect_glNormal3sv(const GLshort * v) void __indirect_glRasterPos2d(GLdouble x, GLdouble y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_RasterPos2dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8); @@ -1186,7 +1186,7 @@ __indirect_glRasterPos2dv(const GLdouble * v) void __indirect_glRasterPos2f(GLfloat x, GLfloat y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_RasterPos2fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -1208,7 +1208,7 @@ __indirect_glRasterPos2fv(const GLfloat * v) void __indirect_glRasterPos2i(GLint x, GLint y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_RasterPos2iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -1230,7 +1230,7 @@ __indirect_glRasterPos2iv(const GLint * v) void __indirect_glRasterPos2s(GLshort x, GLshort y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_RasterPos2sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 2); @@ -1252,7 +1252,7 @@ __indirect_glRasterPos2sv(const GLshort * v) void __indirect_glRasterPos3d(GLdouble x, GLdouble y, GLdouble z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_RasterPos3dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8); @@ -1275,7 +1275,7 @@ __indirect_glRasterPos3dv(const GLdouble * v) void __indirect_glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_RasterPos3fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -1298,7 +1298,7 @@ __indirect_glRasterPos3fv(const GLfloat * v) void __indirect_glRasterPos3i(GLint x, GLint y, GLint z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_RasterPos3iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -1321,7 +1321,7 @@ __indirect_glRasterPos3iv(const GLint * v) void __indirect_glRasterPos3s(GLshort x, GLshort y, GLshort z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_RasterPos3sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 2); @@ -1344,7 +1344,7 @@ __indirect_glRasterPos3sv(const GLshort * v) void __indirect_glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 36; emit_header(gc->pc, X_GLrop_RasterPos4dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8); @@ -1368,7 +1368,7 @@ __indirect_glRasterPos4dv(const GLdouble * v) void __indirect_glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_RasterPos4fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -1392,7 +1392,7 @@ __indirect_glRasterPos4fv(const GLfloat * v) void __indirect_glRasterPos4i(GLint x, GLint y, GLint z, GLint w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_RasterPos4iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -1416,7 +1416,7 @@ __indirect_glRasterPos4iv(const GLint * v) void __indirect_glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_RasterPos4sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 2); @@ -1440,7 +1440,7 @@ __indirect_glRasterPos4sv(const GLshort * v) void __indirect_glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 36; emit_header(gc->pc, X_GLrop_Rectdv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x1), 8); @@ -1457,7 +1457,7 @@ __indirect_glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) void __indirect_glRectdv(const GLdouble * v1, const GLdouble * v2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 36; emit_header(gc->pc, X_GLrop_Rectdv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (v1), 16); @@ -1472,7 +1472,7 @@ __indirect_glRectdv(const GLdouble * v1, const GLdouble * v2) void __indirect_glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Rectfv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x1), 4); @@ -1489,7 +1489,7 @@ __indirect_glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) void __indirect_glRectfv(const GLfloat * v1, const GLfloat * v2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Rectfv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (v1), 8); @@ -1504,7 +1504,7 @@ __indirect_glRectfv(const GLfloat * v1, const GLfloat * v2) void __indirect_glRecti(GLint x1, GLint y1, GLint x2, GLint y2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Rectiv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x1), 4); @@ -1521,7 +1521,7 @@ __indirect_glRecti(GLint x1, GLint y1, GLint x2, GLint y2) void __indirect_glRectiv(const GLint * v1, const GLint * v2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Rectiv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (v1), 8); @@ -1536,7 +1536,7 @@ __indirect_glRectiv(const GLint * v1, const GLint * v2) void __indirect_glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Rectsv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x1), 2); @@ -1553,7 +1553,7 @@ __indirect_glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2) void __indirect_glRectsv(const GLshort * v1, const GLshort * v2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Rectsv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (v1), 4); @@ -1568,7 +1568,7 @@ __indirect_glRectsv(const GLshort * v1, const GLshort * v2) void __indirect_glTexCoord1d(GLdouble s) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_TexCoord1dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 8); @@ -1589,7 +1589,7 @@ __indirect_glTexCoord1dv(const GLdouble * v) void __indirect_glTexCoord1f(GLfloat s) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_TexCoord1fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 4); @@ -1610,7 +1610,7 @@ __indirect_glTexCoord1fv(const GLfloat * v) void __indirect_glTexCoord1i(GLint s) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_TexCoord1iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 4); @@ -1631,7 +1631,7 @@ __indirect_glTexCoord1iv(const GLint * v) void __indirect_glTexCoord1s(GLshort s) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_TexCoord1sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 2); @@ -1645,7 +1645,7 @@ __indirect_glTexCoord1s(GLshort s) void __indirect_glTexCoord1sv(const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_TexCoord1sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (v), 2); @@ -1659,7 +1659,7 @@ __indirect_glTexCoord1sv(const GLshort * v) void __indirect_glTexCoord2d(GLdouble s, GLdouble t) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_TexCoord2dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 8); @@ -1681,7 +1681,7 @@ __indirect_glTexCoord2dv(const GLdouble * v) void __indirect_glTexCoord2f(GLfloat s, GLfloat t) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_TexCoord2fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 4); @@ -1703,7 +1703,7 @@ __indirect_glTexCoord2fv(const GLfloat * v) void __indirect_glTexCoord2i(GLint s, GLint t) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_TexCoord2iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 4); @@ -1725,7 +1725,7 @@ __indirect_glTexCoord2iv(const GLint * v) void __indirect_glTexCoord2s(GLshort s, GLshort t) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_TexCoord2sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 2); @@ -1747,7 +1747,7 @@ __indirect_glTexCoord2sv(const GLshort * v) void __indirect_glTexCoord3d(GLdouble s, GLdouble t, GLdouble r) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_TexCoord3dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 8); @@ -1770,7 +1770,7 @@ __indirect_glTexCoord3dv(const GLdouble * v) void __indirect_glTexCoord3f(GLfloat s, GLfloat t, GLfloat r) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_TexCoord3fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 4); @@ -1793,7 +1793,7 @@ __indirect_glTexCoord3fv(const GLfloat * v) void __indirect_glTexCoord3i(GLint s, GLint t, GLint r) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_TexCoord3iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 4); @@ -1816,7 +1816,7 @@ __indirect_glTexCoord3iv(const GLint * v) void __indirect_glTexCoord3s(GLshort s, GLshort t, GLshort r) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_TexCoord3sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 2); @@ -1839,7 +1839,7 @@ __indirect_glTexCoord3sv(const GLshort * v) void __indirect_glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 36; emit_header(gc->pc, X_GLrop_TexCoord4dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 8); @@ -1863,7 +1863,7 @@ __indirect_glTexCoord4dv(const GLdouble * v) void __indirect_glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_TexCoord4fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 4); @@ -1887,7 +1887,7 @@ __indirect_glTexCoord4fv(const GLfloat * v) void __indirect_glTexCoord4i(GLint s, GLint t, GLint r, GLint q) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_TexCoord4iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 4); @@ -1911,7 +1911,7 @@ __indirect_glTexCoord4iv(const GLint * v) void __indirect_glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_TexCoord4sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 2); @@ -1935,7 +1935,7 @@ __indirect_glTexCoord4sv(const GLshort * v) void __indirect_glVertex2d(GLdouble x, GLdouble y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Vertex2dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8); @@ -1957,7 +1957,7 @@ __indirect_glVertex2dv(const GLdouble * v) void __indirect_glVertex2f(GLfloat x, GLfloat y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Vertex2fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -1979,7 +1979,7 @@ __indirect_glVertex2fv(const GLfloat * v) void __indirect_glVertex2i(GLint x, GLint y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Vertex2iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -2001,7 +2001,7 @@ __indirect_glVertex2iv(const GLint * v) void __indirect_glVertex2s(GLshort x, GLshort y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Vertex2sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 2); @@ -2023,7 +2023,7 @@ __indirect_glVertex2sv(const GLshort * v) void __indirect_glVertex3d(GLdouble x, GLdouble y, GLdouble z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_Vertex3dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8); @@ -2046,7 +2046,7 @@ __indirect_glVertex3dv(const GLdouble * v) void __indirect_glVertex3f(GLfloat x, GLfloat y, GLfloat z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Vertex3fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -2069,7 +2069,7 @@ __indirect_glVertex3fv(const GLfloat * v) void __indirect_glVertex3i(GLint x, GLint y, GLint z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Vertex3iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -2092,7 +2092,7 @@ __indirect_glVertex3iv(const GLint * v) void __indirect_glVertex3s(GLshort x, GLshort y, GLshort z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Vertex3sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 2); @@ -2115,7 +2115,7 @@ __indirect_glVertex3sv(const GLshort * v) void __indirect_glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 36; emit_header(gc->pc, X_GLrop_Vertex4dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8); @@ -2139,7 +2139,7 @@ __indirect_glVertex4dv(const GLdouble * v) void __indirect_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Vertex4fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -2163,7 +2163,7 @@ __indirect_glVertex4fv(const GLfloat * v) void __indirect_glVertex4i(GLint x, GLint y, GLint z, GLint w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Vertex4iv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -2187,7 +2187,7 @@ __indirect_glVertex4iv(const GLint * v) void __indirect_glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Vertex4sv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 2); @@ -2211,7 +2211,7 @@ __indirect_glVertex4sv(const GLshort * v) void __indirect_glClipPlane(GLenum plane, const GLdouble * equation) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 40; emit_header(gc->pc, X_GLrop_ClipPlane, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (equation), 32); @@ -2226,7 +2226,7 @@ __indirect_glClipPlane(GLenum plane, const GLdouble * equation) void __indirect_glColorMaterial(GLenum face, GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_ColorMaterial, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&face), 4); @@ -2241,7 +2241,7 @@ __indirect_glColorMaterial(GLenum face, GLenum mode) void __indirect_glCullFace(GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_CullFace, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mode), 4); @@ -2255,7 +2255,7 @@ __indirect_glCullFace(GLenum mode) void __indirect_glFogf(GLenum pname, GLfloat param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Fogf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&pname), 4); @@ -2270,7 +2270,7 @@ __indirect_glFogf(GLenum pname, GLfloat param) void __indirect_glFogfv(GLenum pname, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glFogfv_size(pname); const GLuint cmdlen = 8 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_Fogfv, cmdlen); @@ -2286,7 +2286,7 @@ __indirect_glFogfv(GLenum pname, const GLfloat * params) void __indirect_glFogi(GLenum pname, GLint param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Fogi, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&pname), 4); @@ -2301,7 +2301,7 @@ __indirect_glFogi(GLenum pname, GLint param) void __indirect_glFogiv(GLenum pname, const GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glFogiv_size(pname); const GLuint cmdlen = 8 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_Fogiv, cmdlen); @@ -2317,7 +2317,7 @@ __indirect_glFogiv(GLenum pname, const GLint * params) void __indirect_glFrontFace(GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_FrontFace, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mode), 4); @@ -2331,7 +2331,7 @@ __indirect_glFrontFace(GLenum mode) void __indirect_glHint(GLenum target, GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Hint, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -2346,7 +2346,7 @@ __indirect_glHint(GLenum target, GLenum mode) void __indirect_glLightf(GLenum light, GLenum pname, GLfloat param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Lightf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&light), 4); @@ -2362,7 +2362,7 @@ __indirect_glLightf(GLenum light, GLenum pname, GLfloat param) void __indirect_glLightfv(GLenum light, GLenum pname, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glLightfv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_Lightfv, cmdlen); @@ -2379,7 +2379,7 @@ __indirect_glLightfv(GLenum light, GLenum pname, const GLfloat * params) void __indirect_glLighti(GLenum light, GLenum pname, GLint param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Lighti, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&light), 4); @@ -2395,7 +2395,7 @@ __indirect_glLighti(GLenum light, GLenum pname, GLint param) void __indirect_glLightiv(GLenum light, GLenum pname, const GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glLightiv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_Lightiv, cmdlen); @@ -2412,7 +2412,7 @@ __indirect_glLightiv(GLenum light, GLenum pname, const GLint * params) void __indirect_glLightModelf(GLenum pname, GLfloat param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_LightModelf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&pname), 4); @@ -2427,7 +2427,7 @@ __indirect_glLightModelf(GLenum pname, GLfloat param) void __indirect_glLightModelfv(GLenum pname, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glLightModelfv_size(pname); const GLuint cmdlen = 8 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_LightModelfv, cmdlen); @@ -2443,7 +2443,7 @@ __indirect_glLightModelfv(GLenum pname, const GLfloat * params) void __indirect_glLightModeli(GLenum pname, GLint param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_LightModeli, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&pname), 4); @@ -2458,7 +2458,7 @@ __indirect_glLightModeli(GLenum pname, GLint param) void __indirect_glLightModeliv(GLenum pname, const GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glLightModeliv_size(pname); const GLuint cmdlen = 8 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_LightModeliv, cmdlen); @@ -2474,7 +2474,7 @@ __indirect_glLightModeliv(GLenum pname, const GLint * params) void __indirect_glLineStipple(GLint factor, GLushort pattern) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_LineStipple, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&factor), 4); @@ -2489,7 +2489,7 @@ __indirect_glLineStipple(GLint factor, GLushort pattern) void __indirect_glLineWidth(GLfloat width) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_LineWidth, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&width), 4); @@ -2503,7 +2503,7 @@ __indirect_glLineWidth(GLfloat width) void __indirect_glMaterialf(GLenum face, GLenum pname, GLfloat param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Materialf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&face), 4); @@ -2519,7 +2519,7 @@ __indirect_glMaterialf(GLenum face, GLenum pname, GLfloat param) void __indirect_glMaterialfv(GLenum face, GLenum pname, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glMaterialfv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_Materialfv, cmdlen); @@ -2536,7 +2536,7 @@ __indirect_glMaterialfv(GLenum face, GLenum pname, const GLfloat * params) void __indirect_glMateriali(GLenum face, GLenum pname, GLint param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Materiali, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&face), 4); @@ -2552,7 +2552,7 @@ __indirect_glMateriali(GLenum face, GLenum pname, GLint param) void __indirect_glMaterialiv(GLenum face, GLenum pname, const GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glMaterialiv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_Materialiv, cmdlen); @@ -2569,7 +2569,7 @@ __indirect_glMaterialiv(GLenum face, GLenum pname, const GLint * params) void __indirect_glPointSize(GLfloat size) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_PointSize, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&size), 4); @@ -2583,7 +2583,7 @@ __indirect_glPointSize(GLfloat size) void __indirect_glPolygonMode(GLenum face, GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_PolygonMode, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&face), 4); @@ -2598,7 +2598,7 @@ __indirect_glPolygonMode(GLenum face, GLenum mode) void __indirect_glPolygonStipple(const GLubyte *mask) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = (mask != NULL) ? __glImageSize(32, 32, 1, GL_COLOR_INDEX, GL_BITMAP, 0) : 0; @@ -2621,7 +2621,7 @@ __indirect_glPolygonStipple(const GLubyte *mask) void __indirect_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Scissor, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -2638,7 +2638,7 @@ __indirect_glScissor(GLint x, GLint y, GLsizei width, GLsizei height) void __indirect_glShadeModel(GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_ShadeModel, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mode), 4); @@ -2652,7 +2652,7 @@ __indirect_glShadeModel(GLenum mode) void __indirect_glTexParameterf(GLenum target, GLenum pname, GLfloat param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_TexParameterf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -2669,7 +2669,7 @@ void __indirect_glTexParameterfv(GLenum target, GLenum pname, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glTexParameterfv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_TexParameterfv, cmdlen); @@ -2686,7 +2686,7 @@ __indirect_glTexParameterfv(GLenum target, GLenum pname, void __indirect_glTexParameteri(GLenum target, GLenum pname, GLint param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_TexParameteri, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -2702,7 +2702,7 @@ __indirect_glTexParameteri(GLenum target, GLenum pname, GLint param) void __indirect_glTexParameteriv(GLenum target, GLenum pname, const GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glTexParameteriv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_TexParameteriv, cmdlen); @@ -2721,7 +2721,7 @@ __glx_TexImage_1D2D(unsigned opcode, unsigned dim, GLenum target, GLint level, GLint border, GLenum format, GLenum type, const GLvoid * pixels) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glImageSize(width, height, 1, format, type, target); const GLuint cmdlen = 56 + __GLX_PAD(compsize); @@ -2795,7 +2795,7 @@ __indirect_glTexImage2D(GLenum target, GLint level, GLint internalformat, void __indirect_glTexEnvf(GLenum target, GLenum pname, GLfloat param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_TexEnvf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -2811,7 +2811,7 @@ __indirect_glTexEnvf(GLenum target, GLenum pname, GLfloat param) void __indirect_glTexEnvfv(GLenum target, GLenum pname, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glTexEnvfv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_TexEnvfv, cmdlen); @@ -2828,7 +2828,7 @@ __indirect_glTexEnvfv(GLenum target, GLenum pname, const GLfloat * params) void __indirect_glTexEnvi(GLenum target, GLenum pname, GLint param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_TexEnvi, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -2844,7 +2844,7 @@ __indirect_glTexEnvi(GLenum target, GLenum pname, GLint param) void __indirect_glTexEnviv(GLenum target, GLenum pname, const GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glTexEnviv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_TexEnviv, cmdlen); @@ -2861,7 +2861,7 @@ __indirect_glTexEnviv(GLenum target, GLenum pname, const GLint * params) void __indirect_glTexGend(GLenum coord, GLenum pname, GLdouble param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_TexGend, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (¶m), 8); @@ -2877,7 +2877,7 @@ __indirect_glTexGend(GLenum coord, GLenum pname, GLdouble param) void __indirect_glTexGendv(GLenum coord, GLenum pname, const GLdouble * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glTexGendv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 8)); emit_header(gc->pc, X_GLrop_TexGendv, cmdlen); @@ -2894,7 +2894,7 @@ __indirect_glTexGendv(GLenum coord, GLenum pname, const GLdouble * params) void __indirect_glTexGenf(GLenum coord, GLenum pname, GLfloat param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_TexGenf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&coord), 4); @@ -2910,7 +2910,7 @@ __indirect_glTexGenf(GLenum coord, GLenum pname, GLfloat param) void __indirect_glTexGenfv(GLenum coord, GLenum pname, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glTexGenfv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_TexGenfv, cmdlen); @@ -2927,7 +2927,7 @@ __indirect_glTexGenfv(GLenum coord, GLenum pname, const GLfloat * params) void __indirect_glTexGeni(GLenum coord, GLenum pname, GLint param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_TexGeni, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&coord), 4); @@ -2943,7 +2943,7 @@ __indirect_glTexGeni(GLenum coord, GLenum pname, GLint param) void __indirect_glTexGeniv(GLenum coord, GLenum pname, const GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glTexGeniv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_TexGeniv, cmdlen); @@ -2960,7 +2960,7 @@ __indirect_glTexGeniv(GLenum coord, GLenum pname, const GLint * params) void __indirect_glInitNames(void) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 4; emit_header(gc->pc, X_GLrop_InitNames, cmdlen); gc->pc += cmdlen; @@ -2973,7 +2973,7 @@ __indirect_glInitNames(void) void __indirect_glLoadName(GLuint name) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_LoadName, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&name), 4); @@ -2987,7 +2987,7 @@ __indirect_glLoadName(GLuint name) void __indirect_glPassThrough(GLfloat token) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_PassThrough, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&token), 4); @@ -3001,7 +3001,7 @@ __indirect_glPassThrough(GLfloat token) void __indirect_glPopName(void) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 4; emit_header(gc->pc, X_GLrop_PopName, cmdlen); gc->pc += cmdlen; @@ -3014,7 +3014,7 @@ __indirect_glPopName(void) void __indirect_glPushName(GLuint name) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_PushName, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&name), 4); @@ -3028,7 +3028,7 @@ __indirect_glPushName(GLuint name) void __indirect_glDrawBuffer(GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_DrawBuffer, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mode), 4); @@ -3042,7 +3042,7 @@ __indirect_glDrawBuffer(GLenum mode) void __indirect_glClear(GLbitfield mask) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Clear, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mask), 4); @@ -3057,7 +3057,7 @@ void __indirect_glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_ClearAccum, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -3074,7 +3074,7 @@ __indirect_glClearAccum(GLfloat red, GLfloat green, GLfloat blue, void __indirect_glClearIndex(GLfloat c) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_ClearIndex, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&c), 4); @@ -3089,7 +3089,7 @@ void __indirect_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_ClearColor, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -3106,7 +3106,7 @@ __indirect_glClearColor(GLclampf red, GLclampf green, GLclampf blue, void __indirect_glClearStencil(GLint s) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_ClearStencil, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 4); @@ -3120,7 +3120,7 @@ __indirect_glClearStencil(GLint s) void __indirect_glClearDepth(GLclampd depth) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_ClearDepth, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&depth), 8); @@ -3134,7 +3134,7 @@ __indirect_glClearDepth(GLclampd depth) void __indirect_glStencilMask(GLuint mask) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_StencilMask, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mask), 4); @@ -3149,7 +3149,7 @@ void __indirect_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_ColorMask, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 1); @@ -3166,7 +3166,7 @@ __indirect_glColorMask(GLboolean red, GLboolean green, GLboolean blue, void __indirect_glDepthMask(GLboolean flag) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_DepthMask, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&flag), 1); @@ -3180,7 +3180,7 @@ __indirect_glDepthMask(GLboolean flag) void __indirect_glIndexMask(GLuint mask) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_IndexMask, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mask), 4); @@ -3194,7 +3194,7 @@ __indirect_glIndexMask(GLuint mask) void __indirect_glAccum(GLenum op, GLfloat value) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_Accum, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&op), 4); @@ -3209,7 +3209,7 @@ __indirect_glAccum(GLenum op, GLfloat value) void __indirect_glPopAttrib(void) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 4; emit_header(gc->pc, X_GLrop_PopAttrib, cmdlen); gc->pc += cmdlen; @@ -3222,7 +3222,7 @@ __indirect_glPopAttrib(void) void __indirect_glPushAttrib(GLbitfield mask) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_PushAttrib, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mask), 4); @@ -3236,7 +3236,7 @@ __indirect_glPushAttrib(GLbitfield mask) void __indirect_glMapGrid1d(GLint un, GLdouble u1, GLdouble u2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_MapGrid1d, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&u1), 8); @@ -3252,7 +3252,7 @@ __indirect_glMapGrid1d(GLint un, GLdouble u1, GLdouble u2) void __indirect_glMapGrid1f(GLint un, GLfloat u1, GLfloat u2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MapGrid1f, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&un), 4); @@ -3269,7 +3269,7 @@ void __indirect_glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 44; emit_header(gc->pc, X_GLrop_MapGrid2d, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&u1), 8); @@ -3289,7 +3289,7 @@ void __indirect_glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_MapGrid2f, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&un), 4); @@ -3308,7 +3308,7 @@ __indirect_glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, void __indirect_glEvalCoord1d(GLdouble u) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_EvalCoord1dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&u), 8); @@ -3329,7 +3329,7 @@ __indirect_glEvalCoord1dv(const GLdouble * u) void __indirect_glEvalCoord1f(GLfloat u) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_EvalCoord1fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&u), 4); @@ -3350,7 +3350,7 @@ __indirect_glEvalCoord1fv(const GLfloat * u) void __indirect_glEvalCoord2d(GLdouble u, GLdouble v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_EvalCoord2dv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&u), 8); @@ -3372,7 +3372,7 @@ __indirect_glEvalCoord2dv(const GLdouble * u) void __indirect_glEvalCoord2f(GLfloat u, GLfloat v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_EvalCoord2fv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&u), 4); @@ -3394,7 +3394,7 @@ __indirect_glEvalCoord2fv(const GLfloat * u) void __indirect_glEvalMesh1(GLenum mode, GLint i1, GLint i2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_EvalMesh1, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mode), 4); @@ -3410,7 +3410,7 @@ __indirect_glEvalMesh1(GLenum mode, GLint i1, GLint i2) void __indirect_glEvalPoint1(GLint i) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_EvalPoint1, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&i), 4); @@ -3424,7 +3424,7 @@ __indirect_glEvalPoint1(GLint i) void __indirect_glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_EvalMesh2, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mode), 4); @@ -3442,7 +3442,7 @@ __indirect_glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) void __indirect_glEvalPoint2(GLint i, GLint j) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_EvalPoint2, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&i), 4); @@ -3457,7 +3457,7 @@ __indirect_glEvalPoint2(GLint i, GLint j) void __indirect_glAlphaFunc(GLenum func, GLclampf ref) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_AlphaFunc, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&func), 4); @@ -3472,7 +3472,7 @@ __indirect_glAlphaFunc(GLenum func, GLclampf ref) void __indirect_glBlendFunc(GLenum sfactor, GLenum dfactor) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_BlendFunc, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&sfactor), 4); @@ -3487,7 +3487,7 @@ __indirect_glBlendFunc(GLenum sfactor, GLenum dfactor) void __indirect_glLogicOp(GLenum opcode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_LogicOp, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&opcode), 4); @@ -3501,7 +3501,7 @@ __indirect_glLogicOp(GLenum opcode) void __indirect_glStencilFunc(GLenum func, GLint ref, GLuint mask) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_StencilFunc, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&func), 4); @@ -3517,7 +3517,7 @@ __indirect_glStencilFunc(GLenum func, GLint ref, GLuint mask) void __indirect_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_StencilOp, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&fail), 4); @@ -3533,7 +3533,7 @@ __indirect_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) void __indirect_glDepthFunc(GLenum func) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_DepthFunc, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&func), 4); @@ -3547,7 +3547,7 @@ __indirect_glDepthFunc(GLenum func) void __indirect_glPixelZoom(GLfloat xfactor, GLfloat yfactor) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_PixelZoom, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&xfactor), 4); @@ -3562,7 +3562,7 @@ __indirect_glPixelZoom(GLfloat xfactor, GLfloat yfactor) void __indirect_glPixelTransferf(GLenum pname, GLfloat param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_PixelTransferf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&pname), 4); @@ -3577,7 +3577,7 @@ __indirect_glPixelTransferf(GLenum pname, GLfloat param) void __indirect_glPixelTransferi(GLenum pname, GLint param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_PixelTransferi, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&pname), 4); @@ -3592,7 +3592,7 @@ __indirect_glPixelTransferi(GLenum pname, GLint param) void __indirect_glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat * values) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 4)); if (mapsize < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -3629,7 +3629,7 @@ __indirect_glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat * values) void __indirect_glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint * values) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 4)); if (mapsize < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -3666,7 +3666,7 @@ __indirect_glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint * values) void __indirect_glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort * values) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((mapsize * 2)); if (mapsize < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -3703,7 +3703,7 @@ __indirect_glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort * values) void __indirect_glReadBuffer(GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_ReadBuffer, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mode), 4); @@ -3718,7 +3718,7 @@ void __indirect_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_CopyPixels, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -3737,7 +3737,7 @@ void __indirect_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * pixels) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; #ifndef USE_XCB @@ -3786,7 +3786,7 @@ void __indirect_glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = (pixels != NULL) ? __glImageSize(width, height, 1, format, type, 0) : 0; @@ -3832,7 +3832,7 @@ __indirect_glDrawPixels(GLsizei width, GLsizei height, GLenum format, void __indirect_glGetClipPlane(GLenum plane, GLdouble * equation) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 4; @@ -3867,7 +3867,7 @@ __indirect_glGetClipPlane(GLenum plane, GLdouble * equation) void __indirect_glGetLightfv(GLenum light, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -3907,7 +3907,7 @@ __indirect_glGetLightfv(GLenum light, GLenum pname, GLfloat * params) void __indirect_glGetLightiv(GLenum light, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -3947,7 +3947,7 @@ __indirect_glGetLightiv(GLenum light, GLenum pname, GLint * params) void __indirect_glGetMapdv(GLenum target, GLenum query, GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -3985,7 +3985,7 @@ __indirect_glGetMapdv(GLenum target, GLenum query, GLdouble * v) void __indirect_glGetMapfv(GLenum target, GLenum query, GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4023,7 +4023,7 @@ __indirect_glGetMapfv(GLenum target, GLenum query, GLfloat * v) void __indirect_glGetMapiv(GLenum target, GLenum query, GLint * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4061,7 +4061,7 @@ __indirect_glGetMapiv(GLenum target, GLenum query, GLint * v) void __indirect_glGetMaterialfv(GLenum face, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4101,7 +4101,7 @@ __indirect_glGetMaterialfv(GLenum face, GLenum pname, GLfloat * params) void __indirect_glGetMaterialiv(GLenum face, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4141,7 +4141,7 @@ __indirect_glGetMaterialiv(GLenum face, GLenum pname, GLint * params) void __indirect_glGetPixelMapfv(GLenum map, GLfloat * values) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 4; @@ -4179,7 +4179,7 @@ __indirect_glGetPixelMapfv(GLenum map, GLfloat * values) void __indirect_glGetPixelMapuiv(GLenum map, GLuint * values) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 4; @@ -4218,7 +4218,7 @@ __indirect_glGetPixelMapuiv(GLenum map, GLuint * values) void __indirect_glGetPixelMapusv(GLenum map, GLushort * values) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 4; @@ -4257,7 +4257,7 @@ __indirect_glGetPixelMapusv(GLenum map, GLushort * values) void __indirect_glGetPolygonStipple(GLubyte *mask) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 4; @@ -4294,7 +4294,7 @@ __indirect_glGetPolygonStipple(GLubyte *mask) void __indirect_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4334,7 +4334,7 @@ __indirect_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params) void __indirect_glGetTexEnviv(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4374,7 +4374,7 @@ __indirect_glGetTexEnviv(GLenum target, GLenum pname, GLint * params) void __indirect_glGetTexGendv(GLenum coord, GLenum pname, GLdouble * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4414,7 +4414,7 @@ __indirect_glGetTexGendv(GLenum coord, GLenum pname, GLdouble * params) void __indirect_glGetTexGenfv(GLenum coord, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4454,7 +4454,7 @@ __indirect_glGetTexGenfv(GLenum coord, GLenum pname, GLfloat * params) void __indirect_glGetTexGeniv(GLenum coord, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4495,7 +4495,7 @@ void __indirect_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; #ifndef USE_XCB @@ -4542,7 +4542,7 @@ __indirect_glGetTexImage(GLenum target, GLint level, GLenum format, void __indirect_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4583,7 +4583,7 @@ __indirect_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat * params) void __indirect_glGetTexParameteriv(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -4625,7 +4625,7 @@ void __indirect_glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 12; @@ -4668,7 +4668,7 @@ void __indirect_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 12; @@ -4710,7 +4710,7 @@ __indirect_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLboolean __indirect_glIsList(GLuint list) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; #ifndef USE_XCB @@ -4742,7 +4742,7 @@ __indirect_glIsList(GLuint list) void __indirect_glDepthRange(GLclampd zNear, GLclampd zFar) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_DepthRange, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&zNear), 8); @@ -4758,7 +4758,7 @@ void __indirect_glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 52; emit_header(gc->pc, X_GLrop_Frustum, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&left), 8); @@ -4777,7 +4777,7 @@ __indirect_glFrustum(GLdouble left, GLdouble right, GLdouble bottom, void __indirect_glLoadIdentity(void) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 4; emit_header(gc->pc, X_GLrop_LoadIdentity, cmdlen); gc->pc += cmdlen; @@ -4790,7 +4790,7 @@ __indirect_glLoadIdentity(void) void __indirect_glLoadMatrixf(const GLfloat * m) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 68; emit_header(gc->pc, X_GLrop_LoadMatrixf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (m), 64); @@ -4804,7 +4804,7 @@ __indirect_glLoadMatrixf(const GLfloat * m) void __indirect_glLoadMatrixd(const GLdouble * m) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 132; emit_header(gc->pc, X_GLrop_LoadMatrixd, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (m), 128); @@ -4818,7 +4818,7 @@ __indirect_glLoadMatrixd(const GLdouble * m) void __indirect_glMatrixMode(GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_MatrixMode, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mode), 4); @@ -4832,7 +4832,7 @@ __indirect_glMatrixMode(GLenum mode) void __indirect_glMultMatrixf(const GLfloat * m) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 68; emit_header(gc->pc, X_GLrop_MultMatrixf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (m), 64); @@ -4846,7 +4846,7 @@ __indirect_glMultMatrixf(const GLfloat * m) void __indirect_glMultMatrixd(const GLdouble * m) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 132; emit_header(gc->pc, X_GLrop_MultMatrixd, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (m), 128); @@ -4861,7 +4861,7 @@ void __indirect_glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 52; emit_header(gc->pc, X_GLrop_Ortho, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&left), 8); @@ -4880,7 +4880,7 @@ __indirect_glOrtho(GLdouble left, GLdouble right, GLdouble bottom, void __indirect_glPopMatrix(void) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 4; emit_header(gc->pc, X_GLrop_PopMatrix, cmdlen); gc->pc += cmdlen; @@ -4893,7 +4893,7 @@ __indirect_glPopMatrix(void) void __indirect_glPushMatrix(void) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 4; emit_header(gc->pc, X_GLrop_PushMatrix, cmdlen); gc->pc += cmdlen; @@ -4906,7 +4906,7 @@ __indirect_glPushMatrix(void) void __indirect_glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 36; emit_header(gc->pc, X_GLrop_Rotated, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&angle), 8); @@ -4923,7 +4923,7 @@ __indirect_glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) void __indirect_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Rotatef, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&angle), 4); @@ -4940,7 +4940,7 @@ __indirect_glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) void __indirect_glScaled(GLdouble x, GLdouble y, GLdouble z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_Scaled, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8); @@ -4956,7 +4956,7 @@ __indirect_glScaled(GLdouble x, GLdouble y, GLdouble z) void __indirect_glScalef(GLfloat x, GLfloat y, GLfloat z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Scalef, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -4972,7 +4972,7 @@ __indirect_glScalef(GLfloat x, GLfloat y, GLfloat z) void __indirect_glTranslated(GLdouble x, GLdouble y, GLdouble z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_Translated, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 8); @@ -4988,7 +4988,7 @@ __indirect_glTranslated(GLdouble x, GLdouble y, GLdouble z) void __indirect_glTranslatef(GLfloat x, GLfloat y, GLfloat z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Translatef, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -5004,7 +5004,7 @@ __indirect_glTranslatef(GLfloat x, GLfloat y, GLfloat z) void __indirect_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Viewport, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -5021,7 +5021,7 @@ __indirect_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) void __indirect_glBindTexture(GLenum target, GLuint texture) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_BindTexture, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -5036,7 +5036,7 @@ __indirect_glBindTexture(GLenum target, GLuint texture) void __indirect_glIndexub(GLubyte c) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Indexubv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&c), 1); @@ -5050,7 +5050,7 @@ __indirect_glIndexub(GLubyte c) void __indirect_glIndexubv(const GLubyte *c) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_Indexubv, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (c), 1); @@ -5064,7 +5064,7 @@ __indirect_glIndexubv(const GLubyte *c) void __indirect_glPolygonOffset(GLfloat factor, GLfloat units) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_PolygonOffset, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&factor), 4); @@ -5080,7 +5080,7 @@ void __indirect_glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 32; emit_header(gc->pc, X_GLrop_CopyTexImage1D, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -5102,7 +5102,7 @@ __indirect_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 36; emit_header(gc->pc, X_GLrop_CopyTexImage2D, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -5124,7 +5124,7 @@ void __indirect_glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_CopyTexSubImage1D, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -5145,7 +5145,7 @@ __indirect_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 36; emit_header(gc->pc, X_GLrop_CopyTexSubImage2D, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -5166,7 +5166,7 @@ __indirect_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, void __indirect_glDeleteTextures(GLsizei n, const GLuint * textures) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); @@ -5196,15 +5196,15 @@ __indirect_glDeleteTextures(GLsizei n, const GLuint * textures) void glDeleteTexturesEXT(GLsizei n, const GLuint * textures) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_DeleteTextures(GET_DISPATCH(), (n, textures)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); if (n < 0) { @@ -5228,7 +5228,7 @@ glDeleteTexturesEXT(GLsizei n, const GLuint * textures) void __indirect_glGenTextures(GLsizei n, GLuint * textures) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 4; @@ -5267,15 +5267,15 @@ __indirect_glGenTextures(GLsizei n, GLuint * textures) void glGenTexturesEXT(GLsizei n, GLuint * textures) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GenTextures(GET_DISPATCH(), (n, textures)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4; if (n < 0) { @@ -5299,7 +5299,7 @@ glGenTexturesEXT(GLsizei n, GLuint * textures) GLboolean __indirect_glIsTexture(GLuint texture) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; #ifndef USE_XCB @@ -5332,15 +5332,15 @@ __indirect_glIsTexture(GLuint texture) GLboolean glIsTextureEXT(GLuint texture) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { return CALL_IsTexture(GET_DISPATCH(), (texture)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; const GLuint cmdlen = 4; @@ -5362,7 +5362,7 @@ void __indirect_glPrioritizeTextures(GLsizei n, const GLuint * textures, const GLclampf * priorities) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8 + __GLX_PAD((n * 4)) + __GLX_PAD((n * 4)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -5387,7 +5387,7 @@ __glx_TexSubImage_1D2D(unsigned opcode, unsigned dim, GLenum target, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = (pixels != NULL) ? __glImageSize(width, height, 1, format, type, target) : 0; @@ -5464,7 +5464,7 @@ void __indirect_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_BlendColor, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -5481,7 +5481,7 @@ __indirect_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, void __indirect_glBlendEquation(GLenum mode) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_BlendEquation, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&mode), 4); @@ -5496,7 +5496,7 @@ void __indirect_glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * table) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = (table != NULL) ? __glImageSize(width, 1, 1, format, type, target) : 0; @@ -5546,7 +5546,7 @@ void __indirect_glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glColorTableParameterfv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_ColorTableParameterfv, cmdlen); @@ -5564,7 +5564,7 @@ void __indirect_glColorTableParameteriv(GLenum target, GLenum pname, const GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glColorTableParameteriv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_ColorTableParameteriv, cmdlen); @@ -5582,7 +5582,7 @@ void __indirect_glCopyColorTable(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_CopyColorTable, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -5601,7 +5601,7 @@ void __indirect_glGetColorTable(GLenum target, GLenum format, GLenum type, GLvoid * table) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; #ifndef USE_XCB @@ -5648,15 +5648,15 @@ __indirect_glGetColorTable(GLenum target, GLenum format, GLenum type, void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid * table) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetColorTable(GET_DISPATCH(), (target, format, type, table)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; const GLuint cmdlen = 16; @@ -5683,7 +5683,7 @@ void __indirect_glGetColorTableParameterfv(GLenum target, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -5724,16 +5724,16 @@ __indirect_glGetColorTableParameterfv(GLenum target, GLenum pname, void glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetColorTableParameterfv(GET_DISPATCH(), (target, pname, params)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -5756,7 +5756,7 @@ void __indirect_glGetColorTableParameteriv(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -5797,16 +5797,16 @@ __indirect_glGetColorTableParameteriv(GLenum target, GLenum pname, void glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetColorTableParameteriv(GET_DISPATCH(), (target, pname, params)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -5829,7 +5829,7 @@ void __indirect_glColorSubTable(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid * data) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = (data != NULL) ? __glImageSize(count, 1, 1, format, type, target) : 0; const GLuint cmdlen = 44 + __GLX_PAD(compsize); @@ -5877,7 +5877,7 @@ void __indirect_glCopyColorSubTable(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_CopyColorSubTable, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -5897,7 +5897,7 @@ __glx_ConvolutionFilter_1D2D(unsigned opcode, unsigned dim, GLenum target, GLsizei height, GLenum format, GLenum type, const GLvoid * image) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = (image != NULL) ? __glImageSize(width, height, 1, format, type, target) : 0; @@ -5971,7 +5971,7 @@ void __indirect_glConvolutionParameterf(GLenum target, GLenum pname, GLfloat params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_ConvolutionParameterf, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -5988,7 +5988,7 @@ void __indirect_glConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glConvolutionParameterfv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_ConvolutionParameterfv, cmdlen); @@ -6005,7 +6005,7 @@ __indirect_glConvolutionParameterfv(GLenum target, GLenum pname, void __indirect_glConvolutionParameteri(GLenum target, GLenum pname, GLint params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_ConvolutionParameteri, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -6022,7 +6022,7 @@ void __indirect_glConvolutionParameteriv(GLenum target, GLenum pname, const GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glConvolutionParameteriv_size(pname); const GLuint cmdlen = 12 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_ConvolutionParameteriv, cmdlen); @@ -6040,7 +6040,7 @@ void __indirect_glCopyConvolutionFilter1D(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_CopyConvolutionFilter1D, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -6060,7 +6060,7 @@ __indirect_glCopyConvolutionFilter2D(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_CopyConvolutionFilter2D, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -6080,7 +6080,7 @@ void __indirect_glGetConvolutionFilter(GLenum target, GLenum format, GLenum type, GLvoid * image) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; #ifndef USE_XCB @@ -6123,16 +6123,16 @@ void gl_dispatch_stub_356(GLenum target, GLenum format, GLenum type, GLvoid * image) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetConvolutionFilter(GET_DISPATCH(), (target, format, type, image)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; const GLuint cmdlen = 16; @@ -6160,7 +6160,7 @@ void __indirect_glGetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -6201,16 +6201,16 @@ __indirect_glGetConvolutionParameterfv(GLenum target, GLenum pname, void gl_dispatch_stub_357(GLenum target, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetConvolutionParameterfv(GET_DISPATCH(), (target, pname, params)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -6233,7 +6233,7 @@ void __indirect_glGetConvolutionParameteriv(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -6274,16 +6274,16 @@ __indirect_glGetConvolutionParameteriv(GLenum target, GLenum pname, void gl_dispatch_stub_358(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetConvolutionParameteriv(GET_DISPATCH(), (target, pname, params)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -6306,7 +6306,7 @@ void __indirect_glGetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; #ifndef USE_XCB @@ -6354,16 +6354,16 @@ void gl_dispatch_stub_361(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetHistogram(GET_DISPATCH(), (target, reset, format, type, values)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; const GLuint cmdlen = 16; @@ -6391,7 +6391,7 @@ void __indirect_glGetHistogramParameterfv(GLenum target, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -6431,15 +6431,15 @@ __indirect_glGetHistogramParameterfv(GLenum target, GLenum pname, void gl_dispatch_stub_362(GLenum target, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetHistogramParameterfv(GET_DISPATCH(), (target, pname, params)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -6462,7 +6462,7 @@ void __indirect_glGetHistogramParameteriv(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -6502,15 +6502,15 @@ __indirect_glGetHistogramParameteriv(GLenum target, GLenum pname, void gl_dispatch_stub_363(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetHistogramParameteriv(GET_DISPATCH(), (target, pname, params)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -6533,7 +6533,7 @@ void __indirect_glGetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; #ifndef USE_XCB @@ -6577,15 +6577,15 @@ void gl_dispatch_stub_364(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetMinmax(GET_DISPATCH(), (target, reset, format, type, values)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const __GLXattribute *const state = gc->client_state_private; Display *const dpy = gc->currentDpy; const GLuint cmdlen = 16; @@ -6613,7 +6613,7 @@ void __indirect_glGetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -6651,15 +6651,15 @@ __indirect_glGetMinmaxParameterfv(GLenum target, GLenum pname, void gl_dispatch_stub_365(GLenum target, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetMinmaxParameterfv(GET_DISPATCH(), (target, pname, params)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -6681,7 +6681,7 @@ gl_dispatch_stub_365(GLenum target, GLenum pname, GLfloat * params) void __indirect_glGetMinmaxParameteriv(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -6719,15 +6719,15 @@ __indirect_glGetMinmaxParameteriv(GLenum target, GLenum pname, GLint * params) void gl_dispatch_stub_366(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetMinmaxParameteriv(GET_DISPATCH(), (target, pname, params)); } else #endif { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -6750,7 +6750,7 @@ void __indirect_glHistogram(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_Histogram, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -6767,7 +6767,7 @@ __indirect_glHistogram(GLenum target, GLsizei width, GLenum internalformat, void __indirect_glMinmax(GLenum target, GLenum internalformat, GLboolean sink) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_Minmax, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -6783,7 +6783,7 @@ __indirect_glMinmax(GLenum target, GLenum internalformat, GLboolean sink) void __indirect_glResetHistogram(GLenum target) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_ResetHistogram, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -6797,7 +6797,7 @@ __indirect_glResetHistogram(GLenum target) void __indirect_glResetMinmax(GLenum target) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_ResetMinmax, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -6813,7 +6813,7 @@ __glx_TexImage_3D4D(unsigned opcode, unsigned dim, GLenum target, GLint level, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const GLvoid * pixels) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = (pixels != NULL) ? __glImageSize(width, height, depth, format, type, target) : 0; @@ -6890,7 +6890,7 @@ __glx_TexSubImage_3D4D(unsigned opcode, unsigned dim, GLenum target, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const GLvoid * pixels) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = (pixels != NULL) ? __glImageSize(width, height, depth, format, type, target) : 0; @@ -6968,7 +6968,7 @@ __indirect_glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 40; emit_header(gc->pc, X_GLrop_CopyTexSubImage3D, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -6990,7 +6990,7 @@ __indirect_glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, void __indirect_glActiveTextureARB(GLenum texture) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_ActiveTextureARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&texture), 4); @@ -7004,7 +7004,7 @@ __indirect_glActiveTextureARB(GLenum texture) void __indirect_glMultiTexCoord1dARB(GLenum target, GLdouble s) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MultiTexCoord1dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 8); @@ -7019,7 +7019,7 @@ __indirect_glMultiTexCoord1dARB(GLenum target, GLdouble s) void __indirect_glMultiTexCoord1dvARB(GLenum target, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MultiTexCoord1dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (v), 8); @@ -7034,7 +7034,7 @@ __indirect_glMultiTexCoord1dvARB(GLenum target, const GLdouble * v) void __indirect_glMultiTexCoord1fARB(GLenum target, GLfloat s) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_MultiTexCoord1fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7049,7 +7049,7 @@ __indirect_glMultiTexCoord1fARB(GLenum target, GLfloat s) void __indirect_glMultiTexCoord1fvARB(GLenum target, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_MultiTexCoord1fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7064,7 +7064,7 @@ __indirect_glMultiTexCoord1fvARB(GLenum target, const GLfloat * v) void __indirect_glMultiTexCoord1iARB(GLenum target, GLint s) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_MultiTexCoord1ivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7079,7 +7079,7 @@ __indirect_glMultiTexCoord1iARB(GLenum target, GLint s) void __indirect_glMultiTexCoord1ivARB(GLenum target, const GLint * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_MultiTexCoord1ivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7094,7 +7094,7 @@ __indirect_glMultiTexCoord1ivARB(GLenum target, const GLint * v) void __indirect_glMultiTexCoord1sARB(GLenum target, GLshort s) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_MultiTexCoord1svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7109,7 +7109,7 @@ __indirect_glMultiTexCoord1sARB(GLenum target, GLshort s) void __indirect_glMultiTexCoord1svARB(GLenum target, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_MultiTexCoord1svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7124,7 +7124,7 @@ __indirect_glMultiTexCoord1svARB(GLenum target, const GLshort * v) void __indirect_glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_MultiTexCoord2dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 8); @@ -7140,7 +7140,7 @@ __indirect_glMultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t) void __indirect_glMultiTexCoord2dvARB(GLenum target, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_MultiTexCoord2dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (v), 16); @@ -7155,7 +7155,7 @@ __indirect_glMultiTexCoord2dvARB(GLenum target, const GLdouble * v) void __indirect_glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MultiTexCoord2fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7171,7 +7171,7 @@ __indirect_glMultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) void __indirect_glMultiTexCoord2fvARB(GLenum target, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MultiTexCoord2fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7186,7 +7186,7 @@ __indirect_glMultiTexCoord2fvARB(GLenum target, const GLfloat * v) void __indirect_glMultiTexCoord2iARB(GLenum target, GLint s, GLint t) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MultiTexCoord2ivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7202,7 +7202,7 @@ __indirect_glMultiTexCoord2iARB(GLenum target, GLint s, GLint t) void __indirect_glMultiTexCoord2ivARB(GLenum target, const GLint * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MultiTexCoord2ivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7217,7 +7217,7 @@ __indirect_glMultiTexCoord2ivARB(GLenum target, const GLint * v) void __indirect_glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_MultiTexCoord2svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7233,7 +7233,7 @@ __indirect_glMultiTexCoord2sARB(GLenum target, GLshort s, GLshort t) void __indirect_glMultiTexCoord2svARB(GLenum target, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_MultiTexCoord2svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7249,7 +7249,7 @@ void __indirect_glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 32; emit_header(gc->pc, X_GLrop_MultiTexCoord3dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 8); @@ -7266,7 +7266,7 @@ __indirect_glMultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, void __indirect_glMultiTexCoord3dvARB(GLenum target, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 32; emit_header(gc->pc, X_GLrop_MultiTexCoord3dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (v), 24); @@ -7282,7 +7282,7 @@ void __indirect_glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_MultiTexCoord3fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7299,7 +7299,7 @@ __indirect_glMultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, void __indirect_glMultiTexCoord3fvARB(GLenum target, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_MultiTexCoord3fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7314,7 +7314,7 @@ __indirect_glMultiTexCoord3fvARB(GLenum target, const GLfloat * v) void __indirect_glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_MultiTexCoord3ivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7331,7 +7331,7 @@ __indirect_glMultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r) void __indirect_glMultiTexCoord3ivARB(GLenum target, const GLint * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_MultiTexCoord3ivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7347,7 +7347,7 @@ void __indirect_glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MultiTexCoord3svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7364,7 +7364,7 @@ __indirect_glMultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, void __indirect_glMultiTexCoord3svARB(GLenum target, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MultiTexCoord3svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7380,7 +7380,7 @@ void __indirect_glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 40; emit_header(gc->pc, X_GLrop_MultiTexCoord4dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&s), 8); @@ -7398,7 +7398,7 @@ __indirect_glMultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, void __indirect_glMultiTexCoord4dvARB(GLenum target, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 40; emit_header(gc->pc, X_GLrop_MultiTexCoord4dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (v), 32); @@ -7414,7 +7414,7 @@ void __indirect_glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_MultiTexCoord4fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7432,7 +7432,7 @@ __indirect_glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, void __indirect_glMultiTexCoord4fvARB(GLenum target, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_MultiTexCoord4fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7448,7 +7448,7 @@ void __indirect_glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_MultiTexCoord4ivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7466,7 +7466,7 @@ __indirect_glMultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, void __indirect_glMultiTexCoord4ivARB(GLenum target, const GLint * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_MultiTexCoord4ivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7482,7 +7482,7 @@ void __indirect_glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MultiTexCoord4svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7500,7 +7500,7 @@ __indirect_glMultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, void __indirect_glMultiTexCoord4svARB(GLenum target, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_MultiTexCoord4svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7515,7 +7515,7 @@ __indirect_glMultiTexCoord4svARB(GLenum target, const GLshort * v) void __indirect_glSampleCoverageARB(GLclampf value, GLboolean invert) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_SampleCoverageARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&value), 4); @@ -7530,7 +7530,7 @@ __indirect_glSampleCoverageARB(GLclampf value, GLboolean invert) void __indirect_glGetProgramStringARB(GLenum target, GLenum pname, GLvoid * string) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -7550,7 +7550,7 @@ __indirect_glGetProgramStringARB(GLenum target, GLenum pname, GLvoid * string) void __indirect_glGetProgramivARB(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -7571,7 +7571,7 @@ void __indirect_glProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 44; emit_header(gc->pc, X_GLrop_ProgramEnvParameter4dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7591,7 +7591,7 @@ void __indirect_glProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 44; emit_header(gc->pc, X_GLrop_ProgramEnvParameter4dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7608,7 +7608,7 @@ void __indirect_glProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_ProgramEnvParameter4fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7628,7 +7628,7 @@ void __indirect_glProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_ProgramEnvParameter4fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7646,7 +7646,7 @@ __indirect_glProgramLocalParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 44; emit_header(gc->pc, X_GLrop_ProgramLocalParameter4dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7666,7 +7666,7 @@ void __indirect_glProgramLocalParameter4dvARB(GLenum target, GLuint index, const GLdouble * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 44; emit_header(gc->pc, X_GLrop_ProgramLocalParameter4dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7684,7 +7684,7 @@ __indirect_glProgramLocalParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_ProgramLocalParameter4fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7704,7 +7704,7 @@ void __indirect_glProgramLocalParameter4fvARB(GLenum target, GLuint index, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_ProgramLocalParameter4fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -7721,7 +7721,7 @@ void __indirect_glProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid * string) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16 + __GLX_PAD(len); if (len < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -7759,7 +7759,7 @@ __indirect_glProgramStringARB(GLenum target, GLenum format, GLsizei len, void __indirect_glVertexAttrib1dARB(GLuint index, GLdouble x) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib1dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7774,7 +7774,7 @@ __indirect_glVertexAttrib1dARB(GLuint index, GLdouble x) void __indirect_glVertexAttrib1dvARB(GLuint index, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib1dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7789,7 +7789,7 @@ __indirect_glVertexAttrib1dvARB(GLuint index, const GLdouble * v) void __indirect_glVertexAttrib1fARB(GLuint index, GLfloat x) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib1fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7804,7 +7804,7 @@ __indirect_glVertexAttrib1fARB(GLuint index, GLfloat x) void __indirect_glVertexAttrib1fvARB(GLuint index, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib1fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7819,7 +7819,7 @@ __indirect_glVertexAttrib1fvARB(GLuint index, const GLfloat * v) void __indirect_glVertexAttrib1sARB(GLuint index, GLshort x) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib1svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7834,7 +7834,7 @@ __indirect_glVertexAttrib1sARB(GLuint index, GLshort x) void __indirect_glVertexAttrib1svARB(GLuint index, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib1svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7849,7 +7849,7 @@ __indirect_glVertexAttrib1svARB(GLuint index, const GLshort * v) void __indirect_glVertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib2dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7865,7 +7865,7 @@ __indirect_glVertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y) void __indirect_glVertexAttrib2dvARB(GLuint index, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib2dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7880,7 +7880,7 @@ __indirect_glVertexAttrib2dvARB(GLuint index, const GLdouble * v) void __indirect_glVertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib2fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7896,7 +7896,7 @@ __indirect_glVertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y) void __indirect_glVertexAttrib2fvARB(GLuint index, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib2fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7911,7 +7911,7 @@ __indirect_glVertexAttrib2fvARB(GLuint index, const GLfloat * v) void __indirect_glVertexAttrib2sARB(GLuint index, GLshort x, GLshort y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib2svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7927,7 +7927,7 @@ __indirect_glVertexAttrib2sARB(GLuint index, GLshort x, GLshort y) void __indirect_glVertexAttrib2svARB(GLuint index, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib2svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7943,7 +7943,7 @@ void __indirect_glVertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 32; emit_header(gc->pc, X_GLrop_VertexAttrib3dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7960,7 +7960,7 @@ __indirect_glVertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, void __indirect_glVertexAttrib3dvARB(GLuint index, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 32; emit_header(gc->pc, X_GLrop_VertexAttrib3dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7975,7 +7975,7 @@ __indirect_glVertexAttrib3dvARB(GLuint index, const GLdouble * v) void __indirect_glVertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_VertexAttrib3fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -7992,7 +7992,7 @@ __indirect_glVertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z) void __indirect_glVertexAttrib3fvARB(GLuint index, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_VertexAttrib3fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8007,7 +8007,7 @@ __indirect_glVertexAttrib3fvARB(GLuint index, const GLfloat * v) void __indirect_glVertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib3svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8024,7 +8024,7 @@ __indirect_glVertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z) void __indirect_glVertexAttrib3svARB(GLuint index, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib3svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8039,7 +8039,7 @@ __indirect_glVertexAttrib3svARB(GLuint index, const GLshort * v) void __indirect_glVertexAttrib4NbvARB(GLuint index, const GLbyte *v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib4NbvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8054,7 +8054,7 @@ __indirect_glVertexAttrib4NbvARB(GLuint index, const GLbyte *v) void __indirect_glVertexAttrib4NivARB(GLuint index, const GLint * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib4NivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8069,7 +8069,7 @@ __indirect_glVertexAttrib4NivARB(GLuint index, const GLint * v) void __indirect_glVertexAttrib4NsvARB(GLuint index, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib4NsvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8085,7 +8085,7 @@ void __indirect_glVertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib4NubvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8103,7 +8103,7 @@ __indirect_glVertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, void __indirect_glVertexAttrib4NubvARB(GLuint index, const GLubyte *v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib4NubvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8118,7 +8118,7 @@ __indirect_glVertexAttrib4NubvARB(GLuint index, const GLubyte *v) void __indirect_glVertexAttrib4NuivARB(GLuint index, const GLuint * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib4NuivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8133,7 +8133,7 @@ __indirect_glVertexAttrib4NuivARB(GLuint index, const GLuint * v) void __indirect_glVertexAttrib4NusvARB(GLuint index, const GLushort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib4NusvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8148,7 +8148,7 @@ __indirect_glVertexAttrib4NusvARB(GLuint index, const GLushort * v) void __indirect_glVertexAttrib4bvARB(GLuint index, const GLbyte *v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib4bvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8164,7 +8164,7 @@ void __indirect_glVertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 40; emit_header(gc->pc, X_GLrop_VertexAttrib4dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8182,7 +8182,7 @@ __indirect_glVertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, void __indirect_glVertexAttrib4dvARB(GLuint index, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 40; emit_header(gc->pc, X_GLrop_VertexAttrib4dvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8198,7 +8198,7 @@ void __indirect_glVertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib4fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8216,7 +8216,7 @@ __indirect_glVertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, void __indirect_glVertexAttrib4fvARB(GLuint index, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib4fvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8231,7 +8231,7 @@ __indirect_glVertexAttrib4fvARB(GLuint index, const GLfloat * v) void __indirect_glVertexAttrib4ivARB(GLuint index, const GLint * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib4ivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8247,7 +8247,7 @@ void __indirect_glVertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib4svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8265,7 +8265,7 @@ __indirect_glVertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, void __indirect_glVertexAttrib4svARB(GLuint index, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib4svARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8280,7 +8280,7 @@ __indirect_glVertexAttrib4svARB(GLuint index, const GLshort * v) void __indirect_glVertexAttrib4ubvARB(GLuint index, const GLubyte *v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib4ubvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8295,7 +8295,7 @@ __indirect_glVertexAttrib4ubvARB(GLuint index, const GLubyte *v) void __indirect_glVertexAttrib4uivARB(GLuint index, const GLuint * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib4uivARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8310,7 +8310,7 @@ __indirect_glVertexAttrib4uivARB(GLuint index, const GLuint * v) void __indirect_glVertexAttrib4usvARB(GLuint index, const GLushort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib4usvARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -8325,7 +8325,7 @@ __indirect_glVertexAttrib4usvARB(GLuint index, const GLushort * v) void __indirect_glBeginQueryARB(GLenum target, GLuint id) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_BeginQueryARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -8340,7 +8340,7 @@ __indirect_glBeginQueryARB(GLenum target, GLuint id) void __indirect_glDeleteQueriesARB(GLsizei n, const GLuint * ids) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); @@ -8370,7 +8370,7 @@ __indirect_glDeleteQueriesARB(GLsizei n, const GLuint * ids) void __indirect_glEndQueryARB(GLenum target) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_EndQueryARB, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -8384,7 +8384,7 @@ __indirect_glEndQueryARB(GLenum target) void __indirect_glGenQueriesARB(GLsizei n, GLuint * ids) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 4; @@ -8423,7 +8423,7 @@ __indirect_glGenQueriesARB(GLsizei n, GLuint * ids) void __indirect_glGetQueryObjectivARB(GLuint id, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -8461,7 +8461,7 @@ __indirect_glGetQueryObjectivARB(GLuint id, GLenum pname, GLint * params) void __indirect_glGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -8499,7 +8499,7 @@ __indirect_glGetQueryObjectuivARB(GLuint id, GLenum pname, GLuint * params) void __indirect_glGetQueryivARB(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; #ifndef USE_XCB const GLuint cmdlen = 8; @@ -8540,7 +8540,7 @@ __indirect_glGetQueryivARB(GLenum target, GLenum pname, GLint * params) GLboolean __indirect_glIsQueryARB(GLuint id) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; #ifndef USE_XCB @@ -8574,7 +8574,7 @@ __indirect_glIsQueryARB(GLuint id) void __indirect_glDrawBuffersARB(GLsizei n, const GLenum * bufs) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8 + __GLX_PAD((n * 4)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -8610,7 +8610,7 @@ __indirect_glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_RenderbufferStorageMultisample, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -8628,7 +8628,7 @@ __indirect_glRenderbufferStorageMultisample(GLenum target, GLsizei samples, void __indirect_glSampleMaskSGIS(GLclampf value, GLboolean invert) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_SampleMaskSGIS, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&value), 4); @@ -8643,7 +8643,7 @@ __indirect_glSampleMaskSGIS(GLclampf value, GLboolean invert) void __indirect_glSamplePatternSGIS(GLenum pattern) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_SamplePatternSGIS, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&pattern), 4); @@ -8657,7 +8657,7 @@ __indirect_glSamplePatternSGIS(GLenum pattern) void __indirect_glPointParameterfEXT(GLenum pname, GLfloat param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_PointParameterfEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&pname), 4); @@ -8672,7 +8672,7 @@ __indirect_glPointParameterfEXT(GLenum pname, GLfloat param) void __indirect_glPointParameterfvEXT(GLenum pname, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glPointParameterfvEXT_size(pname); const GLuint cmdlen = 8 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_PointParameterfvEXT, cmdlen); @@ -8688,7 +8688,7 @@ __indirect_glPointParameterfvEXT(GLenum pname, const GLfloat * params) void __indirect_glSecondaryColor3bEXT(GLbyte red, GLbyte green, GLbyte blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_SecondaryColor3bvEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 1); @@ -8711,7 +8711,7 @@ __indirect_glSecondaryColor3bvEXT(const GLbyte *v) void __indirect_glSecondaryColor3dEXT(GLdouble red, GLdouble green, GLdouble blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_SecondaryColor3dvEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 8); @@ -8734,7 +8734,7 @@ __indirect_glSecondaryColor3dvEXT(const GLdouble * v) void __indirect_glSecondaryColor3fEXT(GLfloat red, GLfloat green, GLfloat blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_SecondaryColor3fvEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -8757,7 +8757,7 @@ __indirect_glSecondaryColor3fvEXT(const GLfloat * v) void __indirect_glSecondaryColor3iEXT(GLint red, GLint green, GLint blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_SecondaryColor3ivEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -8780,7 +8780,7 @@ __indirect_glSecondaryColor3ivEXT(const GLint * v) void __indirect_glSecondaryColor3sEXT(GLshort red, GLshort green, GLshort blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_SecondaryColor3svEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 2); @@ -8803,7 +8803,7 @@ __indirect_glSecondaryColor3svEXT(const GLshort * v) void __indirect_glSecondaryColor3ubEXT(GLubyte red, GLubyte green, GLubyte blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_SecondaryColor3ubvEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 1); @@ -8826,7 +8826,7 @@ __indirect_glSecondaryColor3ubvEXT(const GLubyte *v) void __indirect_glSecondaryColor3uiEXT(GLuint red, GLuint green, GLuint blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_SecondaryColor3uivEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 4); @@ -8849,7 +8849,7 @@ __indirect_glSecondaryColor3uivEXT(const GLuint * v) void __indirect_glSecondaryColor3usEXT(GLushort red, GLushort green, GLushort blue) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_SecondaryColor3usvEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&red), 2); @@ -8872,7 +8872,7 @@ __indirect_glSecondaryColor3usvEXT(const GLushort * v) void __indirect_glFogCoorddEXT(GLdouble coord) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_FogCoorddvEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&coord), 8); @@ -8893,7 +8893,7 @@ __indirect_glFogCoorddvEXT(const GLdouble * coord) void __indirect_glFogCoordfEXT(GLfloat coord) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_FogCoordfvEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&coord), 4); @@ -8915,7 +8915,7 @@ void __indirect_glBlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_BlendFuncSeparateEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&sfactorRGB), 4); @@ -8932,7 +8932,7 @@ __indirect_glBlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB, void __indirect_glWindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_WindowPos3fvMESA, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&x), 4); @@ -8956,7 +8956,7 @@ GLboolean __indirect_glAreProgramsResidentNV(GLsizei n, const GLuint * ids, GLboolean * residences) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); @@ -8981,7 +8981,7 @@ __indirect_glAreProgramsResidentNV(GLsizei n, const GLuint * ids, void __indirect_glBindProgramNV(GLenum target, GLuint program) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_BindProgramNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -8996,7 +8996,7 @@ __indirect_glBindProgramNV(GLenum target, GLuint program) void __indirect_glDeleteProgramsNV(GLsizei n, const GLuint * programs) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); if (n < 0) { @@ -9020,7 +9020,7 @@ void __indirect_glExecuteProgramNV(GLenum target, GLuint id, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_ExecuteProgramNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -9036,7 +9036,7 @@ __indirect_glExecuteProgramNV(GLenum target, GLuint id, void __indirect_glGenProgramsNV(GLsizei n, GLuint * programs) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4; if (n < 0) { @@ -9060,7 +9060,7 @@ void __indirect_glGetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 12; if (__builtin_expect(dpy != NULL, 1)) { @@ -9082,7 +9082,7 @@ void __indirect_glGetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 12; if (__builtin_expect(dpy != NULL, 1)) { @@ -9103,7 +9103,7 @@ __indirect_glGetProgramParameterfvNV(GLenum target, GLuint index, void __indirect_glGetProgramStringNV(GLuint id, GLenum pname, GLubyte *program) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -9123,7 +9123,7 @@ __indirect_glGetProgramStringNV(GLuint id, GLenum pname, GLubyte *program) void __indirect_glGetProgramivNV(GLuint id, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -9144,7 +9144,7 @@ void __indirect_glGetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 12; if (__builtin_expect(dpy != NULL, 1)) { @@ -9166,7 +9166,7 @@ void __indirect_glGetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -9186,7 +9186,7 @@ __indirect_glGetVertexAttribdvNV(GLuint index, GLenum pname, void __indirect_glGetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -9206,7 +9206,7 @@ __indirect_glGetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat * params) void __indirect_glGetVertexAttribivNV(GLuint index, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -9226,7 +9226,7 @@ __indirect_glGetVertexAttribivNV(GLuint index, GLenum pname, GLint * params) GLboolean __indirect_glIsProgramNV(GLuint program) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; const GLuint cmdlen = 4; @@ -9247,7 +9247,7 @@ void __indirect_glLoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16 + __GLX_PAD(len); if (len < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9271,7 +9271,7 @@ void __indirect_glProgramParameters4dvNV(GLenum target, GLuint index, GLuint num, const GLdouble * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16 + __GLX_PAD((num * 32)); if (num < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9295,7 +9295,7 @@ void __indirect_glProgramParameters4fvNV(GLenum target, GLuint index, GLuint num, const GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16 + __GLX_PAD((num * 16)); if (num < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9318,7 +9318,7 @@ __indirect_glProgramParameters4fvNV(GLenum target, GLuint index, GLuint num, void __indirect_glRequestResidentProgramsNV(GLsizei n, const GLuint * ids) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8 + __GLX_PAD((n * 4)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9340,7 +9340,7 @@ void __indirect_glTrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_TrackMatrixNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -9357,7 +9357,7 @@ __indirect_glTrackMatrixNV(GLenum target, GLuint address, GLenum matrix, void __indirect_glVertexAttrib1dNV(GLuint index, GLdouble x) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib1dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9372,7 +9372,7 @@ __indirect_glVertexAttrib1dNV(GLuint index, GLdouble x) void __indirect_glVertexAttrib1dvNV(GLuint index, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib1dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9387,7 +9387,7 @@ __indirect_glVertexAttrib1dvNV(GLuint index, const GLdouble * v) void __indirect_glVertexAttrib1fNV(GLuint index, GLfloat x) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib1fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9402,7 +9402,7 @@ __indirect_glVertexAttrib1fNV(GLuint index, GLfloat x) void __indirect_glVertexAttrib1fvNV(GLuint index, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib1fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9417,7 +9417,7 @@ __indirect_glVertexAttrib1fvNV(GLuint index, const GLfloat * v) void __indirect_glVertexAttrib1sNV(GLuint index, GLshort x) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib1svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9432,7 +9432,7 @@ __indirect_glVertexAttrib1sNV(GLuint index, GLshort x) void __indirect_glVertexAttrib1svNV(GLuint index, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib1svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9447,7 +9447,7 @@ __indirect_glVertexAttrib1svNV(GLuint index, const GLshort * v) void __indirect_glVertexAttrib2dNV(GLuint index, GLdouble x, GLdouble y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib2dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9463,7 +9463,7 @@ __indirect_glVertexAttrib2dNV(GLuint index, GLdouble x, GLdouble y) void __indirect_glVertexAttrib2dvNV(GLuint index, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib2dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9478,7 +9478,7 @@ __indirect_glVertexAttrib2dvNV(GLuint index, const GLdouble * v) void __indirect_glVertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib2fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9494,7 +9494,7 @@ __indirect_glVertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y) void __indirect_glVertexAttrib2fvNV(GLuint index, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib2fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9509,7 +9509,7 @@ __indirect_glVertexAttrib2fvNV(GLuint index, const GLfloat * v) void __indirect_glVertexAttrib2sNV(GLuint index, GLshort x, GLshort y) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib2svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9525,7 +9525,7 @@ __indirect_glVertexAttrib2sNV(GLuint index, GLshort x, GLshort y) void __indirect_glVertexAttrib2svNV(GLuint index, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib2svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9541,7 +9541,7 @@ void __indirect_glVertexAttrib3dNV(GLuint index, GLdouble x, GLdouble y, GLdouble z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 32; emit_header(gc->pc, X_GLrop_VertexAttrib3dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9558,7 +9558,7 @@ __indirect_glVertexAttrib3dNV(GLuint index, GLdouble x, GLdouble y, void __indirect_glVertexAttrib3dvNV(GLuint index, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 32; emit_header(gc->pc, X_GLrop_VertexAttrib3dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9573,7 +9573,7 @@ __indirect_glVertexAttrib3dvNV(GLuint index, const GLdouble * v) void __indirect_glVertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_VertexAttrib3fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9590,7 +9590,7 @@ __indirect_glVertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z) void __indirect_glVertexAttrib3fvNV(GLuint index, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_VertexAttrib3fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9605,7 +9605,7 @@ __indirect_glVertexAttrib3fvNV(GLuint index, const GLfloat * v) void __indirect_glVertexAttrib3sNV(GLuint index, GLshort x, GLshort y, GLshort z) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib3svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9622,7 +9622,7 @@ __indirect_glVertexAttrib3sNV(GLuint index, GLshort x, GLshort y, GLshort z) void __indirect_glVertexAttrib3svNV(GLuint index, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib3svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9638,7 +9638,7 @@ void __indirect_glVertexAttrib4dNV(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 40; emit_header(gc->pc, X_GLrop_VertexAttrib4dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9656,7 +9656,7 @@ __indirect_glVertexAttrib4dNV(GLuint index, GLdouble x, GLdouble y, void __indirect_glVertexAttrib4dvNV(GLuint index, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 40; emit_header(gc->pc, X_GLrop_VertexAttrib4dvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9672,7 +9672,7 @@ void __indirect_glVertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib4fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9690,7 +9690,7 @@ __indirect_glVertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z, void __indirect_glVertexAttrib4fvNV(GLuint index, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_VertexAttrib4fvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9706,7 +9706,7 @@ void __indirect_glVertexAttrib4sNV(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib4svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9724,7 +9724,7 @@ __indirect_glVertexAttrib4sNV(GLuint index, GLshort x, GLshort y, GLshort z, void __indirect_glVertexAttrib4svNV(GLuint index, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 16; emit_header(gc->pc, X_GLrop_VertexAttrib4svNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9740,7 +9740,7 @@ void __indirect_glVertexAttrib4ubNV(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib4ubvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9758,7 +9758,7 @@ __indirect_glVertexAttrib4ubNV(GLuint index, GLubyte x, GLubyte y, GLubyte z, void __indirect_glVertexAttrib4ubvNV(GLuint index, const GLubyte *v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_VertexAttrib4ubvNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&index), 4); @@ -9773,7 +9773,7 @@ __indirect_glVertexAttrib4ubvNV(GLuint index, const GLubyte *v) void __indirect_glVertexAttribs1dvNV(GLuint index, GLsizei n, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 8)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9795,7 +9795,7 @@ __indirect_glVertexAttribs1dvNV(GLuint index, GLsizei n, const GLdouble * v) void __indirect_glVertexAttribs1fvNV(GLuint index, GLsizei n, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 4)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9817,7 +9817,7 @@ __indirect_glVertexAttribs1fvNV(GLuint index, GLsizei n, const GLfloat * v) void __indirect_glVertexAttribs1svNV(GLuint index, GLsizei n, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 2)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9839,7 +9839,7 @@ __indirect_glVertexAttribs1svNV(GLuint index, GLsizei n, const GLshort * v) void __indirect_glVertexAttribs2dvNV(GLuint index, GLsizei n, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 16)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9861,7 +9861,7 @@ __indirect_glVertexAttribs2dvNV(GLuint index, GLsizei n, const GLdouble * v) void __indirect_glVertexAttribs2fvNV(GLuint index, GLsizei n, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 8)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9883,7 +9883,7 @@ __indirect_glVertexAttribs2fvNV(GLuint index, GLsizei n, const GLfloat * v) void __indirect_glVertexAttribs2svNV(GLuint index, GLsizei n, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 4)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9905,7 +9905,7 @@ __indirect_glVertexAttribs2svNV(GLuint index, GLsizei n, const GLshort * v) void __indirect_glVertexAttribs3dvNV(GLuint index, GLsizei n, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 24)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9927,7 +9927,7 @@ __indirect_glVertexAttribs3dvNV(GLuint index, GLsizei n, const GLdouble * v) void __indirect_glVertexAttribs3fvNV(GLuint index, GLsizei n, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 12)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9949,7 +9949,7 @@ __indirect_glVertexAttribs3fvNV(GLuint index, GLsizei n, const GLfloat * v) void __indirect_glVertexAttribs3svNV(GLuint index, GLsizei n, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 6)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9971,7 +9971,7 @@ __indirect_glVertexAttribs3svNV(GLuint index, GLsizei n, const GLshort * v) void __indirect_glVertexAttribs4dvNV(GLuint index, GLsizei n, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 32)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -9993,7 +9993,7 @@ __indirect_glVertexAttribs4dvNV(GLuint index, GLsizei n, const GLdouble * v) void __indirect_glVertexAttribs4fvNV(GLuint index, GLsizei n, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 16)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -10015,7 +10015,7 @@ __indirect_glVertexAttribs4fvNV(GLuint index, GLsizei n, const GLfloat * v) void __indirect_glVertexAttribs4svNV(GLuint index, GLsizei n, const GLshort * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 8)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -10037,7 +10037,7 @@ __indirect_glVertexAttribs4svNV(GLuint index, GLsizei n, const GLshort * v) void __indirect_glVertexAttribs4ubvNV(GLuint index, GLsizei n, const GLubyte *v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12 + __GLX_PAD((n * 4)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -10059,7 +10059,7 @@ __indirect_glVertexAttribs4ubvNV(GLuint index, GLsizei n, const GLubyte *v) void __indirect_glPointParameteriNV(GLenum pname, GLint param) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_PointParameteriNV, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&pname), 4); @@ -10074,7 +10074,7 @@ __indirect_glPointParameteriNV(GLenum pname, GLint param) void __indirect_glPointParameterivNV(GLenum pname, const GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint compsize = __glPointParameterivNV_size(pname); const GLuint cmdlen = 8 + __GLX_PAD((compsize * 4)); emit_header(gc->pc, X_GLrop_PointParameterivNV, cmdlen); @@ -10090,7 +10090,7 @@ __indirect_glPointParameterivNV(GLenum pname, const GLint * params) void __indirect_glActiveStencilFaceEXT(GLenum face) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_ActiveStencilFaceEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&face), 4); @@ -10106,7 +10106,7 @@ __indirect_glGetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name, GLdouble * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8 + __GLX_PAD(len); if (len < 0) { @@ -10134,7 +10134,7 @@ __indirect_glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8 + __GLX_PAD(len); if (len < 0) { @@ -10162,7 +10162,7 @@ __indirect_glProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 44 + __GLX_PAD(len); if (len < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -10190,7 +10190,7 @@ __indirect_glProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name, const GLdouble * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 44 + __GLX_PAD(len); if (len < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -10215,7 +10215,7 @@ __indirect_glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28 + __GLX_PAD(len); if (len < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -10243,7 +10243,7 @@ __indirect_glProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name, const GLfloat * v) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28 + __GLX_PAD(len); if (len < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -10266,7 +10266,7 @@ __indirect_glProgramNamedParameter4fvNV(GLuint id, GLsizei len, void __indirect_glBlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_BlendEquationSeparateEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&modeRGB), 4); @@ -10281,7 +10281,7 @@ __indirect_glBlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) void __indirect_glBindFramebufferEXT(GLenum target, GLuint framebuffer) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_BindFramebufferEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -10296,7 +10296,7 @@ __indirect_glBindFramebufferEXT(GLenum target, GLuint framebuffer) void __indirect_glBindRenderbufferEXT(GLenum target, GLuint renderbuffer) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 12; emit_header(gc->pc, X_GLrop_BindRenderbufferEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -10311,7 +10311,7 @@ __indirect_glBindRenderbufferEXT(GLenum target, GLuint renderbuffer) GLenum __indirect_glCheckFramebufferStatusEXT(GLenum target) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLenum retval = (GLenum) 0; const GLuint cmdlen = 4; @@ -10332,7 +10332,7 @@ __indirect_glCheckFramebufferStatusEXT(GLenum target) void __indirect_glDeleteFramebuffersEXT(GLsizei n, const GLuint * framebuffers) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8 + __GLX_PAD((n * 4)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -10354,7 +10354,7 @@ __indirect_glDeleteFramebuffersEXT(GLsizei n, const GLuint * framebuffers) void __indirect_glDeleteRenderbuffersEXT(GLsizei n, const GLuint * renderbuffers) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8 + __GLX_PAD((n * 4)); if (n < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -10378,7 +10378,7 @@ __indirect_glFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_FramebufferRenderbufferEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -10397,7 +10397,7 @@ __indirect_glFramebufferTexture1DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_FramebufferTexture1DEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -10417,7 +10417,7 @@ __indirect_glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_FramebufferTexture2DEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -10437,7 +10437,7 @@ __indirect_glFramebufferTexture3DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 28; emit_header(gc->pc, X_GLrop_FramebufferTexture3DEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -10456,7 +10456,7 @@ __indirect_glFramebufferTexture3DEXT(GLenum target, GLenum attachment, void __indirect_glGenFramebuffersEXT(GLsizei n, GLuint * framebuffers) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4; if (n < 0) { @@ -10479,7 +10479,7 @@ __indirect_glGenFramebuffersEXT(GLsizei n, GLuint * framebuffers) void __indirect_glGenRenderbuffersEXT(GLsizei n, GLuint * renderbuffers) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 4; if (n < 0) { @@ -10502,7 +10502,7 @@ __indirect_glGenRenderbuffersEXT(GLsizei n, GLuint * renderbuffers) void __indirect_glGenerateMipmapEXT(GLenum target) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 8; emit_header(gc->pc, X_GLrop_GenerateMipmapEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -10519,7 +10519,7 @@ __indirect_glGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 12; if (__builtin_expect(dpy != NULL, 1)) { @@ -10542,7 +10542,7 @@ void __indirect_glGetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 8; if (__builtin_expect(dpy != NULL, 1)) { @@ -10563,7 +10563,7 @@ __indirect_glGetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLboolean __indirect_glIsFramebufferEXT(GLuint framebuffer) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; const GLuint cmdlen = 4; @@ -10583,7 +10583,7 @@ __indirect_glIsFramebufferEXT(GLuint framebuffer) GLboolean __indirect_glIsRenderbufferEXT(GLuint renderbuffer) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; const GLuint cmdlen = 4; @@ -10604,7 +10604,7 @@ void __indirect_glRenderbufferStorageEXT(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 20; emit_header(gc->pc, X_GLrop_RenderbufferStorageEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); @@ -10624,7 +10624,7 @@ __indirect_glBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 44; emit_header(gc->pc, X_GLrop_BlitFramebufferEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&srcX0), 4); @@ -10649,7 +10649,7 @@ __indirect_glFramebufferTextureLayerEXT(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); const GLuint cmdlen = 24; emit_header(gc->pc, X_GLrop_FramebufferTextureLayerEXT, cmdlen); (void) memcpy((void *) (gc->pc + 4), (void *) (&target), 4); diff --git a/src/glx/indirect.h b/src/glx/indirect.h index b09b61aae76..36d68b066cc 100644 --- a/src/glx/indirect.h +++ b/src/glx/indirect.h @@ -59,15 +59,15 @@ extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array ); extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy, - __GLXcontext * gc, unsigned max_dim, GLint width, GLint height, + struct glx_context * gc, unsigned max_dim, GLint width, GLint height, GLint depth, GLenum format, GLenum type, void * dest, GLboolean dimensions_in_reply ); extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest( - __GLXcontext * gc, GLint sop, GLint cmdlen ); + struct glx_context * gc, GLint sop, GLint cmdlen ); extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest( - __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen ); + struct glx_context * gc, GLint code, GLint vop, GLint cmdlen ); extern HIDDEN void __indirect_glNewList(GLuint list, GLenum mode); extern HIDDEN void __indirect_glEndList(void); diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c new file mode 100644 index 00000000000..f0598409cd6 --- /dev/null +++ b/src/glx/indirect_glx.c @@ -0,0 +1,456 @@ +/* + * Copyright © 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg ([email protected]) + */ + +#include "glapi.h" +#include "glxclient.h" + +extern struct _glapi_table *__glXNewIndirectAPI(void); + +/* +** All indirect rendering contexts will share the same indirect dispatch table. +*/ +static struct _glapi_table *IndirectAPI = NULL; + +static void +indirect_destroy_context(struct glx_context *gc) +{ + if (!gc->imported && gc->xid) + glx_send_destroy_context(gc->psc->dpy, gc->xid); + + __glXFreeVertexArrayState(gc); + + if (gc->vendor) + XFree((char *) gc->vendor); + if (gc->renderer) + XFree((char *) gc->renderer); + if (gc->version) + XFree((char *) gc->version); + if (gc->extensions) + XFree((char *) gc->extensions); + __glFreeAttributeState(gc); + XFree((char *) gc->buf); + Xfree((char *) gc->client_state_private); + XFree((char *) gc); +} + +static Bool +SendMakeCurrentRequest(Display * dpy, CARD8 opcode, + GLXContextID gc_id, GLXContextTag gc_tag, + GLXDrawable draw, GLXDrawable read, + xGLXMakeCurrentReply * reply) +{ + Bool ret; + + LockDisplay(dpy); + + if (draw == read) { + xGLXMakeCurrentReq *req; + + GetReq(GLXMakeCurrent, req); + req->reqType = opcode; + req->glxCode = X_GLXMakeCurrent; + req->drawable = draw; + req->context = gc_id; + req->oldContextTag = gc_tag; + } + else { + struct glx_display *priv = __glXInitialize(dpy); + + /* If the server can support the GLX 1.3 version, we should + * perfer that. Not only that, some servers support GLX 1.3 but + * not the SGI extension. + */ + + if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) { + xGLXMakeContextCurrentReq *req; + + GetReq(GLXMakeContextCurrent, req); + req->reqType = opcode; + req->glxCode = X_GLXMakeContextCurrent; + req->drawable = draw; + req->readdrawable = read; + req->context = gc_id; + req->oldContextTag = gc_tag; + } + else { + xGLXVendorPrivateWithReplyReq *vpreq; + xGLXMakeCurrentReadSGIReq *req; + + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXMakeCurrentReadSGIReq - + sz_xGLXVendorPrivateWithReplyReq, vpreq); + req = (xGLXMakeCurrentReadSGIReq *) vpreq; + req->reqType = opcode; + req->glxCode = X_GLXVendorPrivateWithReply; + req->vendorCode = X_GLXvop_MakeCurrentReadSGI; + req->drawable = draw; + req->readable = read; + req->context = gc_id; + req->oldContextTag = gc_tag; + } + } + + ret = _XReply(dpy, (xReply *) reply, 0, False); + + UnlockDisplay(dpy); + SyncHandle(); + + return ret; +} + +static int +indirect_bind_context(struct glx_context *gc, struct glx_context *old, + GLXDrawable draw, GLXDrawable read) +{ + xGLXMakeCurrentReply reply; + GLXContextTag tag; + __GLXattribute *state; + Display *dpy = gc->psc->dpy; + int opcode = __glXSetupForCommand(dpy); + + if (old != &dummyContext && !old->isDirect && old->psc->dpy == dpy) + tag = old->currentContextTag; + else + tag = None; + + SendMakeCurrentRequest(dpy, opcode, gc->xid, tag, draw, read, &reply); + + if (!IndirectAPI) + IndirectAPI = __glXNewIndirectAPI(); + _glapi_set_dispatch(IndirectAPI); + + gc->currentContextTag = reply.contextTag; + state = gc->client_state_private; + if (state->array_state == NULL) { + glGetString(GL_EXTENSIONS); + glGetString(GL_VERSION); + __glXInitVertexArrayState(gc); + } + + return Success; +} + +static void +indirect_unbind_context(struct glx_context *gc, struct glx_context *new) +{ + Display *dpy = gc->psc->dpy; + int opcode = __glXSetupForCommand(dpy); + xGLXMakeCurrentReply reply; + + /* We are either switching to no context, away from a indirect + * context to a direct context or from one dpy to another and have + * to send a request to the dpy to unbind the previous context. + */ + if (!new || new->isDirect || new->psc->dpy != dpy) + SendMakeCurrentRequest(dpy, opcode, None, + gc->currentContextTag, None, None, &reply); + gc->currentContextTag = 0; +} + +static void +indirect_wait_gl(struct glx_context *gc) +{ + xGLXWaitGLReq *req; + Display *dpy = gc->currentDpy; + + /* Flush any pending commands out */ + __glXFlushRenderBuffer(gc, gc->pc); + + /* Send the glXWaitGL request */ + LockDisplay(dpy); + GetReq(GLXWaitGL, req); + req->reqType = gc->majorOpcode; + req->glxCode = X_GLXWaitGL; + req->contextTag = gc->currentContextTag; + UnlockDisplay(dpy); + SyncHandle(); +} + +static void +indirect_wait_x(struct glx_context *gc) +{ + xGLXWaitXReq *req; + Display *dpy = gc->currentDpy; + + /* Flush any pending commands out */ + __glXFlushRenderBuffer(gc, gc->pc); + + LockDisplay(dpy); + GetReq(GLXWaitX, req); + req->reqType = gc->majorOpcode; + req->glxCode = X_GLXWaitX; + req->contextTag = gc->currentContextTag; + UnlockDisplay(dpy); + SyncHandle(); +} + +static void +indirect_use_x_font(struct glx_context *gc, + Font font, int first, int count, int listBase) +{ + xGLXUseXFontReq *req; + Display *dpy = gc->currentDpy; + + /* Flush any pending commands out */ + __glXFlushRenderBuffer(gc, gc->pc); + + /* Send the glXUseFont request */ + LockDisplay(dpy); + GetReq(GLXUseXFont, req); + req->reqType = gc->majorOpcode; + req->glxCode = X_GLXUseXFont; + req->contextTag = gc->currentContextTag; + req->font = font; + req->first = first; + req->count = count; + req->listBase = listBase; + UnlockDisplay(dpy); + SyncHandle(); +} + +static void +indirect_bind_tex_image(Display * dpy, + GLXDrawable drawable, + int buffer, const int *attrib_list) +{ + xGLXVendorPrivateReq *req; + struct glx_context *gc = __glXGetCurrentContext(); + CARD32 *drawable_ptr; + INT32 *buffer_ptr; + CARD32 *num_attrib_ptr; + CARD32 *attrib_ptr; + CARD8 opcode; + unsigned int i; + + i = 0; + if (attrib_list) { + while (attrib_list[i * 2] != None) + i++; + } + + opcode = __glXSetupForCommand(dpy); + if (!opcode) + return; + + LockDisplay(dpy); + GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req); + req->reqType = opcode; + req->glxCode = X_GLXVendorPrivate; + req->vendorCode = X_GLXvop_BindTexImageEXT; + req->contextTag = gc->currentContextTag; + + drawable_ptr = (CARD32 *) (req + 1); + buffer_ptr = (INT32 *) (drawable_ptr + 1); + num_attrib_ptr = (CARD32 *) (buffer_ptr + 1); + attrib_ptr = (CARD32 *) (num_attrib_ptr + 1); + + *drawable_ptr = drawable; + *buffer_ptr = buffer; + *num_attrib_ptr = (CARD32) i; + + i = 0; + if (attrib_list) { + while (attrib_list[i * 2] != None) { + *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0]; + *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1]; + i++; + } + } + + UnlockDisplay(dpy); + SyncHandle(); +} + +static void +indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer) +{ + xGLXVendorPrivateReq *req; + struct glx_context *gc = __glXGetCurrentContext(); + CARD32 *drawable_ptr; + INT32 *buffer_ptr; + CARD8 opcode; + + opcode = __glXSetupForCommand(dpy); + if (!opcode) + return; + + LockDisplay(dpy); + GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req); + req->reqType = opcode; + req->glxCode = X_GLXVendorPrivate; + req->vendorCode = X_GLXvop_ReleaseTexImageEXT; + req->contextTag = gc->currentContextTag; + + drawable_ptr = (CARD32 *) (req + 1); + buffer_ptr = (INT32 *) (drawable_ptr + 1); + + *drawable_ptr = drawable; + *buffer_ptr = buffer; + + UnlockDisplay(dpy); + SyncHandle(); +} + +static const struct glx_context_vtable indirect_context_vtable = { + indirect_destroy_context, + indirect_bind_context, + indirect_unbind_context, + indirect_wait_gl, + indirect_wait_x, + indirect_use_x_font, + indirect_bind_tex_image, + indirect_release_tex_image, +}; + +/** + * \todo Eliminate \c __glXInitVertexArrayState. Replace it with a new + * function called \c __glXAllocateClientState that allocates the memory and + * does all the initialization (including the pixel pack / unpack). + */ +_X_HIDDEN struct glx_context * +indirect_create_context(struct glx_screen *psc, + struct glx_config *mode, + struct glx_context *shareList, int renderType) +{ + struct glx_context *gc; + int bufSize; + CARD8 opcode; + __GLXattribute *state; + + opcode = __glXSetupForCommand(psc->dpy); + if (!opcode) { + return NULL; + } + + /* Allocate our context record */ + gc = Xmalloc(sizeof *gc); + if (!gc) { + /* Out of memory */ + return NULL; + } + memset(gc, 0, sizeof *gc); + + glx_context_init(gc, psc, mode); + gc->isDirect = GL_FALSE; + gc->vtable = &indirect_context_vtable; + state = Xmalloc(sizeof(struct __GLXattributeRec)); + if (state == NULL) { + /* Out of memory */ + Xfree(gc); + return NULL; + } + gc->client_state_private = state; + memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec)); + state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL); + + /* + ** Create a temporary buffer to hold GLX rendering commands. The size + ** of the buffer is selected so that the maximum number of GLX rendering + ** commands can fit in a single X packet and still have room in the X + ** packet for the GLXRenderReq header. + */ + + bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq; + gc->buf = (GLubyte *) Xmalloc(bufSize); + if (!gc->buf) { + Xfree(gc->client_state_private); + Xfree(gc); + return NULL; + } + gc->bufSize = bufSize; + + /* Fill in the new context */ + gc->renderMode = GL_RENDER; + + state->storePack.alignment = 4; + state->storeUnpack.alignment = 4; + + gc->attributes.stackPointer = &gc->attributes.stack[0]; + + /* + ** PERFORMANCE NOTE: A mode dependent fill image can speed things up. + ** Other code uses the fastImageUnpack bit, but it is never set + ** to GL_TRUE. + */ + gc->fastImageUnpack = GL_FALSE; + gc->fillImage = __glFillImage; + gc->pc = gc->buf; + gc->bufEnd = gc->buf + bufSize; + gc->isDirect = GL_FALSE; + if (__glXDebug) { + /* + ** Set limit register so that there will be one command per packet + */ + gc->limit = gc->buf; + } + else { + gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE; + } + gc->majorOpcode = opcode; + + /* + ** Constrain the maximum drawing command size allowed to be + ** transfered using the X_GLXRender protocol request. First + ** constrain by a software limit, then constrain by the protocl + ** limit. + */ + if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) { + bufSize = __GLX_RENDER_CMD_SIZE_LIMIT; + } + if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) { + bufSize = __GLX_MAX_RENDER_CMD_SIZE; + } + gc->maxSmallRenderCommandSize = bufSize; + + + return gc; +} + +struct glx_screen_vtable indirect_screen_vtable = { + indirect_create_context +}; + +_X_HIDDEN struct glx_screen * +indirect_create_screen(int screen, struct glx_display * priv) +{ + struct glx_screen *psc; + + psc = Xmalloc(sizeof *psc); + if (psc == NULL) + return NULL; + + memset(psc, 0, sizeof *psc); + glx_screen_init(psc, screen, priv); + psc->vtable = &indirect_screen_vtable; + + return psc; +} diff --git a/src/glx/indirect_init.c b/src/glx/indirect_init.c index 73ca993027b..ea051883988 100644 --- a/src/glx/indirect_init.c +++ b/src/glx/indirect_init.c @@ -53,13 +53,13 @@ static int NoOp(void) * Create and initialize a new GL dispatch table. The table is initialized * with GLX indirect rendering protocol functions. */ -__GLapi * __glXNewIndirectAPI( void ) +struct _glapi_table *__glXNewIndirectAPI( void ) { - __GLapi *glAPI; + struct _glapi_table *glAPI; GLuint entries; entries = _glapi_get_dispatch_table_size(); - glAPI = (__GLapi *) Xmalloc(entries * sizeof(void *)); + glAPI = (struct _glapi_table *) Xmalloc(entries * sizeof(void *)); /* first, set all entries to point to no-op functions */ { diff --git a/src/glx/indirect_init.h b/src/glx/indirect_init.h index 72255f13014..2ba01f56c3f 100644 --- a/src/glx/indirect_init.h +++ b/src/glx/indirect_init.h @@ -36,6 +36,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "glxclient.h" -extern __GLapi *__glXNewIndirectAPI(void); +extern struct _glapi_table *__glXNewIndirectAPI(void); #endif /* _INDIRECT_INIT_H_ */ diff --git a/src/glx/indirect_vertex_array.c b/src/glx/indirect_vertex_array.c index ec0e654ceae..372618de4f2 100644 --- a/src/glx/indirect_vertex_array.c +++ b/src/glx/indirect_vertex_array.c @@ -84,9 +84,9 @@ static struct array_state *get_array_entry(const struct array_state_vector *arrays, GLenum key, unsigned index); static void fill_array_info_cache(struct array_state_vector *arrays); -static GLboolean validate_mode(__GLXcontext * gc, GLenum mode); -static GLboolean validate_count(__GLXcontext * gc, GLsizei count); -static GLboolean validate_type(__GLXcontext * gc, GLenum type); +static GLboolean validate_mode(struct glx_context * gc, GLenum mode); +static GLboolean validate_count(struct glx_context * gc, GLsizei count); +static GLboolean validate_type(struct glx_context * gc, GLenum type); /** @@ -109,7 +109,7 @@ const GLuint __glXTypeSize_table[16] = { * __glXInitVertexArrayState(). */ void -__glXFreeVertexArrayState(__GLXcontext * gc) +__glXFreeVertexArrayState(struct glx_context * gc) { __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -135,8 +135,8 @@ __glXFreeVertexArrayState(__GLXcontext * gc) * \param gc GLX context whose vertex array state is to be initialized. * * \warning - * This function may only be called after __GLXcontext::gl_extension_bits, - * __GLXcontext::server_minor, and __GLXcontext::server_major have been + * This function may only be called after struct glx_context::gl_extension_bits, + * struct glx_context::server_minor, and __GLXcontext::server_major have been * initialized. These values are used to determine what vertex arrays are * supported. * @@ -144,7 +144,7 @@ __glXFreeVertexArrayState(__GLXcontext * gc) * Return values from malloc are not properly tested. */ void -__glXInitVertexArrayState(__GLXcontext * gc) +__glXInitVertexArrayState(struct glx_context * gc) { __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays; @@ -487,7 +487,7 @@ fill_array_info_cache(struct array_state_vector *arrays) void emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -549,7 +549,7 @@ emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count) * A pointer to the buffer for array data. */ static GLubyte * -emit_DrawArrays_header_old(__GLXcontext * gc, +emit_DrawArrays_header_old(struct glx_context * gc, struct array_state_vector *arrays, size_t * elements_per_request, unsigned int *total_requests, @@ -658,7 +658,7 @@ emit_DrawArrays_header_old(__GLXcontext * gc, void emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -720,7 +720,7 @@ void emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -787,7 +787,7 @@ void emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -875,7 +875,7 @@ emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type, * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not. */ static GLboolean -validate_mode(__GLXcontext * gc, GLenum mode) +validate_mode(struct glx_context * gc, GLenum mode) { switch (mode) { case GL_POINTS: @@ -908,7 +908,7 @@ validate_mode(__GLXcontext * gc, GLenum mode) * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not. */ static GLboolean -validate_count(__GLXcontext * gc, GLsizei count) +validate_count(struct glx_context * gc, GLsizei count) { if (count < 0) { __glXSetError(gc, GL_INVALID_VALUE); @@ -927,7 +927,7 @@ validate_count(__GLXcontext * gc, GLsizei count) * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not. */ static GLboolean -validate_type(__GLXcontext * gc, GLenum type) +validate_type(struct glx_context * gc, GLenum type) { switch (type) { case GL_UNSIGNED_INT: @@ -944,7 +944,7 @@ validate_type(__GLXcontext * gc, GLenum type) void __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -963,7 +963,7 @@ __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count) void __indirect_glArrayElement(GLint index) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -989,7 +989,7 @@ void __indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -1011,7 +1011,7 @@ __indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -1037,7 +1037,7 @@ void __indirect_glMultiDrawArraysEXT(GLenum mode, GLint * first, GLsizei * count, GLsizei primcount) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -1063,7 +1063,7 @@ __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count, GLenum type, const GLvoid ** indices, GLsizei primcount) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); const __GLXattribute *state = (const __GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; @@ -1119,7 +1119,7 @@ __indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride, 0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv }; uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1164,7 +1164,7 @@ __indirect_glNormalPointer(GLenum type, GLsizei stride, const GLvoid * pointer) { uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1235,7 +1235,7 @@ __indirect_glColorPointer(GLint size, GLenum type, GLsizei stride, 0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv }; uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1290,7 +1290,7 @@ void __indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) { uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1335,7 +1335,7 @@ __indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) void __indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1397,7 +1397,7 @@ __indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, }; uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1470,7 +1470,7 @@ __indirect_glSecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1530,7 +1530,7 @@ __indirect_glFogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid * pointer) { uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1577,7 +1577,7 @@ __indirect_glVertexAttribPointerARB(GLuint index, GLint size, static const uint16_t double_ops[5] = { 0, 4197, 4198, 4199, 4200 }; uint16_t opcode; - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *arrays = state->array_state; struct array_state *a; @@ -1690,7 +1690,7 @@ __indirect_glVertexAttribPointerNV(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); GLboolean normalized = GL_FALSE; @@ -1718,7 +1718,7 @@ __indirect_glVertexAttribPointerNV(GLuint index, GLint size, void __indirect_glClientActiveTextureARB(GLenum texture) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); __GLXattribute *const state = (__GLXattribute *) (gc->client_state_private); struct array_state_vector *const arrays = state->array_state; diff --git a/src/glx/indirect_vertex_program.c b/src/glx/indirect_vertex_program.c index d822a7ee56e..d955fdfa93e 100644 --- a/src/glx/indirect_vertex_program.c +++ b/src/glx/indirect_vertex_program.c @@ -37,7 +37,7 @@ static void do_vertex_attrib_enable(GLuint index, GLboolean val) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); if (!__glXSetArrayEnable(state, GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB, @@ -65,7 +65,7 @@ static void get_parameter(unsigned opcode, unsigned size, GLenum target, GLuint index, void *params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; const GLuint cmdlen = 12; @@ -122,7 +122,7 @@ void __indirect_glGetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid ** pointer) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) { @@ -177,7 +177,7 @@ get_attrib_array_data(__GLXattribute * state, GLuint index, GLenum cap, static void -get_vertex_attrib(__GLXcontext * gc, unsigned vop, +get_vertex_attrib(struct glx_context * gc, unsigned vop, GLuint index, GLenum pname, xReply * reply) { Display *const dpy = gc->currentDpy; @@ -195,7 +195,7 @@ get_vertex_attrib(__GLXcontext * gc, unsigned vop, void __indirect_glGetVertexAttribivARB(GLuint index, GLenum pname, GLint * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); xGLXSingleReply reply; @@ -229,7 +229,7 @@ void __indirect_glGetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); xGLXSingleReply reply; @@ -263,7 +263,7 @@ void __indirect_glGetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble * params) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); xGLXSingleReply reply; diff --git a/src/glx/packrender.h b/src/glx/packrender.h index 30f6d44bbd2..4266d5cc67b 100644 --- a/src/glx/packrender.h +++ b/src/glx/packrender.h @@ -54,7 +54,7 @@ /* Setup for all commands */ #define __GLX_DECLARE_VARIABLES() \ - __GLXcontext *gc; \ + struct glx_context *gc; \ GLubyte *pc, *pixelHeaderPC; \ GLuint compsize, cmdlen diff --git a/src/glx/packsingle.h b/src/glx/packsingle.h index f33a873f3a7..037265a7671 100644 --- a/src/glx/packsingle.h +++ b/src/glx/packsingle.h @@ -49,7 +49,7 @@ /* Declare common variables used during a single command */ #define __GLX_SINGLE_DECLARE_VARIABLES() \ - __GLXcontext *gc = __glXGetCurrentContext(); \ + struct glx_context *gc = __glXGetCurrentContext(); \ GLubyte *pc, *pixelHeaderPC; \ GLuint compsize, cmdlen; \ Display *dpy = gc->currentDpy; \ diff --git a/src/glx/pixel.c b/src/glx/pixel.c index d36ca31e7dd..d508d620736 100644 --- a/src/glx/pixel.c +++ b/src/glx/pixel.c @@ -80,7 +80,7 @@ static const GLubyte HighBitsMask[9] = { ** set of pixel modes that are to be done by the server. */ static void -FillBitmap(__GLXcontext * gc, GLint width, GLint height, +FillBitmap(struct glx_context * gc, GLint width, GLint height, GLenum format, const GLvoid * userdata, GLubyte * destImage) { const __GLXattribute *state = gc->client_state_private; @@ -161,7 +161,7 @@ FillBitmap(__GLXcontext * gc, GLint width, GLint height, ** ALIGNMENT = 1. */ void -__glFillImage(__GLXcontext * gc, GLint dim, GLint width, GLint height, +__glFillImage(struct glx_context * gc, GLint dim, GLint width, GLint height, GLint depth, GLenum format, GLenum type, const GLvoid * userdata, GLubyte * newimage, GLubyte * modes) { @@ -268,7 +268,7 @@ __glFillImage(__GLXcontext * gc, GLint dim, GLint width, GLint height, ** into the clients memory using the pixel store PACK modes. */ static void -EmptyBitmap(__GLXcontext * gc, GLint width, GLint height, +EmptyBitmap(struct glx_context * gc, GLint width, GLint height, GLenum format, const GLubyte * sourceImage, GLvoid * userdata) { const __GLXattribute *state = gc->client_state_private; @@ -388,7 +388,7 @@ EmptyBitmap(__GLXcontext * gc, GLint width, GLint height, */ /* ARGSUSED */ void -__glEmptyImage(__GLXcontext * gc, GLint dim, GLint width, GLint height, +__glEmptyImage(struct glx_context * gc, GLint dim, GLint width, GLint height, GLint depth, GLenum format, GLenum type, const GLubyte * sourceImage, GLvoid * userdata) { diff --git a/src/glx/pixelstore.c b/src/glx/pixelstore.c index dc193b9f747..1d776b817e5 100644 --- a/src/glx/pixelstore.c +++ b/src/glx/pixelstore.c @@ -46,7 +46,7 @@ * \sa __indirect_glPixelStorei, __indirect_glPixelStoref */ static void -send_PixelStore(__GLXcontext * gc, unsigned sop, GLenum pname, +send_PixelStore(struct glx_context * gc, unsigned sop, GLenum pname, const void *param) { Display *const dpy = gc->currentDpy; @@ -67,7 +67,7 @@ send_PixelStore(__GLXcontext * gc, unsigned sop, GLenum pname, void __indirect_glPixelStoref(GLenum pname, GLfloat param) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = gc->client_state_private; Display *dpy = gc->currentDpy; GLuint a; @@ -217,7 +217,7 @@ __indirect_glPixelStoref(GLenum pname, GLfloat param) void __indirect_glPixelStorei(GLenum pname, GLint param) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = gc->client_state_private; Display *dpy = gc->currentDpy; diff --git a/src/glx/renderpix.c b/src/glx/renderpix.c index 9919bbcde3b..8234bbe21f6 100644 --- a/src/glx/renderpix.c +++ b/src/glx/renderpix.c @@ -82,7 +82,7 @@ * broken. */ void -__glXSendLargeImage(__GLXcontext * gc, GLint compsize, GLint dim, +__glXSendLargeImage(struct glx_context * gc, GLint compsize, GLint dim, GLint width, GLint height, GLint depth, GLenum format, GLenum type, const GLvoid * src, GLubyte * pc, GLubyte * modes) diff --git a/src/glx/single2.c b/src/glx/single2.c index a1461956b99..318d18e5554 100644 --- a/src/glx/single2.c +++ b/src/glx/single2.c @@ -156,7 +156,7 @@ __indirect_glGetError(void) * On success \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned. */ static GLboolean -get_client_data(__GLXcontext * gc, GLenum cap, GLintptr * data) +get_client_data(struct glx_context * gc, GLenum cap, GLintptr * data) { GLboolean retval = GL_TRUE; __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); @@ -646,7 +646,7 @@ version_from_string(const char *ver, int *major_version, int *minor_version) const GLubyte * __indirect_glGetString(GLenum name) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); Display *dpy = gc->currentDpy; GLubyte *s = NULL; @@ -837,7 +837,7 @@ __indirect_glIsEnabled(GLenum cap) void __indirect_glGetPointerv(GLenum pname, void **params) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); Display *dpy = gc->currentDpy; @@ -885,7 +885,7 @@ GLboolean __indirect_glAreTexturesResident(GLsizei n, const GLuint * textures, GLboolean * residences) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); @@ -941,14 +941,14 @@ GLboolean glAreTexturesResidentEXT(GLsizei n, const GLuint * textures, GLboolean * residences) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); if (gc->isDirect) { return CALL_AreTexturesResident(GET_DISPATCH(), (n, textures, residences)); } else { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); Display *const dpy = gc->currentDpy; GLboolean retval = (GLboolean) 0; const GLuint cmdlen = 4 + __GLX_PAD((n * 4)); diff --git a/src/glx/singlepix.c b/src/glx/singlepix.c index c4010d79bd0..b61f26b2f3b 100644 --- a/src/glx/singlepix.c +++ b/src/glx/singlepix.c @@ -117,10 +117,10 @@ void NAME(_gloffset_GetSeparableFilter) (GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span) { - __GLXcontext *const gc = __glXGetCurrentContext(); + struct glx_context *const gc = __glXGetCurrentContext(); #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) - if (gc->driContext) { + if (gc->isDirect) { CALL_GetSeparableFilter(GET_DISPATCH(), (target, format, type, row, column, span)); return; diff --git a/src/glx/vertarr.c b/src/glx/vertarr.c index 398cfb1e796..609cafac2b1 100644 --- a/src/glx/vertarr.c +++ b/src/glx/vertarr.c @@ -101,7 +101,7 @@ void __indirect_glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid * pointer) { - __GLXcontext *gc = __glXGetCurrentContext(); + struct glx_context *gc = __glXGetCurrentContext(); __GLXattribute *state = (__GLXattribute *) (gc->client_state_private); #define NONE {0, 0, 0} diff --git a/src/glx/xfont.c b/src/glx/xfont.c index db3a5701100..4ca2c8f868f 100644 --- a/src/glx/xfont.c +++ b/src/glx/xfont.c @@ -212,7 +212,7 @@ isvalid(XFontStruct * fs, int which) } _X_HIDDEN void -DRI_glXUseXFont(GLXContext CC, Font font, int first, int count, int listbase) +DRI_glXUseXFont(struct glx_context *CC, Font font, int first, int count, int listbase) { Display *dpy; Window win; diff --git a/src/mapi/glapi/gen/glX_proto_recv.py b/src/mapi/glapi/gen/glX_proto_recv.py index 31745fcef77..887f63191de 100644 --- a/src/mapi/glapi/gen/glX_proto_recv.py +++ b/src/mapi/glapi/gen/glX_proto_recv.py @@ -384,9 +384,9 @@ class PrintGlxDispatchFunctions(glX_proto_common.glx_print_proto): print ' int error;' if self.do_swap: - print ' __GLXcontext * const cx = __glXForceCurrent(cl, bswap_CARD32( &req->contextTag ), &error);' + print ' struct glx_context * const cx = __glXForceCurrent(cl, bswap_CARD32( &req->contextTag ), &error);' else: - print ' __GLXcontext * const cx = __glXForceCurrent(cl, req->contextTag, &error);' + print ' struct glx_context * const cx = __glXForceCurrent(cl, req->contextTag, &error);' print '' if name not in f.glx_vendorpriv_names: diff --git a/src/mapi/glapi/gen/glX_proto_send.py b/src/mapi/glapi/gen/glX_proto_send.py index e7322820738..0ca0ff92a6c 100644 --- a/src/mapi/glapi/gen/glX_proto_send.py +++ b/src/mapi/glapi/gen/glX_proto_send.py @@ -220,7 +220,7 @@ __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_alway } NOINLINE void -__glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim, +__glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim, GLint width, GLint height, GLint depth, GLenum format, GLenum type, void * dest, GLboolean dimensions_in_reply ) { @@ -264,7 +264,7 @@ __glXReadPixelReply( Display *dpy, __GLXcontext * gc, unsigned max_dim, #define X_GLXSingle 0 NOINLINE FASTCALL GLubyte * -__glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen ) +__glXSetupSingleRequest( struct glx_context * gc, GLint sop, GLint cmdlen ) { xGLXSingleReq * req; Display * const dpy = gc->currentDpy; @@ -279,7 +279,7 @@ __glXSetupSingleRequest( __GLXcontext * gc, GLint sop, GLint cmdlen ) } NOINLINE FASTCALL GLubyte * -__glXSetupVendorRequest( __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen ) +__glXSetupVendorRequest( struct glx_context * gc, GLint code, GLint vop, GLint cmdlen ) { xGLXVendorPrivateReq * req; Display * const dpy = gc->currentDpy; @@ -371,10 +371,10 @@ const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; print '#define %s %d' % (func.opcode_vendor_name(name), func.glx_vendorpriv) print '%s gl%s(%s)' % (func.return_type, func_name, func.get_parameter_string()) print '{' - print ' __GLXcontext * const gc = __glXGetCurrentContext();' + print ' struct glx_context * const gc = __glXGetCurrentContext();' print '' print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)' - print ' if (gc->driContext) {' + print ' if (gc->isDirect) {' print ' %sCALL_%s(GET_DISPATCH(), (%s));' % (ret_string, func.name, func.get_called_parameter_string()) print ' } else' print '#endif' @@ -408,7 +408,7 @@ const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 }; print """static FASTCALL NOINLINE void generic_%u_byte( GLint rop, const void * ptr ) { - __GLXcontext * const gc = __glXGetCurrentContext(); + struct glx_context * const gc = __glXGetCurrentContext(); const GLuint cmdlen = %u; emit_header(gc->pc, rop, cmdlen); @@ -523,7 +523,7 @@ generic_%u_byte( GLint rop, const void * ptr ) def common_func_print_just_start(self, f, name): - print ' __GLXcontext * const gc = __glXGetCurrentContext();' + print ' struct glx_context * const gc = __glXGetCurrentContext();' # The only reason that single and vendor private commands need # a variable called 'dpy' is becuase they use the SyncHandle @@ -971,15 +971,15 @@ extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array ); extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy, - __GLXcontext * gc, unsigned max_dim, GLint width, GLint height, + struct glx_context * gc, unsigned max_dim, GLint width, GLint height, GLint depth, GLenum format, GLenum type, void * dest, GLboolean dimensions_in_reply ); extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest( - __GLXcontext * gc, GLint sop, GLint cmdlen ); + struct glx_context * gc, GLint sop, GLint cmdlen ); extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest( - __GLXcontext * gc, GLint code, GLint vop, GLint cmdlen ); + struct glx_context * gc, GLint code, GLint vop, GLint cmdlen ); """ diff --git a/src/mapi/glapi/glapi_nop.c b/src/mapi/glapi/glapi_nop.c index 4257b1fbce6..9709551ee78 100644 --- a/src/mapi/glapi/glapi_nop.c +++ b/src/mapi/glapi/glapi_nop.c @@ -3,7 +3,7 @@ * Version: 7.8 * * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2010 VMWare, Inc. All Rights Reserved. + * Copyright (C) 2010 VMware, Inc. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), diff --git a/src/mesa/Makefile b/src/mesa/Makefile index 3e0f010671c..7073c92240b 100644 --- a/src/mesa/Makefile +++ b/src/mesa/Makefile @@ -20,6 +20,13 @@ MESA_CPPFLAGS := $(API_DEFINES) ES1_CPPFLAGS := -DFEATURE_ES1=1 ES2_CPPFLAGS := -DFEATURE_ES2=1 +ifeq ($(MESA_LLVM),1) +MESA_CPPFLAGS += $(LLVM_CFLAGS) +ES1_CPPFLAGS += $(LLVM_CFLAGS) +ES2_CPPFLAGS += $(LLVM_CFLAGS) +endif + + include sources.mak # adjust object dirs diff --git a/src/mesa/SConscript b/src/mesa/SConscript index 79e9b4553b7..d31b957234b 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -80,6 +80,7 @@ if env['platform'] != 'winddk': 'main/pixelstore.c', 'main/points.c', 'main/polygon.c', + 'main/querymatrix.c', 'main/queryobj.c', 'main/rastpos.c', 'main/readpix.c', diff --git a/src/mesa/drivers/dri/common/dri_metaops.c b/src/mesa/drivers/dri/common/dri_metaops.c index 86e59a8e51c..a2f404b616f 100644 --- a/src/mesa/drivers/dri/common/dri_metaops.c +++ b/src/mesa/drivers/dri/common/dri_metaops.c @@ -29,6 +29,7 @@ #include "main/arbprogram.h" #include "main/arrayobj.h" #include "main/bufferobj.h" +#include "main/context.h" #include "main/enable.h" #include "main/matrix.h" #include "main/texstate.h" diff --git a/src/mesa/drivers/dri/i810/i810render.c b/src/mesa/drivers/dri/i810/i810render.c index b543d4f012c..205f0cebc1c 100644 --- a/src/mesa/drivers/dri/i810/i810render.c +++ b/src/mesa/drivers/dri/i810/i810render.c @@ -37,6 +37,8 @@ #include "main/imports.h" #include "main/mtypes.h" +#include "math/m_xform.h" + #include "tnl/t_context.h" #include "i810screen.h" diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile index 71ee753748c..65fd658c047 100644 --- a/src/mesa/drivers/dri/i915/Makefile +++ b/src/mesa/drivers/dri/i915/Makefile @@ -56,7 +56,7 @@ C_SOURCES = \ ASM_SOURCES = -DRIVER_DEFINES = -I../intel -I../intel/server -DI915 \ +DRIVER_DEFINES = -I../intel -DI915 \ $(shell pkg-config libdrm --atleast-version=2.3.1 \ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP") diff --git a/src/mesa/drivers/dri/i915/intel_render.c b/src/mesa/drivers/dri/i915/intel_render.c index ec209391ab4..add0adacb56 100644 --- a/src/mesa/drivers/dri/i915/intel_render.c +++ b/src/mesa/drivers/dri/i915/intel_render.c @@ -37,6 +37,8 @@ #include "main/mtypes.h" #include "main/enums.h" +#include "math/m_xform.h" + #include "tnl/t_context.h" #include "tnl/t_vertex.h" #include "tnl/t_pipeline.h" diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile index 831981558d8..e381a5c714b 100644 --- a/src/mesa/drivers/dri/i965/Makefile +++ b/src/mesa/drivers/dri/i965/Makefile @@ -106,7 +106,7 @@ C_SOURCES = \ ASM_SOURCES = -DRIVER_DEFINES = -I../intel -I../intel/server +DRIVER_DEFINES = -I../intel INCLUDES += $(INTEL_CFLAGS) DRI_LIB_DEPS += $(INTEL_LIBS) diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c index a74bbc25643..d2ac1235e46 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_util.c +++ b/src/mesa/drivers/dri/i965/brw_clip_util.c @@ -192,11 +192,6 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c, brw_clip_project_vertex(c, dest_ptr ); } - - - -#define MAX_MRF 16 - void brw_clip_emit_vue(struct brw_clip_compile *c, struct brw_indirect vert, GLboolean allocate, diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 6b20a2979f8..f7a68cead7c 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -604,6 +604,8 @@ #define BRW_ARF_NOTIFICATION_COUNT 0x90 #define BRW_ARF_IP 0xA0 +#define BRW_MRF_COMPR4 (1 << 7) + #define BRW_AMASK 0 #define BRW_IMASK 1 #define BRW_LMASK 2 diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index 31ff86cf731..ffdddd0a388 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.h +++ b/src/mesa/drivers/dri/i965/brw_eu.h @@ -984,5 +984,7 @@ void brw_set_src1( struct brw_instruction *insn, /* brw_optimize.c */ void brw_optimize(struct brw_compile *p); +void brw_remove_duplicate_mrf_moves(struct brw_compile *p); +void brw_remove_grf_to_mrf_moves(struct brw_compile *p); #endif diff --git a/src/mesa/drivers/dri/i965/brw_optimize.c b/src/mesa/drivers/dri/i965/brw_optimize.c index a364b158209..8aa6fb6cc6f 100644 --- a/src/mesa/drivers/dri/i965/brw_optimize.c +++ b/src/mesa/drivers/dri/i965/brw_optimize.c @@ -32,6 +32,594 @@ #include "brw_defines.h" #include "brw_eu.h" +static const struct { + char *name; + int nsrc; + int ndst; + GLboolean is_arith; +} inst_opcode[128] = { + [BRW_OPCODE_MOV] = { .name = "mov", .nsrc = 1, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_FRC] = { .name = "frc", .nsrc = 1, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_RNDU] = { .name = "rndu", .nsrc = 1, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_RNDD] = { .name = "rndd", .nsrc = 1, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_RNDE] = { .name = "rnde", .nsrc = 1, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_RNDZ] = { .name = "rndz", .nsrc = 1, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_NOT] = { .name = "not", .nsrc = 1, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_LZD] = { .name = "lzd", .nsrc = 1, .ndst = 1 }, + + [BRW_OPCODE_MUL] = { .name = "mul", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_MAC] = { .name = "mac", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_MACH] = { .name = "mach", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_LINE] = { .name = "line", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_PLN] = { .name = "pln", .nsrc = 2, .ndst = 1 }, + [BRW_OPCODE_SAD2] = { .name = "sad2", .nsrc = 2, .ndst = 1 }, + [BRW_OPCODE_SADA2] = { .name = "sada2", .nsrc = 2, .ndst = 1 }, + [BRW_OPCODE_DP4] = { .name = "dp4", .nsrc = 2, .ndst = 1 }, + [BRW_OPCODE_DPH] = { .name = "dph", .nsrc = 2, .ndst = 1 }, + [BRW_OPCODE_DP3] = { .name = "dp3", .nsrc = 2, .ndst = 1 }, + [BRW_OPCODE_DP2] = { .name = "dp2", .nsrc = 2, .ndst = 1 }, + [BRW_OPCODE_MATH] = { .name = "math", .nsrc = 2, .ndst = 1 }, + + [BRW_OPCODE_AVG] = { .name = "avg", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_ADD] = { .name = "add", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_SEL] = { .name = "sel", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_AND] = { .name = "and", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_OR] = { .name = "or", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_XOR] = { .name = "xor", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_SHR] = { .name = "shr", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_SHL] = { .name = "shl", .nsrc = 2, .ndst = 1, .is_arith = 1 }, + [BRW_OPCODE_ASR] = { .name = "asr", .nsrc = 2, .ndst = 1 }, + [BRW_OPCODE_CMP] = { .name = "cmp", .nsrc = 2, .ndst = 1 }, + [BRW_OPCODE_CMPN] = { .name = "cmpn", .nsrc = 2, .ndst = 1 }, + + [BRW_OPCODE_SEND] = { .name = "send", .nsrc = 1, .ndst = 1 }, + [BRW_OPCODE_NOP] = { .name = "nop", .nsrc = 0, .ndst = 0 }, + [BRW_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 1, .ndst = 0 }, + [BRW_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 }, + [BRW_OPCODE_IFF] = { .name = "iff", .nsrc = 2, .ndst = 1 }, + [BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 2, .ndst = 0 }, + [BRW_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 }, + [BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 2, .ndst = 0 }, + [BRW_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 1, .ndst = 0 }, + [BRW_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 }, + [BRW_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 }, + [BRW_OPCODE_PUSH] = { .name = "push", .nsrc = 1, .ndst = 1 }, + [BRW_OPCODE_MRESTORE] = { .name = "mrest", .nsrc = 1, .ndst = 1 }, + [BRW_OPCODE_POP] = { .name = "pop", .nsrc = 2, .ndst = 0 }, + [BRW_OPCODE_WAIT] = { .name = "wait", .nsrc = 1, .ndst = 0 }, + [BRW_OPCODE_DO] = { .name = "do", .nsrc = 0, .ndst = 0 }, + [BRW_OPCODE_ENDIF] = { .name = "endif", .nsrc = 2, .ndst = 0 }, +}; + +static INLINE +GLboolean brw_is_arithmetic_inst(const struct brw_instruction *inst) +{ + return inst_opcode[inst->header.opcode].is_arith; +} + +static const GLuint inst_stride[7] = { + [0] = 0, + [1] = 1, + [2] = 2, + [3] = 4, + [4] = 8, + [5] = 16, + [6] = 32 +}; + +static const GLuint inst_type_size[8] = { + [BRW_REGISTER_TYPE_UD] = 4, + [BRW_REGISTER_TYPE_D] = 4, + [BRW_REGISTER_TYPE_UW] = 2, + [BRW_REGISTER_TYPE_W] = 2, + [BRW_REGISTER_TYPE_UB] = 1, + [BRW_REGISTER_TYPE_B] = 1, + [BRW_REGISTER_TYPE_F] = 4 +}; + +static INLINE GLboolean +brw_is_grf_written(const struct brw_instruction *inst, + int reg_index, int size, + int gen) +{ + if (inst_opcode[inst->header.opcode].ndst == 0) + return GL_FALSE; + + if (inst->bits1.da1.dest_address_mode != BRW_ADDRESS_DIRECT) + if (inst->bits1.ia1.dest_reg_file == BRW_GENERAL_REGISTER_FILE) + return GL_TRUE; + + if (inst->bits1.da1.dest_reg_file != BRW_GENERAL_REGISTER_FILE) + return GL_FALSE; + + const int reg_start = reg_index * REG_SIZE; + const int reg_end = reg_start + size; + + const int type_size = inst_type_size[inst->bits1.da1.dest_reg_type]; + const int write_start = inst->bits1.da1.dest_reg_nr*REG_SIZE + + inst->bits1.da1.dest_subreg_nr; + int length, write_end; + + /* SEND is specific */ + if (inst->header.opcode == BRW_OPCODE_SEND) { + if (gen >= 5) + length = inst->bits3.generic_gen5.response_length*REG_SIZE; + else + length = inst->bits3.generic.response_length*REG_SIZE; + } + else { + length = 1 << inst->header.execution_size; + length *= type_size; + length *= inst->bits1.da1.dest_horiz_stride; + } + + /* If the two intervals intersect, we overwrite the register */ + write_end = write_start + length; + const int left = MAX2(write_start, reg_start); + const int right = MIN2(write_end, reg_end); + + return left < right; +} + +/* Specific path for message register since we need to handle the compr4 case */ +static INLINE GLboolean +brw_is_mrf_written(const struct brw_instruction *inst, int reg_index, int size) +{ + if (inst_opcode[inst->header.opcode].ndst == 0) + return GL_FALSE; + + if (inst->bits1.da1.dest_address_mode != BRW_ADDRESS_DIRECT) + if (inst->bits1.ia1.dest_reg_file == BRW_MESSAGE_REGISTER_FILE) + return GL_TRUE; + + if (inst->bits1.da1.dest_reg_file != BRW_MESSAGE_REGISTER_FILE) + return GL_FALSE; + + const int reg_start = reg_index * REG_SIZE; + const int reg_end = reg_start + size; + + const int mrf_index = inst->bits1.da1.dest_reg_nr & 0x0f; + const int is_compr4 = inst->bits1.da1.dest_reg_nr & BRW_MRF_COMPR4; + const int type_size = inst_type_size[inst->bits1.da1.dest_reg_type]; + + /* We use compr4 with a size != 16 elements. Strange, we conservatively + * consider that we are writing the register. + */ + if (is_compr4 && inst->header.execution_size != BRW_EXECUTE_16) + return GL_TRUE; + + GLboolean is_written = GL_FALSE; + + /* Here we write mrf_{i} and mrf_{i+4}. So we read two times 8 elements */ + if (is_compr4) { + const int length = 8 * type_size * inst->bits1.da1.dest_horiz_stride; + + /* First 8-way register */ + const int write_start0 = mrf_index*REG_SIZE + + inst->bits1.da1.dest_subreg_nr; + const int write_end0 = write_start0 + length; + + /* Second 8-way register */ + const int write_start1 = (mrf_index+4)*REG_SIZE + + inst->bits1.da1.dest_subreg_nr; + const int write_end1 = write_start1 + length; + + /* If the two intervals intersect, we overwrite the register */ + const int left0 = MAX2(write_start0, reg_start); + const int right0 = MIN2(write_end0, reg_end); + const int left1 = MAX2(write_start1, reg_start); + const int right1 = MIN2(write_end1, reg_end); + + is_written = left0 < right0 || left1 < right1; + } + else { + int length; + length = 1 << inst->header.execution_size; + length *= type_size; + length *= inst->bits1.da1.dest_horiz_stride; + + /* If the two intervals intersect, we write into the register */ + const int write_start = inst->bits1.da1.dest_reg_nr*REG_SIZE + + inst->bits1.da1.dest_subreg_nr; + const int write_end = write_start + length; + const int left = MAX2(write_start, reg_start); + const int right = MIN2(write_end, reg_end);; + + is_written = left < right; + } + + /* SEND may perform an implicit mov to a mrf register */ + if (is_written == GL_FALSE && + inst->header.opcode == BRW_OPCODE_SEND && + inst->bits1.da1.src0_reg_file != 0) { + + const int mrf_start = inst->header.destreg__conditionalmod; + const int write_start = mrf_start * REG_SIZE; + const int write_end = write_start + REG_SIZE; + const int left = MAX2(write_start, reg_start); + const int right = MIN2(write_end, reg_end);; + is_written = left < right; + } + + return is_written; +} + +static INLINE GLboolean +brw_is_mrf_read(const struct brw_instruction *inst, + int reg_index, int size, int gen) +{ + if (inst->header.opcode != BRW_OPCODE_SEND) + return GL_FALSE; + if (inst->bits2.da1.src0_address_mode != BRW_ADDRESS_DIRECT) + return GL_TRUE; + + const int reg_start = reg_index*REG_SIZE; + const int reg_end = reg_start + size; + + int length, read_start, read_end; + if (gen >= 5) + length = inst->bits3.generic_gen5.msg_length*REG_SIZE; + else + length = inst->bits3.generic.msg_length*REG_SIZE; + + /* Look if SEND uses an implicit mov. In that case, we read one less register + * (but we write it) + */ + if (inst->bits1.da1.src0_reg_file != 0) + read_start = inst->header.destreg__conditionalmod; + else { + length--; + read_start = inst->header.destreg__conditionalmod + 1; + } + read_start *= REG_SIZE; + read_end = read_start + length; + + const int left = MAX2(read_start, reg_start); + const int right = MIN2(read_end, reg_end); + + return left < right; +} + +static INLINE GLboolean +brw_is_grf_read(const struct brw_instruction *inst, int reg_index, int size) +{ + int i, j; + if (inst_opcode[inst->header.opcode].nsrc == 0) + return GL_FALSE; + + /* Look at first source. We must take into account register regions to + * monitor carefully the read. Note that we are a bit too conservative here + * since we do not take into account the fact that some complete registers + * may be skipped + */ + if (inst_opcode[inst->header.opcode].nsrc >= 1) { + + if (inst->bits2.da1.src0_address_mode != BRW_ADDRESS_DIRECT) + if (inst->bits1.ia1.src0_reg_file == BRW_GENERAL_REGISTER_FILE) + return GL_TRUE; + if (inst->bits1.da1.src0_reg_file != BRW_GENERAL_REGISTER_FILE) + return GL_FALSE; + + const int reg_start = reg_index*REG_SIZE; + const int reg_end = reg_start + size; + + /* See if at least one of this element intersects the interval */ + const int type_size = inst_type_size[inst->bits1.da1.src0_reg_type]; + const int elem_num = 1 << inst->header.execution_size; + const int width = 1 << inst->bits2.da1.src0_width; + const int row_num = elem_num >> inst->bits2.da1.src0_width; + const int hs = type_size*inst_stride[inst->bits2.da1.src0_horiz_stride]; + const int vs = type_size*inst_stride[inst->bits2.da1.src0_vert_stride]; + int row_start = inst->bits2.da1.src0_reg_nr*REG_SIZE + + inst->bits2.da1.src0_subreg_nr; + for (j = 0; j < row_num; ++j) { + int write_start = row_start; + for (i = 0; i < width; ++i) { + const int write_end = write_start + type_size; + const int left = write_start > reg_start ? write_start : reg_start; + const int right = write_end < reg_end ? write_end : reg_end; + if (left < right) + return GL_TRUE; + write_start += hs; + } + row_start += vs; + } + } + + /* Second src register */ + if (inst_opcode[inst->header.opcode].nsrc >= 2) { + + if (inst->bits3.da1.src1_address_mode != BRW_ADDRESS_DIRECT) + if (inst->bits1.ia1.src1_reg_file == BRW_GENERAL_REGISTER_FILE) + return GL_TRUE; + if (inst->bits1.da1.src1_reg_file != BRW_GENERAL_REGISTER_FILE) + return GL_FALSE; + + const int reg_start = reg_index*REG_SIZE; + const int reg_end = reg_start + size; + + /* See if at least one of this element intersects the interval */ + const int type_size = inst_type_size[inst->bits1.da1.src1_reg_type]; + const int elem_num = 1 << inst->header.execution_size; + const int width = 1 << inst->bits3.da1.src1_width; + const int row_num = elem_num >> inst->bits3.da1.src1_width; + const int hs = type_size*inst_stride[inst->bits3.da1.src1_horiz_stride]; + const int vs = type_size*inst_stride[inst->bits3.da1.src1_vert_stride]; + int row_start = inst->bits3.da1.src1_reg_nr*REG_SIZE + + inst->bits3.da1.src1_subreg_nr; + for (j = 0; j < row_num; ++j) { + int write_start = row_start; + for (i = 0; i < width; ++i) { + const int write_end = write_start + type_size; + const int left = write_start > reg_start ? write_start : reg_start; + const int right = write_end < reg_end ? write_end : reg_end; + if (left < right) + return GL_TRUE; + write_start += hs; + } + row_start += vs; + } + } + + return GL_FALSE; +} + +static INLINE GLboolean +brw_is_control_done(const struct brw_instruction *mov) { + return + mov->header.dependency_control != 0 || + mov->header.thread_control != 0 || + mov->header.mask_control != 0 || + mov->header.saturate != 0 || + mov->header.debug_control != 0; +} + +static INLINE GLboolean +brw_is_predicated(const struct brw_instruction *mov) { + return mov->header.predicate_control != 0; +} + +static INLINE GLboolean +brw_is_grf_to_mrf_mov(const struct brw_instruction *mov, + int *mrf_index, + int *grf_index, + GLboolean *is_compr4) +{ + if (brw_is_predicated(mov) || + brw_is_control_done(mov) || + mov->header.debug_control != 0) + return GL_FALSE; + + if (mov->bits1.da1.dest_address_mode != BRW_ADDRESS_DIRECT || + mov->bits1.da1.dest_reg_file != BRW_MESSAGE_REGISTER_FILE || + mov->bits1.da1.dest_reg_type != BRW_REGISTER_TYPE_F || + mov->bits1.da1.dest_horiz_stride != BRW_HORIZONTAL_STRIDE_1 || + mov->bits1.da1.dest_subreg_nr != 0) + return GL_FALSE; + + if (mov->bits2.da1.src0_address_mode != BRW_ADDRESS_DIRECT || + mov->bits1.da1.src0_reg_file != BRW_GENERAL_REGISTER_FILE || + mov->bits1.da1.src0_reg_type != BRW_REGISTER_TYPE_F || + mov->bits2.da1.src0_width != BRW_WIDTH_8 || + mov->bits2.da1.src0_horiz_stride != BRW_HORIZONTAL_STRIDE_1 || + mov->bits2.da1.src0_vert_stride != BRW_VERTICAL_STRIDE_8 || + mov->bits2.da1.src0_subreg_nr != 0 || + mov->bits2.da1.src0_abs != 0 || + mov->bits2.da1.src0_negate != 0) + return GL_FALSE; + + *grf_index = mov->bits2.da1.src0_reg_nr; + *mrf_index = mov->bits1.da1.dest_reg_nr & 0x0f; + *is_compr4 = (mov->bits1.da1.dest_reg_nr & BRW_MRF_COMPR4) != 0; + return GL_TRUE; +} + +static INLINE GLboolean +brw_is_grf_straight_write(const struct brw_instruction *inst, int grf_index) +{ + /* remark: no problem to predicate a SEL instruction */ + if ((!brw_is_predicated(inst) || inst->header.opcode == BRW_OPCODE_SEL) && + brw_is_control_done(inst) == GL_FALSE && + inst->header.execution_size == 4 && + inst->header.access_mode == BRW_ALIGN_1 && + inst->bits1.da1.dest_address_mode == BRW_ADDRESS_DIRECT && + inst->bits1.da1.dest_reg_file == BRW_GENERAL_REGISTER_FILE && + inst->bits1.da1.dest_reg_type == BRW_REGISTER_TYPE_F && + inst->bits1.da1.dest_horiz_stride == BRW_HORIZONTAL_STRIDE_1 && + inst->bits1.da1.dest_reg_nr == grf_index && + inst->bits1.da1.dest_subreg_nr == 0 && + brw_is_arithmetic_inst(inst)) + return GL_TRUE; + + return GL_FALSE; +} + +static INLINE GLboolean +brw_inst_are_equal(const struct brw_instruction *src0, + const struct brw_instruction *src1) +{ + const GLuint *field0 = (GLuint *) src0; + const GLuint *field1 = (GLuint *) src1; + return field0[0] == field1[0] && + field0[1] == field1[1] && + field0[2] == field1[2] && + field0[3] == field1[3]; +} + +static INLINE void +brw_inst_copy(struct brw_instruction *dst, + const struct brw_instruction *src) +{ + GLuint *field_dst = (GLuint *) dst; + const GLuint *field_src = (GLuint *) src; + field_dst[0] = field_src[0]; + field_dst[1] = field_src[1]; + field_dst[2] = field_src[2]; + field_dst[3] = field_src[3]; +} + +static void brw_remove_inst(struct brw_compile *p, const GLboolean *removeInst) +{ + int i, nr_insn = 0, to = 0, from = 0; + + for (from = 0; from < p->nr_insn; ++from) { + if (removeInst[from]) + continue; + if(to != from) + brw_inst_copy(p->store + to, p->store + from); + to++; + } + + for (i = 0; i < p->nr_insn; ++i) + if (removeInst[i] == GL_FALSE) + nr_insn++; + p->nr_insn = nr_insn; +} + +/* The gen code emitter generates a lot of duplications in the + * grf-to-mrf moves, for example when texture sampling with the same + * coordinates from multiple textures.. Here, we monitor same mov + * grf-to-mrf instrutions and remove repeated ones where the operands + * and dst ahven't changed in between. + */ +void brw_remove_duplicate_mrf_moves(struct brw_compile *p) +{ + const int gen = p->brw->intel.gen; + int i, j; + + GLboolean *removeInst = calloc(sizeof(GLboolean), p->nr_insn); + for (i = 0; i < p->nr_insn; i++) { + if (removeInst[i]) + continue; + + const struct brw_instruction *mov = p->store + i; + int mrf_index, grf_index; + GLboolean is_compr4; + + /* Only consider _straight_ grf-to-mrf moves */ + if (!brw_is_grf_to_mrf_mov(mov, &mrf_index, &grf_index, &is_compr4)) + continue; + + const int mrf_index0 = mrf_index; + const int mrf_index1 = is_compr4 ? mrf_index0+4 : mrf_index0+1; + const int simd16_size = 2 * REG_SIZE; + + for (j = i + 1; j < p->nr_insn; j++) { + const struct brw_instruction *inst = p->store + j; + + if (brw_inst_are_equal(mov, inst)) { + removeInst[j] = GL_TRUE; + continue; + } + + if (brw_is_grf_written(inst, grf_index, simd16_size, gen) || + brw_is_mrf_written(inst, mrf_index0, REG_SIZE) || + brw_is_mrf_written(inst, mrf_index1, REG_SIZE)) + break; + } + } + + brw_remove_inst(p, removeInst); + free(removeInst); +} + +/* Replace moves to MRFs where the value moved is the result of a + * normal arithmetic operation with computation right into the MRF. + */ +void brw_remove_grf_to_mrf_moves(struct brw_compile *p) +{ + int i, j, prev; + struct brw_context *brw = p->brw; + const int gen = brw->intel.gen; + const int simd16_size = 2*REG_SIZE; + + GLboolean *removeInst = calloc(sizeof(GLboolean), p->nr_insn); + assert(removeInst); + + for (i = 0; i < p->nr_insn; i++) { + if (removeInst[i]) + continue; + + struct brw_instruction *grf_inst = NULL; + const struct brw_instruction *mov = p->store + i; + int mrf_index, grf_index; + GLboolean is_compr4; + + /* Only consider _straight_ grf-to-mrf moves */ + if (!brw_is_grf_to_mrf_mov(mov, &mrf_index, &grf_index, &is_compr4)) + continue; + + /* Using comp4 enables a stride of 4 for this instruction */ + const int mrf_index0 = mrf_index; + const int mrf_index1 = is_compr4 ? mrf_index+4 : mrf_index+1; + + /* Look where the register has been set */ + prev = i; + GLboolean potential_remove = GL_FALSE; + while (prev--) { + + /* If _one_ instruction writes the grf, we try to remove the mov */ + struct brw_instruction *inst = p->store + prev; + if (brw_is_grf_straight_write(inst, grf_index)) { + potential_remove = GL_TRUE; + grf_inst = inst; + break; + } + + } + + if (potential_remove == GL_FALSE) + continue; + removeInst[i] = GL_TRUE; + + /* Monitor first the section of code between the grf computation and the + * mov. Here we cannot read or write both mrf and grf register + */ + for (j = prev + 1; j < i; ++j) { + struct brw_instruction *inst = p->store + j; + if (removeInst[j]) + continue; + if (brw_is_grf_written(inst, grf_index, simd16_size, gen) || + brw_is_grf_read(inst, grf_index, simd16_size) || + brw_is_mrf_written(inst, mrf_index0, REG_SIZE) || + brw_is_mrf_written(inst, mrf_index1, REG_SIZE) || + brw_is_mrf_read(inst, mrf_index0, REG_SIZE, gen) || + brw_is_mrf_read(inst, mrf_index1, REG_SIZE, gen)) { + removeInst[i] = GL_FALSE; + break; + } + } + + /* After the mov, we can read or write the mrf. If the grf is overwritten, + * we are done + */ + for (j = i + 1; j < p->nr_insn; ++j) { + struct brw_instruction *inst = p->store + j; + if (removeInst[j]) + continue; + + if (brw_is_grf_read(inst, grf_index, simd16_size)) { + removeInst[i] = GL_FALSE; + break; + } + + if (brw_is_grf_straight_write(inst, grf_index)) + break; + } + + /* Note that with the top down traversal, we can safely pacth the mov + * instruction + */ + if (removeInst[i]) { + grf_inst->bits1.da1.dest_reg_file = mov->bits1.da1.dest_reg_file; + grf_inst->bits1.da1.dest_reg_nr = mov->bits1.da1.dest_reg_nr; + } + } + + brw_remove_inst(p, removeInst); + free(removeInst); +} + static GLboolean is_single_channel_dp4(struct brw_instruction *insn) { diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index 40eece276b7..af08446f2d8 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -46,68 +46,68 @@ brw_add_validated_bo(struct brw_context *brw, drm_intel_bo *bo) } }; -const struct brw_tracked_state brw_blend_constant_color; -const struct brw_tracked_state brw_cc_unit; -const struct brw_tracked_state brw_check_fallback; -const struct brw_tracked_state brw_clip_prog; -const struct brw_tracked_state brw_clip_unit; -const struct brw_tracked_state brw_vs_constants; -const struct brw_tracked_state brw_wm_constants; -const struct brw_tracked_state brw_constant_buffer; -const struct brw_tracked_state brw_curbe_offsets; -const struct brw_tracked_state brw_invarient_state; -const struct brw_tracked_state brw_gs_prog; -const struct brw_tracked_state brw_gs_unit; -const struct brw_tracked_state brw_line_stipple; -const struct brw_tracked_state brw_aa_line_parameters; -const struct brw_tracked_state brw_pipelined_state_pointers; -const struct brw_tracked_state brw_binding_table_pointers; -const struct brw_tracked_state brw_depthbuffer; -const struct brw_tracked_state brw_polygon_stipple_offset; -const struct brw_tracked_state brw_polygon_stipple; -const struct brw_tracked_state brw_program_parameters; -const struct brw_tracked_state brw_recalculate_urb_fence; -const struct brw_tracked_state brw_sf_prog; -const struct brw_tracked_state brw_sf_unit; -const struct brw_tracked_state brw_sf_vp; -const struct brw_tracked_state brw_state_base_address; -const struct brw_tracked_state brw_urb_fence; -const struct brw_tracked_state brw_vertex_state; -const struct brw_tracked_state brw_vs_surfaces; -const struct brw_tracked_state brw_vs_prog; -const struct brw_tracked_state brw_vs_unit; -const struct brw_tracked_state brw_wm_input_sizes; -const struct brw_tracked_state brw_wm_prog; -const struct brw_tracked_state brw_wm_samplers; -const struct brw_tracked_state brw_wm_constant_surface; -const struct brw_tracked_state brw_wm_surfaces; -const struct brw_tracked_state brw_wm_binding_table; -const struct brw_tracked_state brw_wm_unit; - -const struct brw_tracked_state brw_psp_urb_cbs; - -const struct brw_tracked_state brw_pipe_control; - -const struct brw_tracked_state brw_drawing_rect; -const struct brw_tracked_state brw_indices; -const struct brw_tracked_state brw_vertices; -const struct brw_tracked_state brw_index_buffer; -const struct brw_tracked_state gen6_binding_table_pointers; -const struct brw_tracked_state gen6_blend_state; -const struct brw_tracked_state gen6_cc_state_pointers; -const struct brw_tracked_state gen6_clip_state; -const struct brw_tracked_state gen6_clip_vp; -const struct brw_tracked_state gen6_color_calc_state; -const struct brw_tracked_state gen6_depth_stencil_state; -const struct brw_tracked_state gen6_gs_state; -const struct brw_tracked_state gen6_sampler_state; -const struct brw_tracked_state gen6_scissor_state; -const struct brw_tracked_state gen6_sf_state; -const struct brw_tracked_state gen6_sf_vp; -const struct brw_tracked_state gen6_urb; -const struct brw_tracked_state gen6_viewport_state; -const struct brw_tracked_state gen6_vs_state; -const struct brw_tracked_state gen6_wm_state; +extern const struct brw_tracked_state brw_blend_constant_color; +extern const struct brw_tracked_state brw_cc_unit; +extern const struct brw_tracked_state brw_check_fallback; +extern const struct brw_tracked_state brw_clip_prog; +extern const struct brw_tracked_state brw_clip_unit; +extern const struct brw_tracked_state brw_vs_constants; +extern const struct brw_tracked_state brw_wm_constants; +extern const struct brw_tracked_state brw_constant_buffer; +extern const struct brw_tracked_state brw_curbe_offsets; +extern const struct brw_tracked_state brw_invarient_state; +extern const struct brw_tracked_state brw_gs_prog; +extern const struct brw_tracked_state brw_gs_unit; +extern const struct brw_tracked_state brw_line_stipple; +extern const struct brw_tracked_state brw_aa_line_parameters; +extern const struct brw_tracked_state brw_pipelined_state_pointers; +extern const struct brw_tracked_state brw_binding_table_pointers; +extern const struct brw_tracked_state brw_depthbuffer; +extern const struct brw_tracked_state brw_polygon_stipple_offset; +extern const struct brw_tracked_state brw_polygon_stipple; +extern const struct brw_tracked_state brw_program_parameters; +extern const struct brw_tracked_state brw_recalculate_urb_fence; +extern const struct brw_tracked_state brw_sf_prog; +extern const struct brw_tracked_state brw_sf_unit; +extern const struct brw_tracked_state brw_sf_vp; +extern const struct brw_tracked_state brw_state_base_address; +extern const struct brw_tracked_state brw_urb_fence; +extern const struct brw_tracked_state brw_vertex_state; +extern const struct brw_tracked_state brw_vs_surfaces; +extern const struct brw_tracked_state brw_vs_prog; +extern const struct brw_tracked_state brw_vs_unit; +extern const struct brw_tracked_state brw_wm_input_sizes; +extern const struct brw_tracked_state brw_wm_prog; +extern const struct brw_tracked_state brw_wm_samplers; +extern const struct brw_tracked_state brw_wm_constant_surface; +extern const struct brw_tracked_state brw_wm_surfaces; +extern const struct brw_tracked_state brw_wm_binding_table; +extern const struct brw_tracked_state brw_wm_unit; + +extern const struct brw_tracked_state brw_psp_urb_cbs; + +extern const struct brw_tracked_state brw_pipe_control; + +extern const struct brw_tracked_state brw_drawing_rect; +extern const struct brw_tracked_state brw_indices; +extern const struct brw_tracked_state brw_vertices; +extern const struct brw_tracked_state brw_index_buffer; +extern const struct brw_tracked_state gen6_binding_table_pointers; +extern const struct brw_tracked_state gen6_blend_state; +extern const struct brw_tracked_state gen6_cc_state_pointers; +extern const struct brw_tracked_state gen6_clip_state; +extern const struct brw_tracked_state gen6_clip_vp; +extern const struct brw_tracked_state gen6_color_calc_state; +extern const struct brw_tracked_state gen6_depth_stencil_state; +extern const struct brw_tracked_state gen6_gs_state; +extern const struct brw_tracked_state gen6_sampler_state; +extern const struct brw_tracked_state gen6_scissor_state; +extern const struct brw_tracked_state gen6_sf_state; +extern const struct brw_tracked_state gen6_sf_vp; +extern const struct brw_tracked_state gen6_urb; +extern const struct brw_tracked_state gen6_viewport_state; +extern const struct brw_tracked_state gen6_vs_state; +extern const struct brw_tracked_state gen6_wm_state; /*********************************************************************** * brw_state.c diff --git a/src/mesa/drivers/dri/i965/brw_util.c b/src/mesa/drivers/dri/i965/brw_util.c index 1db2a210d45..e878da3850d 100644 --- a/src/mesa/drivers/dri/i965/brw_util.c +++ b/src/mesa/drivers/dri/i965/brw_util.c @@ -30,6 +30,8 @@ */ +#include <assert.h> + #include "main/mtypes.h" #include "program/prog_parameter.h" #include "brw_util.h" diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index a1bee2e44ab..b6b558e9a69 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -44,6 +44,7 @@ static GLboolean brw_vs_arg_can_be_immediate(enum prog_opcode opcode, int arg) { int opcode_array[] = { + [OPCODE_MOV] = 1, [OPCODE_ADD] = 2, [OPCODE_CMP] = 3, [OPCODE_DP3] = 2, diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index 323cfac8fa7..d9fa2e63354 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -1283,7 +1283,7 @@ void emit_fb_write(struct brw_wm_compile *c, * + 1 for the second half we get destination + 4. */ brw_MOV(p, - brw_message_reg(nr + channel + (1 << 7)), + brw_message_reg(nr + channel + BRW_MRF_COMPR4), arg0[channel]); } else { /* mov (8) m2.0<1>:ud r28.0<8;8,1>:ud { Align1 } */ @@ -1712,12 +1712,20 @@ void brw_wm_emit( struct brw_wm_compile *c ) inst->dst[i]->spill_slot); } + /* Only properly tested on ILK */ + if (p->brw->intel.gen == 5) { + brw_remove_duplicate_mrf_moves(p); + if (c->dispatch_width == 16) + brw_remove_grf_to_mrf_moves(p); + } + if (INTEL_DEBUG & DEBUG_WM) { int i; - printf("wm-native:\n"); - for (i = 0; i < p->nr_insn; i++) + printf("wm-native:\n"); + for (i = 0; i < p->nr_insn; i++) brw_disasm(stderr, &p->store[i], p->brw->intel.gen); printf("\n"); } } + diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 5f2035d79c9..e19f44035fd 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -29,6 +29,7 @@ #include "main/glheader.h" #include "main/context.h" #include "main/extensions.h" +#include "main/fbobject.h" #include "main/framebuffer.h" #include "main/imports.h" #include "main/points.h" @@ -39,8 +40,6 @@ #include "drivers/common/driverfuncs.h" #include "drivers/common/meta.h" -#include "i830_dri.h" - #include "intel_chipset.h" #include "intel_buffers.h" #include "intel_tex.h" @@ -420,7 +419,7 @@ intel_prepare_render(struct intel_context *intel) __DRIdrawable *drawable; drawable = driContext->driDrawablePriv; - if (drawable->dri2.stamp != driContext->dri2.draw_stamp) { + if (drawable && drawable->dri2.stamp != driContext->dri2.draw_stamp) { if (drawable->lastStamp != drawable->dri2.stamp) intel_update_renderbuffers(driContext, drawable); intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer); @@ -428,7 +427,7 @@ intel_prepare_render(struct intel_context *intel) } drawable = driContext->driReadablePriv; - if (drawable->dri2.stamp != driContext->dri2.read_stamp) { + if (drawable && drawable->dri2.stamp != driContext->dri2.read_stamp) { if (drawable->lastStamp != drawable->dri2.stamp) intel_update_renderbuffers(driContext, drawable); driContext->dri2.read_stamp = drawable->dri2.stamp; @@ -613,6 +612,7 @@ intelInitContext(struct intel_context *intel, __DRIscreen *sPriv = driContextPriv->driScreenPriv; struct intel_screen *intelScreen = sPriv->private; int bo_reuse_mode; + __GLcontextModes visual; /* we can't do anything without a connection to the device */ if (intelScreen->bufmgr == NULL) @@ -624,6 +624,11 @@ intelInitContext(struct intel_context *intel, functions->Viewport = intel_viewport; } + if (mesaVis == NULL) { + memset(&visual, 0, sizeof visual); + mesaVis = &visual; + } + if (!_mesa_initialize_context_for_api(&intel->ctx, api, mesaVis, shareCtx, functions, (void *) intel)) { printf("%s: failed to init mesa context\n", __FUNCTION__); @@ -890,14 +895,21 @@ intelMakeCurrent(__DRIcontext * driContextPriv, } if (driContextPriv) { - struct gl_framebuffer *fb = driDrawPriv->driverPrivate; - struct gl_framebuffer *readFb = driReadPriv->driverPrivate; + struct gl_framebuffer *fb, *readFb; + + if (driDrawPriv == NULL && driReadPriv == NULL) { + fb = _mesa_get_incomplete_framebuffer(); + readFb = _mesa_get_incomplete_framebuffer(); + } else { + fb = driDrawPriv->driverPrivate; + readFb = driReadPriv->driverPrivate; + driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1; + driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1; + } - driContextPriv->dri2.draw_stamp = driDrawPriv->dri2.stamp - 1; - driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1; intel_prepare_render(intel); _mesa_make_current(&intel->ctx, fb, readFb); - + /* We do this in intel_prepare_render() too, but intel->ctx.DrawBuffer * is NULL at that point. We can't call _mesa_makecurrent() * first, since we need the buffer size for the initial diff --git a/src/mesa/drivers/dri/intel/intel_extensions_es2.c b/src/mesa/drivers/dri/intel/intel_extensions_es2.c index baf8e130010..de34bbb2aec 100644 --- a/src/mesa/drivers/dri/intel/intel_extensions_es2.c +++ b/src/mesa/drivers/dri/intel/intel_extensions_es2.c @@ -28,7 +28,6 @@ #include "main/extensions.h" #include "intel_extensions.h" -#include "utils.h" static const char *es2_extensions[] = { /* Used by mesa internally (cf all_mesa_extensions in ../common/utils.c) */ diff --git a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c index 0e2fe893fed..02c0ffce31d 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c @@ -45,6 +45,7 @@ #include "main/attrib.h" #include "main/enable.h" #include "main/viewport.h" +#include "main/context.h" #include "swrast/swrast.h" #include "intel_screen.h" diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index fe4de189600..680d18ba299 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -155,6 +155,9 @@ intel_region_alloc_internal(struct intel_context *intel, } region = calloc(sizeof(*region), 1); + if (region == NULL) + return region; + region->cpp = cpp; region->width = width; region->height = height; @@ -189,6 +192,9 @@ intel_region_alloc(struct intel_context *intel, region = intel_region_alloc_internal(intel, cpp, width, height, aligned_pitch / cpp, buffer); + if (region == NULL) + return region; + region->tiling = tiling; return region; diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 224b506c05b..6efb2ddc553 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -102,7 +102,7 @@ do_copy_texsubimage(struct intel_context *intel, GLcontext *ctx = &intel->ctx; const struct intel_region *src = get_teximage_source(intel, internalFormat); - if (!intelImage->mt || !src) { + if (!intelImage->mt || !src || !src->buffer) { if (INTEL_DEBUG & DEBUG_FALLBACKS) fprintf(stderr, "%s fail %p %p (0x%08x)\n", __FUNCTION__, intelImage->mt, src, internalFormat); diff --git a/src/mesa/drivers/dri/intel/intel_tex_format.c b/src/mesa/drivers/dri/intel/intel_tex_format.c index 5f813c0efa2..e03b203fb40 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_format.c +++ b/src/mesa/drivers/dri/intel/intel_tex_format.c @@ -19,7 +19,6 @@ intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat, GLenum format, GLenum type) { struct intel_context *intel = intel_context(ctx); - const GLboolean do32bpt = (intel->ctx.Visual.rgbBits >= 24); #if 0 printf("%s intFmt=0x%x format=0x%x type=0x%x\n", @@ -30,39 +29,28 @@ intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat, case 4: case GL_RGBA: case GL_COMPRESSED_RGBA: - if (format == GL_BGRA) { - if (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT_8_8_8_8_REV) { - return MESA_FORMAT_ARGB8888; - } - else if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) { - return MESA_FORMAT_ARGB4444; - } - else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { - return MESA_FORMAT_ARGB1555; - } - } - return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444; + if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) + return MESA_FORMAT_ARGB4444; + else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) + return MESA_FORMAT_ARGB1555; + else + return MESA_FORMAT_ARGB8888; case 3: case GL_RGB: case GL_COMPRESSED_RGB: - if (format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5) { - return MESA_FORMAT_RGB565; - } - if (do32bpt) { - if (intel->has_xrgb_textures) - return MESA_FORMAT_XRGB8888; - else - return MESA_FORMAT_ARGB8888; - } else { + if (type == GL_UNSIGNED_SHORT_5_6_5) return MESA_FORMAT_RGB565; - } + else if (intel->has_xrgb_textures) + return MESA_FORMAT_XRGB8888; + else + return MESA_FORMAT_ARGB8888; case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: case GL_RGBA16: - return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444; + return MESA_FORMAT_ARGB8888; case GL_RGBA4: case GL_RGBA2: diff --git a/src/mesa/drivers/dri/intel/server/i830_dri.h b/src/mesa/drivers/dri/intel/server/i830_dri.h deleted file mode 100644 index def049e7a6b..00000000000 --- a/src/mesa/drivers/dri/intel/server/i830_dri.h +++ /dev/null @@ -1,62 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i810/i830_dri.h,v 1.6 2003/09/28 20:15:59 alanh Exp $ */ - -#ifndef _I830_DRI_H -#define _I830_DRI_H - -#include "xf86drm.h" - -#define I830_MAX_DRAWABLES 256 - -#define I830_MAJOR_VERSION 1 -#define I830_MINOR_VERSION 9 -#define I830_PATCHLEVEL 0 - -#define I830_REG_SIZE 0x80000 - -typedef struct _I830DRIRec { - drm_handle_t regs; - drmSize regsSize; - - drmSize unused1; /* backbufferSize */ - drm_handle_t unused2; /* backbuffer */ - - drmSize unused3; /* depthbufferSize */ - drm_handle_t unused4; /* depthbuffer */ - - drmSize unused5; /* rotatedSize */ - drm_handle_t unused6; /* rotatedbuffer */ - - drm_handle_t unused7; /* textures */ - int unused8; /* textureSize */ - - drm_handle_t unused9; /* agp_buffers */ - drmSize unused10; /* agp_buf_size */ - - int deviceID; - int width; - int height; - int mem; - int cpp; - int bitsPerPixel; - - int unused11[8]; /* was front/back/depth/rotated offset/pitch */ - - int unused12; /* logTextureGranularity */ - int unused13; /* textureOffset */ - - int irq; - int sarea_priv_offset; -} I830DRIRec, *I830DRIPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830ConfigPrivRec, *I830ConfigPrivPtr; - -typedef struct { - /* Nothing here yet */ - int dummy; -} I830DRIContextRec, *I830DRIContextPtr; - - -#endif diff --git a/src/mesa/drivers/dri/intel/server/intel.h b/src/mesa/drivers/dri/intel/server/intel.h deleted file mode 100644 index 6ea72499c1c..00000000000 --- a/src/mesa/drivers/dri/intel/server/intel.h +++ /dev/null @@ -1,331 +0,0 @@ -#ifndef _INTEL_H_ -#define _INTEL_H_ - -#include "xf86drm.h" /* drm_handle_t, etc */ - -/* Intel */ -#ifndef PCI_CHIP_I810 -#define PCI_CHIP_I810 0x7121 -#define PCI_CHIP_I810_DC100 0x7123 -#define PCI_CHIP_I810_E 0x7125 -#define PCI_CHIP_I815 0x1132 -#define PCI_CHIP_I810_BRIDGE 0x7120 -#define PCI_CHIP_I810_DC100_BRIDGE 0x7122 -#define PCI_CHIP_I810_E_BRIDGE 0x7124 -#define PCI_CHIP_I815_BRIDGE 0x1130 -#endif - -#define PCI_CHIP_845_G 0x2562 -#define PCI_CHIP_I830_M 0x3577 - -#ifndef PCI_CHIP_I855_GM -#define PCI_CHIP_I855_GM 0x3582 -#define PCI_CHIP_I855_GM_BRIDGE 0x3580 -#endif - -#ifndef PCI_CHIP_I865_G -#define PCI_CHIP_I865_G 0x2572 -#define PCI_CHIP_I865_G_BRIDGE 0x2570 -#endif - -#ifndef PCI_CHIP_I915_G -#define PCI_CHIP_I915_G 0x2582 -#define PCI_CHIP_I915_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I915_GM -#define PCI_CHIP_I915_GM 0x2592 -#define PCI_CHIP_I915_GM_BRIDGE 0x2590 -#endif - -#ifndef PCI_CHIP_E7221_G -#define PCI_CHIP_E7221_G 0x258A -/* Same as I915_G_BRIDGE */ -#define PCI_CHIP_E7221_G_BRIDGE 0x2580 -#endif - -#ifndef PCI_CHIP_I945_G -#define PCI_CHIP_I945_G 0x2772 -#define PCI_CHIP_I945_G_BRIDGE 0x2770 -#endif - -#ifndef PCI_CHIP_I945_GM -#define PCI_CHIP_I945_GM 0x27A2 -#define PCI_CHIP_I945_GM_BRIDGE 0x27A0 -#endif - -#define IS_I810(pI810) (pI810->Chipset == PCI_CHIP_I810 || \ - pI810->Chipset == PCI_CHIP_I810_DC100 || \ - pI810->Chipset == PCI_CHIP_I810_E) -#define IS_I815(pI810) (pI810->Chipset == PCI_CHIP_I815) -#define IS_I830(pI810) (pI810->Chipset == PCI_CHIP_I830_M) -#define IS_845G(pI810) (pI810->Chipset == PCI_CHIP_845_G) -#define IS_I85X(pI810) (pI810->Chipset == PCI_CHIP_I855_GM) -#define IS_I852(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I852_GM || pI810->variant == I852_GME)) -#define IS_I855(pI810) (pI810->Chipset == PCI_CHIP_I855_GM && (pI810->variant == I855_GM || pI810->variant == I855_GME)) -#define IS_I865G(pI810) (pI810->Chipset == PCI_CHIP_I865_G) - -#define IS_I915G(pI810) (pI810->Chipset == PCI_CHIP_I915_G || pI810->Chipset == PCI_CHIP_E7221_G) -#define IS_I915GM(pI810) (pI810->Chipset == PCI_CHIP_I915_GM) -#define IS_I945G(pI810) (pI810->Chipset == PCI_CHIP_I945_G) -#define IS_I945GM(pI810) (pI810->Chipset == PCI_CHIP_I945_GM) -#define IS_I9XX(pI810) (IS_I915G(pI810) || IS_I915GM(pI810) || IS_I945G(pI810) || IS_I945GM(pI810)) - -#define IS_MOBILE(pI810) (IS_I830(pI810) || IS_I85X(pI810) || IS_I915GM(pI810) || IS_I945GM(pI810)) - -#define I830_GMCH_CTRL 0x52 - -#define I830_GMCH_MEM_MASK 0x1 -#define I830_GMCH_MEM_64M 0x1 -#define I830_GMCH_MEM_128M 0 - -#define I830_GMCH_GMS_MASK 0x70 -#define I830_GMCH_GMS_DISABLED 0x00 -#define I830_GMCH_GMS_LOCAL 0x10 -#define I830_GMCH_GMS_STOLEN_512 0x20 -#define I830_GMCH_GMS_STOLEN_1024 0x30 -#define I830_GMCH_GMS_STOLEN_8192 0x40 - -#define I855_GMCH_GMS_MASK (0x7 << 4) -#define I855_GMCH_GMS_DISABLED 0x00 -#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4) -#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4) -#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4) -#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4) -#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4) -#define I915G_GMCH_GMS_STOLEN_48M (0x6 << 4) -#define I915G_GMCH_GMS_STOLEN_64M (0x7 << 4) - -typedef unsigned char Bool; -#define TRUE 1 -#define FALSE 0 - -#define PIPE_NONE 0<<0 -#define PIPE_CRT 1<<0 -#define PIPE_TV 1<<1 -#define PIPE_DFP 1<<2 -#define PIPE_LFP 1<<3 -#define PIPE_CRT2 1<<4 -#define PIPE_TV2 1<<5 -#define PIPE_DFP2 1<<6 -#define PIPE_LFP2 1<<7 - -typedef struct _I830MemPool *I830MemPoolPtr; -typedef struct _I830MemRange *I830MemRangePtr; -typedef struct _I830MemRange { - long Start; - long End; - long Size; - unsigned long Physical; - unsigned long Offset; /* Offset of AGP-allocated portion */ - unsigned long Alignment; - drm_handle_t Key; - unsigned long Pitch; // add pitch - I830MemPoolPtr Pool; -} I830MemRange; - -typedef struct _I830MemPool { - I830MemRange Total; - I830MemRange Free; - I830MemRange Fixed; - I830MemRange Allocated; -} I830MemPool; - -typedef struct { - int tail_mask; - I830MemRange mem; - unsigned char *virtual_start; - int head; - int tail; - int space; -} I830RingBuffer; - -typedef struct _I830Rec { - unsigned char *MMIOBase; - unsigned char *FbBase; - int cpp; - uint32_t aper_size; - unsigned int bios_version; - - /* These are set in PreInit and never changed. */ - long FbMapSize; - long TotalVideoRam; - I830MemRange StolenMemory; /* pre-allocated memory */ - long BIOSMemorySize; /* min stolen pool size */ - int BIOSMemSizeLoc; - - /* These change according to what has been allocated. */ - long FreeMemory; - I830MemRange MemoryAperture; - I830MemPool StolenPool; - long allocatedMemory; - - /* Regions allocated either from the above pools, or from agpgart. */ - /* for single and dual head configurations */ - I830MemRange FrontBuffer; - I830MemRange FrontBuffer2; - I830MemRange Scratch; - I830MemRange Scratch2; - - I830RingBuffer *LpRing; - - I830MemRange BackBuffer; - I830MemRange DepthBuffer; - I830MemRange TexMem; - int TexGranularity; - I830MemRange ContextMem; - int drmMinor; - Bool have3DWindows; - - Bool NeedRingBufferLow; - Bool allowPageFlip; - Bool disableTiling; - - int Chipset; - unsigned long LinearAddr; - unsigned long MMIOAddr; - - drmSize registerSize; /**< \brief MMIO register map size */ - drm_handle_t registerHandle; /**< \brief MMIO register map handle */ - // IOADDRESS ioBase; - int irq; /**< \brief IRQ number */ - int GttBound; - - drm_handle_t ring_map; - unsigned int Fence[8]; - -} I830Rec; - -/* - * 12288 is set as the maximum, chosen because it is enough for - * 1920x1440@32bpp with a 2048 pixel line pitch with some to spare. - */ -#define I830_MAXIMUM_VBIOS_MEM 12288 -#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024) -#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024) - -/* Flags for memory allocation function */ -#define FROM_ANYWHERE 0x00000000 -#define FROM_POOL_ONLY 0x00000001 -#define FROM_NEW_ONLY 0x00000002 -#define FROM_MASK 0x0000000f - -#define ALLOCATE_AT_TOP 0x00000010 -#define ALLOCATE_AT_BOTTOM 0x00000020 -#define FORCE_GAPS 0x00000040 - -#define NEED_PHYSICAL_ADDR 0x00000100 -#define ALIGN_BOTH_ENDS 0x00000200 -#define FORCE_LOW 0x00000400 - -#define ALLOC_NO_TILING 0x00001000 -#define ALLOC_INITIAL 0x00002000 - -#define ALLOCATE_DRY_RUN 0x80000000 - -/* Chipset registers for VIDEO BIOS memory RW access */ -#define _855_DRAM_RW_CONTROL 0x58 -#define _845_DRAM_RW_CONTROL 0x90 -#define DRAM_WRITE 0x33330000 - -#define KB(x) ((x) * 1024) -#define MB(x) ((x) * KB(1024)) - -#define GTT_PAGE_SIZE KB(4) -#define ROUND_TO(x, y) (((x) + (y) - 1) / (y) * (y)) -#define ROUND_DOWN_TO(x, y) ((x) / (y) * (y)) -#define ROUND_TO_PAGE(x) ROUND_TO((x), GTT_PAGE_SIZE) -#define ROUND_TO_MB(x) ROUND_TO((x), MB(1)) -#define PRIMARY_RINGBUFFER_SIZE KB(128) - - -/* Ring buffer registers, p277, overview p19 - */ -#define LP_RING 0x2030 -#define HP_RING 0x2040 - -#define RING_TAIL 0x00 -#define TAIL_ADDR 0x000FFFF8 -#define I830_TAIL_MASK 0x001FFFF8 - -#define RING_HEAD 0x04 -#define HEAD_WRAP_COUNT 0xFFE00000 -#define HEAD_WRAP_ONE 0x00200000 -#define HEAD_ADDR 0x001FFFFC -#define I830_HEAD_MASK 0x001FFFFC - -#define RING_START 0x08 -#define START_ADDR 0x03FFFFF8 -#define I830_RING_START_MASK 0xFFFFF000 - -#define RING_LEN 0x0C -#define RING_NR_PAGES 0x001FF000 -#define I830_RING_NR_PAGES 0x001FF000 -#define RING_REPORT_MASK 0x00000006 -#define RING_REPORT_64K 0x00000002 -#define RING_REPORT_128K 0x00000004 -#define RING_NO_REPORT 0x00000000 -#define RING_VALID_MASK 0x00000001 -#define RING_VALID 0x00000001 -#define RING_INVALID 0x00000000 - - -/* Fence/Tiling ranges [0..7] - */ -#define FENCE 0x2000 -#define FENCE_NR 8 - -#define I915G_FENCE_START_MASK 0x0ff00000 - -#define I830_FENCE_START_MASK 0x07f80000 - -#define FENCE_START_MASK 0x03F80000 -#define FENCE_X_MAJOR 0x00000000 -#define FENCE_Y_MAJOR 0x00001000 -#define FENCE_SIZE_MASK 0x00000700 -#define FENCE_SIZE_512K 0x00000000 -#define FENCE_SIZE_1M 0x00000100 -#define FENCE_SIZE_2M 0x00000200 -#define FENCE_SIZE_4M 0x00000300 -#define FENCE_SIZE_8M 0x00000400 -#define FENCE_SIZE_16M 0x00000500 -#define FENCE_SIZE_32M 0x00000600 -#define FENCE_SIZE_64M 0x00000700 -#define I915G_FENCE_SIZE_1M 0x00000000 -#define I915G_FENCE_SIZE_2M 0x00000100 -#define I915G_FENCE_SIZE_4M 0x00000200 -#define I915G_FENCE_SIZE_8M 0x00000300 -#define I915G_FENCE_SIZE_16M 0x00000400 -#define I915G_FENCE_SIZE_32M 0x00000500 -#define I915G_FENCE_SIZE_64M 0x00000600 -#define I915G_FENCE_SIZE_128M 0x00000700 -#define FENCE_PITCH_1 0x00000000 -#define FENCE_PITCH_2 0x00000010 -#define FENCE_PITCH_4 0x00000020 -#define FENCE_PITCH_8 0x00000030 -#define FENCE_PITCH_16 0x00000040 -#define FENCE_PITCH_32 0x00000050 -#define FENCE_PITCH_64 0x00000060 -#define FENCE_VALID 0x00000001 - -#include <mmio.h> - -# define MMIO_IN8(base, offset) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) -# define MMIO_IN32(base, offset) \ - read_MMIO_LE32(base, offset) -# define MMIO_OUT8(base, offset, val) \ - *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) -# define MMIO_OUT32(base, offset, val) \ - *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = CPU_TO_LE32(val) - - - /* Memory mapped register access macros */ -#define INREG8(addr) MMIO_IN8(MMIO, addr) -#define INREG(addr) MMIO_IN32(MMIO, addr) -#define OUTREG8(addr, val) MMIO_OUT8(MMIO, addr, val) -#define OUTREG(addr, val) MMIO_OUT32(MMIO, addr, val) - -#define DSPABASE 0x70184 - -#endif diff --git a/src/mesa/drivers/dri/mach64/mach64_ioctl.h b/src/mesa/drivers/dri/mach64/mach64_ioctl.h index 1ffda1932f1..9145ee6e6cf 100644 --- a/src/mesa/drivers/dri/mach64/mach64_ioctl.h +++ b/src/mesa/drivers/dri/mach64/mach64_ioctl.h @@ -32,6 +32,9 @@ #ifndef __MACH64_IOCTL_H__ #define __MACH64_IOCTL_H__ +#include <stdio.h> +#include <stdlib.h> + #include "mach64_dri.h" #include "mach64_reg.h" #include "mach64_lock.h" diff --git a/src/mesa/drivers/dri/mga/mgarender.c b/src/mesa/drivers/dri/mga/mgarender.c index 8b8fc485d31..cc0cea618d1 100644 --- a/src/mesa/drivers/dri/mga/mgarender.c +++ b/src/mesa/drivers/dri/mga/mgarender.c @@ -44,6 +44,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/imports.h" #include "main/mtypes.h" +#include "math/m_xform.h" + #include "tnl/t_context.h" #include "mgacontext.h" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c index 8be7edb150b..bd1273beea7 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_fbo.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_fbo.c @@ -220,7 +220,7 @@ get_tex_format(struct gl_texture_image *ti) case MESA_FORMAT_RGB565: return GL_RGB5; default: - assert(0); + return GL_NONE; } } @@ -231,7 +231,6 @@ nouveau_render_texture(GLcontext *ctx, struct gl_framebuffer *fb, struct gl_renderbuffer *rb = att->Renderbuffer; struct gl_texture_image *ti = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; - int ret; /* Allocate a renderbuffer object for the texture if we * haven't already done so. */ @@ -244,9 +243,7 @@ nouveau_render_texture(GLcontext *ctx, struct gl_framebuffer *fb, } /* Update the renderbuffer fields from the texture. */ - ret = set_renderbuffer_format(rb, get_tex_format(ti)); - assert(ret); - + set_renderbuffer_format(rb, get_tex_format(ti)); rb->Width = ti->Width; rb->Height = ti->Height; nouveau_surface_ref(&to_nouveau_teximage(ti)->surface, diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c b/src/mesa/drivers/dri/nouveau/nouveau_texture.c index dbf9a5cc613..442f4e899ee 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_texture.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c @@ -38,6 +38,7 @@ #include "main/mipmap.h" #include "main/texfetch.h" #include "main/teximage.h" +#include "drivers/common/meta.h" static struct gl_texture_object * nouveau_texture_new(GLcontext *ctx, GLuint name, GLenum target) @@ -182,10 +183,10 @@ teximage_fits(struct gl_texture_object *t, int level) struct nouveau_surface *s = &to_nouveau_texture(t)->surfaces[level]; struct gl_texture_image *ti = t->Image[0][level]; - return ti && (t->Target == GL_TEXTURE_RECTANGLE || - (s->bo && s->width == ti->Width && - s->height == ti->Height && - s->format == ti->TexFormat)); + return ti && to_nouveau_teximage(ti)->surface.bo && + (t->Target == GL_TEXTURE_RECTANGLE || + (s->bo && s->format == ti->TexFormat && + s->width == ti->Width && s->height == ti->Height)); } static GLboolean @@ -589,6 +590,53 @@ nouveau_texture_unmap(GLcontext *ctx, struct gl_texture_object *t) } } +static void +store_mipmap(GLcontext *ctx, GLenum target, int first, int last, + struct gl_texture_object *t) +{ + struct gl_pixelstore_attrib packing = { + .BufferObj = ctx->Shared->NullBufferObj, + .Alignment = 1 + }; + GLenum format = t->Image[0][first]->TexFormat; + unsigned base_format, type, comps; + int i; + + base_format = _mesa_get_format_base_format(format); + _mesa_format_to_type_and_comps(format, &type, &comps); + + for (i = first; i <= last; i++) { + struct gl_texture_image *ti = t->Image[0][i]; + void *data = ti->Data; + + nouveau_teximage(ctx, 3, target, i, ti->InternalFormat, + ti->Width, ti->Height, ti->Depth, + ti->Border, base_format, type, data, + &packing, t, ti); + + _mesa_free_texmemory(data); + } +} + +static void +nouveau_generate_mipmap(GLcontext *ctx, GLenum target, + struct gl_texture_object *t) +{ + if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, t)) { + struct gl_texture_image *base = t->Image[0][t->BaseLevel]; + + nouveau_teximage_map(ctx, base); + _mesa_generate_mipmap(ctx, target, t); + nouveau_teximage_unmap(ctx, base); + + store_mipmap(ctx, target, t->BaseLevel + 1, + get_last_level(t), t); + + } else { + _mesa_meta_GenerateMipmap(ctx, target, t); + } +} + void nouveau_texture_functions_init(struct dd_function_table *functions) { @@ -607,4 +655,5 @@ nouveau_texture_functions_init(struct dd_function_table *functions) functions->BindTexture = nouveau_bind_texture; functions->MapTexture = nouveau_texture_map; functions->UnmapTexture = nouveau_texture_unmap; + functions->GenerateMipmap = nouveau_generate_mipmap; } diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_fb.c b/src/mesa/drivers/dri/nouveau/nv20_state_fb.c index 21da4f7af16..95691cad047 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state_fb.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state_fb.c @@ -72,7 +72,7 @@ nv20_emit_framebuffer(GLcontext *ctx, int emit) fb->_ColorDrawBuffers[0])->surface; rt_format |= get_rt_format(s->format); - zeta_pitch = rt_pitch = s->pitch; + rt_pitch = s->pitch; nouveau_bo_markl(bctx, kelvin, NV20TCL_COLOR_OFFSET, s->bo, 0, bo_flags); @@ -88,6 +88,9 @@ nv20_emit_framebuffer(GLcontext *ctx, int emit) nouveau_bo_markl(bctx, kelvin, NV20TCL_ZETA_OFFSET, s->bo, 0, bo_flags); + } else { + rt_format |= get_rt_format(MESA_FORMAT_Z24_S8); + zeta_pitch = rt_pitch; } BEGIN_RING(chan, kelvin, NV20TCL_RT_FORMAT, 2); diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tex.c b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c index e46118e4fce..2d45513bb4c 100644 --- a/src/mesa/drivers/dri/nouveau/nv20_state_tex.c +++ b/src/mesa/drivers/dri/nouveau/nv20_state_tex.c @@ -194,7 +194,8 @@ nv20_emit_tex_obj(GLcontext *ctx, int emit) | nvgl_wrap_mode(t->WrapS) << 0; tx_filter = nvgl_filter_mode(t->MagFilter) << 24 - | nvgl_filter_mode(t->MinFilter) << 16; + | nvgl_filter_mode(t->MinFilter) << 16 + | 2 << 12; tx_enable = NV20TCL_TX_ENABLE_ENABLE | log2i(t->MaxAnisotropy) << 4; diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c index 262fe3cddee..dbf4ad477db 100644 --- a/src/mesa/drivers/dri/r200/r200_swtcl.c +++ b/src/mesa/drivers/dri/r200/r200_swtcl.c @@ -612,6 +612,8 @@ static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); + radeon_prepare_render(&rmesa->radeon); + if (rmesa->radeon.swtcl.hw_primitive != hwprim) { /* need to disable perspective-correct texturing for point sprites */ if ((hwprim & 0xf) == R200_VF_PRIM_POINT_SPRITES && ctx->Point.PointSprite) { diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index d43e14581e9..4ae0f304918 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -264,6 +264,8 @@ void r200TclPrimitive( GLcontext *ctx, r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint newprim = hw_prim | R200_VF_TCL_OUTPUT_VTX_ENABLE; + radeon_prepare_render(&rmesa->radeon); + if (newprim != rmesa->tcl.hw_primitive || !discrete_prim[hw_prim&0xf]) { /* need to disable perspective-correct texturing for point sprites */ diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c index a326ee4c4fa..d2fa816894c 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c @@ -109,13 +109,13 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) debug_program_log(c, "before compilation"); if (c->Base.is_r500){ - r500_transform_unroll_loops(&c->Base, &loop_state); - debug_program_log(c, "after r500 transform loops"); + rc_unroll_loops(&c->Base, R500_PFS_MAX_INST); + debug_program_log(c, "after unroll loops"); } else{ - rc_transform_unroll_loops(&c->Base, &loop_state); + rc_transform_loops(&c->Base, &loop_state, -1); debug_program_log(c, "after transform loops"); - + rc_emulate_branches(&c->Base); debug_program_log(c, "after emulate branches"); } diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c index d347b4df9cd..666c9c2a7a9 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c @@ -32,6 +32,11 @@ #include "radeon_emulate_branches.h" #include "radeon_emulate_loops.h" +struct loop { + int BgnLoop; + +}; + /* * Take an already-setup and valid source then swizzle it appropriately to * obtain a constant ZERO or ONE source. @@ -332,11 +337,140 @@ static void ei_pow(struct r300_vertex_program_code *vp, inst[3] = t_src_scalar(vp, &vpi->SrcReg[1]); } +static void mark_write(void * userdata, struct rc_instruction * inst, + rc_register_file file, unsigned int index, unsigned int mask) +{ + unsigned int * writemasks = userdata; + + if (file != RC_FILE_TEMPORARY) + return; + + if (index >= R300_VS_MAX_TEMPS) + return; + + writemasks[index] |= mask; +} + +static unsigned long t_pred_src(struct r300_vertex_program_compiler * compiler) +{ + return PVS_SRC_OPERAND(compiler->PredicateIndex, + t_swizzle(RC_SWIZZLE_ZERO), + t_swizzle(RC_SWIZZLE_ZERO), + t_swizzle(RC_SWIZZLE_ZERO), + t_swizzle(RC_SWIZZLE_W), + t_src_class(RC_FILE_TEMPORARY), + 0); +} + +static unsigned long t_pred_dst(struct r300_vertex_program_compiler * compiler, + unsigned int hw_opcode, int is_math) +{ + return PVS_OP_DST_OPERAND(hw_opcode, + is_math, + 0, + compiler->PredicateIndex, + RC_MASK_W, + t_dst_class(RC_FILE_TEMPORARY)); + +} + +static void ei_if(struct r300_vertex_program_compiler * compiler, + struct rc_instruction *rci, + unsigned int * inst, + unsigned int branch_depth) +{ + unsigned int predicate_opcode; + int is_math = 0; + + if (!compiler->Base.is_r500) { + rc_error(&compiler->Base,"Opcode IF not supported\n"); + return; + } + + /* Reserve a temporary to use as our predicate stack counter, if we + * don't already have one. */ + if (!compiler->PredicateMask) { + unsigned int writemasks[R300_VS_MAX_TEMPS]; + memset(writemasks, 0, sizeof(writemasks)); + struct rc_instruction * inst; + unsigned int i; + for(inst = compiler->Base.Program.Instructions.Next; + inst != &compiler->Base.Program.Instructions; + inst = inst->Next) { + rc_for_all_writes_mask(inst, mark_write, writemasks); + } + for(i = 0; i < R300_VS_MAX_TEMPS; i++) { + unsigned int mask = ~writemasks[i] & RC_MASK_XYZW; + /* Only the W component can be used fo the predicate + * stack counter. */ + if (mask & RC_MASK_W) { + compiler->PredicateMask = RC_MASK_W; + compiler->PredicateIndex = i; + break; + } + } + if (i == R300_VS_MAX_TEMPS) { + rc_error(&compiler->Base, "No free temporary to use for" + " predicate stack counter.\n"); + return; + } + } + predicate_opcode = + branch_depth ? VE_PRED_SET_NEQ_PUSH : ME_PRED_SET_NEQ; + + rci->U.I.SrcReg[0].Swizzle = RC_MAKE_SWIZZLE_SMEAR(GET_SWZ(rci->U.I.SrcReg[0].Swizzle,0)); + if (branch_depth == 0) { + is_math = 1; + predicate_opcode = ME_PRED_SET_NEQ; + inst[1] = t_src(compiler->code, &rci->U.I.SrcReg[0]); + inst[2] = 0; + } else { + predicate_opcode = VE_PRED_SET_NEQ_PUSH; + inst[1] = t_pred_src(compiler); + inst[2] = t_src(compiler->code, &rci->U.I.SrcReg[0]); + } + + inst[0] = t_pred_dst(compiler, predicate_opcode, is_math); + inst[3] = 0; + +} + +static void ei_else(struct r300_vertex_program_compiler * compiler, + unsigned int * inst) +{ + if (!compiler->Base.is_r500) { + rc_error(&compiler->Base,"Opcode ELSE not supported\n"); + return; + } + inst[0] = t_pred_dst(compiler, ME_PRED_SET_INV, 1); + inst[1] = t_pred_src(compiler); + inst[2] = 0; + inst[3] = 0; +} + +static void ei_endif(struct r300_vertex_program_compiler *compiler, + unsigned int * inst) +{ + if (!compiler->Base.is_r500) { + rc_error(&compiler->Base,"Opcode ENDIF not supported\n"); + return; + } + inst[0] = t_pred_dst(compiler, ME_PRED_SET_POP, 1); + inst[1] = t_pred_src(compiler); + inst[2] = 0; + inst[3] = 0; +} static void translate_vertex_program(struct r300_vertex_program_compiler * compiler) { struct rc_instruction *rci; + struct loop * loops; + int current_loop_depth = 0; + int loops_reserved = 0; + + unsigned int branch_depth = 0; + compiler->code->pos_end = 0; /* Not supported yet */ compiler->code->length = 0; @@ -366,9 +500,12 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi case RC_OPCODE_COS: ei_math1(compiler->code, ME_COS, vpi, inst); break; case RC_OPCODE_DP4: ei_vector2(compiler->code, VE_DOT_PRODUCT, vpi, inst); break; case RC_OPCODE_DST: ei_vector2(compiler->code, VE_DISTANCE_VECTOR, vpi, inst); break; + case RC_OPCODE_ELSE: ei_else(compiler, inst); break; + case RC_OPCODE_ENDIF: ei_endif(compiler, inst); branch_depth--; break; case RC_OPCODE_EX2: ei_math1(compiler->code, ME_EXP_BASE2_FULL_DX, vpi, inst); break; case RC_OPCODE_EXP: ei_math1(compiler->code, ME_EXP_BASE2_DX, vpi, inst); break; case RC_OPCODE_FRC: ei_vector1(compiler->code, VE_FRACTION, vpi, inst); break; + case RC_OPCODE_IF: ei_if(compiler, rci, inst, branch_depth); branch_depth++; break; case RC_OPCODE_LG2: ei_math1(compiler->code, ME_LOG_BASE2_FULL_DX, vpi, inst); break; case RC_OPCODE_LIT: ei_lit(compiler->code, vpi, inst); break; case RC_OPCODE_LOG: ei_math1(compiler->code, ME_LOG_BASE2_DX, vpi, inst); break; @@ -385,11 +522,86 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi case RC_OPCODE_SIN: ei_math1(compiler->code, ME_SIN, vpi, inst); break; case RC_OPCODE_SLT: ei_vector2(compiler->code, VE_SET_LESS_THAN, vpi, inst); break; case RC_OPCODE_SNE: ei_vector2(compiler->code, VE_SET_NOT_EQUAL, vpi, inst); break; + case RC_OPCODE_BGNLOOP: + { + struct loop * l; + + if ((!compiler->Base.is_r500 + && loops_reserved >= R300_VS_MAX_LOOP_DEPTH) + || loops_reserved >= R500_VS_MAX_FC_DEPTH) { + rc_error(&compiler->Base, + "Loops are nested too deep."); + return; + } + memory_pool_array_reserve(&compiler->Base.Pool, + struct loop, loops, current_loop_depth, + loops_reserved, 1); + l = &loops[current_loop_depth++]; + memset(l , 0, sizeof(struct loop)); + l->BgnLoop = (compiler->code->length / 4); + continue; + } + case RC_OPCODE_ENDLOOP: + { + struct loop * l = &loops[current_loop_depth - 1]; + unsigned int act_addr = l->BgnLoop - 1; + unsigned int last_addr = (compiler->code->length / 4) - 1; + unsigned int ret_addr = l->BgnLoop; + + if (loops_reserved >= R300_VS_MAX_FC_OPS) { + rc_error(&compiler->Base, + "Too many flow control instructions."); + return; + } + if (compiler->Base.is_r500) { + compiler->code->fc_op_addrs.r500 + [compiler->code->num_fc_ops].lw = + R500_PVS_FC_ACT_ADRS(act_addr) + | R500_PVS_FC_LOOP_CNT_JMP_INST(0xffff) + ; + compiler->code->fc_op_addrs.r500 + [compiler->code->num_fc_ops].uw = + R500_PVS_FC_LAST_INST(last_addr) + | R500_PVS_FC_RTN_INST(ret_addr) + ; + } else { + compiler->code->fc_op_addrs.r300 + [compiler->code->num_fc_ops] = + R300_PVS_FC_ACT_ADRS(act_addr) + | R300_PVS_FC_LOOP_CNT_JMP_INST(0xff) + | R300_PVS_FC_LAST_INST(last_addr) + | R300_PVS_FC_RTN_INST(ret_addr) + ; + } + compiler->code->fc_loop_index[compiler->code->num_fc_ops] = + R300_PVS_FC_LOOP_INIT_VAL(0x0) + | R300_PVS_FC_LOOP_STEP_VAL(0x1) + ; + compiler->code->fc_ops |= R300_VAP_PVS_FC_OPC_LOOP( + compiler->code->num_fc_ops); + compiler->code->num_fc_ops++; + current_loop_depth--; + continue; + } + default: rc_error(&compiler->Base, "Unknown opcode %s\n", rc_get_opcode_info(vpi->Opcode)->Name); return; } + /* Non-flow control instructions that are inside an if statement + * need to pay attention to the predicate bit. */ + if (branch_depth + && vpi->Opcode != RC_OPCODE_IF + && vpi->Opcode != RC_OPCODE_ELSE + && vpi->Opcode != RC_OPCODE_ENDIF) { + + inst[0] |= (PVS_DST_PRED_ENABLE_MASK + << PVS_DST_PRED_ENABLE_SHIFT); + inst[0] |= (PVS_DST_PRED_SENSE_MASK + << PVS_DST_PRED_SENSE_SHIFT); + } + compiler->code->length += 4; if (compiler->Base.Error) @@ -406,6 +618,7 @@ struct temporary_allocation { static void allocate_temporary_registers(struct r300_vertex_program_compiler * compiler) { struct rc_instruction *inst; + struct rc_instruction *end_loop = NULL; unsigned int num_orig_temps = 0; char hwtemps[R300_VS_MAX_TEMPS]; struct temporary_allocation * ta; @@ -440,10 +653,35 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c /* Pass 2: Determine original temporary lifetimes */ for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) { const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); + /* Instructions inside of loops need to use the ENDLOOP + * instruction as their LastRead. */ + if (!end_loop && inst->U.I.Opcode == RC_OPCODE_BGNLOOP) { + int endloops = 1; + struct rc_instruction * ptr; + for(ptr = inst->Next; + ptr != &compiler->Base.Program.Instructions; + ptr = ptr->Next){ + if (ptr->U.I.Opcode == RC_OPCODE_BGNLOOP) { + endloops++; + } else if (ptr->U.I.Opcode == RC_OPCODE_ENDLOOP) { + endloops--; + if (endloops <= 0) { + end_loop = ptr; + break; + } + } + } + } + + if (inst == end_loop) { + end_loop = NULL; + continue; + } for (i = 0; i < opcode->NumSrcRegs; ++i) { if (inst->U.I.SrcReg[i].File == RC_FILE_TEMPORARY) - ta[inst->U.I.SrcReg[i].Index].LastRead = inst; + ta[inst->U.I.SrcReg[i].Index].LastRead = + end_loop ? end_loop : inst; } } @@ -633,30 +871,24 @@ static struct rc_swizzle_caps r300_vertprog_swizzle_caps = { void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler) { struct emulate_loop_state loop_state; - + compiler->Base.SwizzleCaps = &r300_vertprog_swizzle_caps; addArtificialOutputs(compiler); debug_program_log(compiler, "before compilation"); - /* XXX Ideally this should be done only for r3xx, but since - * we don't have branching support for r5xx, we use the emulation - * on all chipsets. */ - rc_transform_unroll_loops(&compiler->Base, &loop_state); - - debug_program_log(compiler, "after transform loops"); - - if (compiler->Base.is_r500){ - rc_emulate_loops(&loop_state, R500_VS_MAX_ALU); - } else { - rc_emulate_loops(&loop_state, R300_VS_MAX_ALU); - } - debug_program_log(compiler, "after emulate loops"); + if (compiler->Base.is_r500) + rc_transform_loops(&compiler->Base, &loop_state, R500_VS_MAX_ALU); + else + rc_transform_loops(&compiler->Base, &loop_state, R300_VS_MAX_ALU); - rc_emulate_branches(&compiler->Base); + debug_program_log(compiler, "after emulate loops"); - debug_program_log(compiler, "after emulate branches"); + if (!compiler->Base.is_r500) { + rc_emulate_branches(&compiler->Base); + debug_program_log(compiler, "after emulate branches"); + } if (compiler->Base.is_r500) { struct radeon_program_transformation transformations[] = { @@ -718,6 +950,6 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler) if (compiler->Base.Debug) { fprintf(stderr, "Final vertex program code:\n"); - r300_vertex_program_dump(compiler->code); + r300_vertex_program_dump(compiler); } } diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog_dump.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog_dump.c index 5800f1a78e1..e6009338e2e 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog_dump.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog_dump.c @@ -20,7 +20,9 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "radeon_compiler.h" #include "radeon_code.h" +#include "../r300_reg.h" #include <stdio.h> @@ -133,6 +135,10 @@ static void r300_vs_op_dump(uint32_t op) { fprintf(stderr, " dst: %d%s op: ", (op >> 13) & 0x7f, r300_vs_dst_debug[(op >> 8) & 0x7]); + if ((op >> PVS_DST_PRED_ENABLE_SHIFT) & 0x1) { + fprintf(stderr, "PRED %u", + (op >> PVS_DST_PRED_SENSE_SHIFT) & 0x1); + } if (op & 0x80) { if (op & 0x1) { fprintf(stderr, "PVS_MACRO_OP_2CLK_M2X_ADD\n"); @@ -160,8 +166,9 @@ static void r300_vs_src_dump(uint32_t src) r300_vs_swiz_debug[(src >> 22) & 0x7]); } -void r300_vertex_program_dump(struct r300_vertex_program_code * vs) +void r300_vertex_program_dump(struct r300_vertex_program_compiler * c) { + struct r300_vertex_program_code * vs = c->code; unsigned instrcount = vs->length / 4; unsigned i; @@ -177,4 +184,21 @@ void r300_vertex_program_dump(struct r300_vertex_program_code * vs) r300_vs_src_dump(vs->body.d[offset+1+src]); } } + + fprintf(stderr, "Flow Control Ops: 0x%08x\n",vs->fc_ops); + for(i = 0; i < vs->num_fc_ops; i++) { + switch((vs->fc_ops >> (i * 2)) & 0x3 ) { + case 0: fprintf(stderr, "NOP"); break; + case 1: fprintf(stderr, "JUMP"); break; + case 2: fprintf(stderr, "LOOP"); break; + case 3: fprintf(stderr, "JSR"); break; + } + if (c->Base.is_r500) { + fprintf(stderr,": uw-> 0x%08x lw-> 0x%08x\n", + vs->fc_op_addrs.r500[i].uw, + vs->fc_op_addrs.r500[i].lw); + } else { + fprintf(stderr,": 0x%08x\n", vs->fc_op_addrs.r300[i]); + } + } } diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c index e6b5522c5b9..80a120497e3 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c @@ -30,7 +30,6 @@ #include <stdio.h> #include "../r300_reg.h" -#include "radeon_emulate_loops.h" /** * Rewrite IF instructions to use the ALU result special register. @@ -60,31 +59,6 @@ int r500_transform_IF( return 1; } -/** - * Rewrite loops to make them easier to emit. This is not a local - * transformation, because it modifies and reorders an entire block of code. - */ -void r500_transform_unroll_loops(struct radeon_compiler * c, - struct emulate_loop_state *s) -{ - int i; - - rc_transform_unroll_loops(c, s); - - for( i = s->LoopCount - 1; i >= 0; i-- ){ - struct rc_instruction * inst_continue; - if(!s->Loops[i].EndLoop){ - continue; - } - /* Insert a continue instruction at the end of the loop. This - * is required in order to emit loops correctly. */ - inst_continue = rc_insert_new_instruction(c, - s->Loops[i].EndIf->Prev); - inst_continue->U.I.Opcode = RC_OPCODE_CONTINUE; - } - -} - static int r500_swizzle_is_native(rc_opcode opcode, struct rc_src_register reg) { unsigned int relevant; diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h index 0d005a794ff..34173351f83 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h @@ -49,6 +49,4 @@ extern int r500_transform_IF( struct rc_instruction * inst, void* data); -void r500_transform_unroll_loops(struct radeon_compiler * c, - struct emulate_loop_state * s); #endif diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c index 0bd8f0a239f..9b60e30f586 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c @@ -64,7 +64,16 @@ struct branch_info { }; struct loop_info { - int LoopStart; + int BgnLoop; + + int BranchDepth; + int * Brks; + int BrkCount; + int BrkReserved; + + int * Conts; + int ContCount; + int ContReserved; }; struct emit_state { @@ -368,6 +377,12 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst unsigned int newip = ++s->Code->inst_end; + /* Currently all loops use the same integer constant to intialize + * the loop variables. */ + if(!s->Code->int_constants[0]) { + s->Code->int_constants[0] = R500_FC_INT_CONST_KR(0xff); + s->Code->int_constant_count = 1; + } s->Code->inst[newip].inst0 = R500_INST_TYPE_FC | R500_INST_ALU_WAIT; switch(inst->U.I.Opcode){ @@ -378,32 +393,77 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst s->Loops, s->CurrentLoopDepth, s->LoopsReserved, 1); loop = &s->Loops[s->CurrentLoopDepth++]; - - /* We don't emit an instruction for BGNLOOP, so we need to - * decrement the instruction counter, but first we need to - * set LoopStart to the current value of inst_end, which - * will end up being the first real instruction in the loop.*/ - loop->LoopStart = s->Code->inst_end--; + memset(loop, 0, sizeof(struct loop_info)); + loop->BranchDepth = s->CurrentBranchDepth; + loop->BgnLoop = newip; + + s->Code->inst[newip].inst2 = R500_FC_OP_LOOP + | R500_FC_JUMP_FUNC(0x00) + | R500_FC_IGNORE_UNCOVERED + ; break; - case RC_OPCODE_BRK: - /* Don't emit an instruction for BRK */ - s->Code->inst_end--; + loop = &s->Loops[s->CurrentLoopDepth - 1]; + memory_pool_array_reserve(&s->C->Pool, int, loop->Brks, + loop->BrkCount, loop->BrkReserved, 1); + + loop->Brks[loop->BrkCount++] = newip; + s->Code->inst[newip].inst2 = R500_FC_OP_BREAKLOOP + | R500_FC_JUMP_FUNC(0xff) + | R500_FC_B_OP1_DECR + | R500_FC_B_POP_CNT( + s->CurrentBranchDepth - loop->BranchDepth) + | R500_FC_IGNORE_UNCOVERED + ; break; - case RC_OPCODE_CONTINUE: + case RC_OPCODE_CONT: loop = &s->Loops[s->CurrentLoopDepth - 1]; - s->Code->inst[newip].inst2 = R500_FC_OP_JUMP | - R500_FC_JUMP_FUNC(0xff); - s->Code->inst[newip].inst3 = R500_FC_JUMP_ADDR(loop->LoopStart); + memory_pool_array_reserve(&s->C->Pool, int, loop->Conts, + loop->ContCount, loop->ContReserved, 1); + loop->Conts[loop->ContCount++] = newip; + s->Code->inst[newip].inst2 = R500_FC_OP_CONTINUE + | R500_FC_JUMP_FUNC(0xff) + | R500_FC_B_OP1_DECR + | R500_FC_B_POP_CNT( + s->CurrentBranchDepth - loop->BranchDepth) + | R500_FC_IGNORE_UNCOVERED + ; break; case RC_OPCODE_ENDLOOP: - /* Don't emit an instruction for ENDLOOP */ - s->Code->inst_end--; + { + loop = &s->Loops[s->CurrentLoopDepth - 1]; + /* Emit ENDLOOP */ + s->Code->inst[newip].inst2 = R500_FC_OP_ENDLOOP + | R500_FC_JUMP_FUNC(0xff) + | R500_FC_JUMP_ANY + | R500_FC_IGNORE_UNCOVERED + ; + /* The constant integer at index 0 is used by all loops. */ + s->Code->inst[newip].inst3 = R500_FC_INT_ADDR(0) + | R500_FC_JUMP_ADDR(loop->BgnLoop + 1) + ; + + /* Set jump address and int constant for BGNLOOP */ + s->Code->inst[loop->BgnLoop].inst3 = R500_FC_INT_ADDR(0) + | R500_FC_JUMP_ADDR(newip) + ; + + /* Set jump address for the BRK instructions. */ + while(loop->BrkCount--) { + s->Code->inst[loop->Brks[loop->BrkCount]].inst3 = + R500_FC_JUMP_ADDR(newip + 1); + } + + /* Set jump address for CONT instructions. */ + while(loop->ContCount--) { + s->Code->inst[loop->Conts[loop->ContCount]].inst3 = + R500_FC_JUMP_ADDR(newip); + } s->CurrentLoopDepth--; break; - + } case RC_OPCODE_IF: if ( s->CurrentBranchDepth >= MAX_BRANCH_DEPTH_FULL) { rc_error(s->C, "Branch depth exceeds hardware limit"); @@ -442,24 +502,16 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst } branch = &s->Branches[s->CurrentBranchDepth - 1]; - - if(inst->Prev->U.I.Opcode == RC_OPCODE_BRK){ - branch->Endif = --s->Code->inst_end; - s->Code->inst[branch->Endif].inst2 |= - R500_FC_B_OP0_DECR; - } - else{ - branch->Endif = newip; - - s->Code->inst[branch->Endif].inst2 = R500_FC_OP_JUMP - | R500_FC_A_OP_NONE /* no address stack */ - | R500_FC_JUMP_ANY /* docs says set this, but I don't understand why */ - | R500_FC_B_OP0_DECR /* decrement branch counter if stay */ - | R500_FC_B_OP1_NONE /* no branch counter if stay */ - | R500_FC_B_POP_CNT(1) + branch->Endif = newip; + + s->Code->inst[branch->Endif].inst2 = R500_FC_OP_JUMP + | R500_FC_A_OP_NONE /* no address stack */ + | R500_FC_JUMP_ANY /* docs says set this, but I don't understand why */ + | R500_FC_B_OP0_DECR /* decrement branch counter if stay */ + | R500_FC_B_OP1_NONE /* no branch counter if stay */ + | R500_FC_B_POP_CNT(1) ; - s->Code->inst[branch->Endif].inst3 = R500_FC_JUMP_ADDR(branch->Endif + 1); - } + s->Code->inst[branch->Endif].inst3 = R500_FC_JUMP_ADDR(branch->Endif + 1); s->Code->inst[branch->If].inst2 = R500_FC_OP_JUMP | R500_FC_A_OP_NONE /* no address stack */ | R500_FC_JUMP_FUNC(0x0f) /* jump if ALU result is false */ @@ -544,11 +596,9 @@ void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compi code->inst[ip].inst0 = R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT; } - /* Use FULL flow control mode if branches are nested deep enough. - * We don not need to enable FULL flow control mode for loops, becasue - * we aren't using the hardware loop instructions. - */ - if (s.MaxBranchDepth >= 4) { + /* Enable full flow control mode if we are using loops or have if + * statements nested at least four deep. */ + if (s.MaxBranchDepth >= 4 || s.LoopsReserved > 0) { if (code->max_temp_idx < 1) code->max_temp_idx = 1; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h index d03689763bc..896246d2035 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_code.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h @@ -221,6 +221,9 @@ struct r500_fragment_program_code { int max_temp_idx; uint32_t us_fc_ctrl; + + uint32_t int_constants[32]; + uint32_t int_constant_count; }; struct rX00_fragment_program_code { @@ -240,6 +243,12 @@ struct rX00_fragment_program_code { #define R500_VS_MAX_ALU 1024 #define R500_VS_MAX_ALU_DWORDS (R500_VS_MAX_ALU * 4) #define R300_VS_MAX_TEMPS 32 +/* This is the max for all chipsets (r300-r500) */ +#define R300_VS_MAX_FC_OPS 16 +/* The r500 maximum depth is not just for loops, but any combination of loops + * and subroutine jumps. */ +#define R500_VS_MAX_FC_DEPTH 8 +#define R300_VS_MAX_LOOP_DEPTH 1 #define VSF_MAX_INPUTS 32 #define VSF_MAX_OUTPUTS 32 @@ -260,9 +269,18 @@ struct r300_vertex_program_code { uint32_t InputsRead; uint32_t OutputsWritten; -}; -void r300_vertex_program_dump(struct r300_vertex_program_code * vs); + unsigned int num_fc_ops; + uint32_t fc_ops; + union { + uint32_t r300[R300_VS_MAX_FC_OPS]; + struct { + uint32_t lw; + uint32_t uw; + } r500[R300_VS_MAX_FC_OPS]; + } fc_op_addrs; + int32_t fc_loop_index[R300_VS_MAX_FC_OPS]; +}; #endif /* RADEON_CODE_H */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c index 1c8ba864a41..935dc9b0a80 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c @@ -307,3 +307,46 @@ void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsig } } + +/** + * The FACE input in hardware contains 1 if it's a back face, 0 otherwise. + * Gallium and OpenGL define it the other way around. + * + * So let's just negate FACE at the beginning of the shader and rewrite the rest + * of the shader to read from the newly allocated temporary. + */ +void rc_transform_fragment_face(struct radeon_compiler *c, unsigned face) +{ + unsigned tempregi = rc_find_free_temporary(c); + struct rc_instruction *inst_add; + struct rc_instruction *inst; + + /* perspective divide */ + inst_add = rc_insert_new_instruction(c, &c->Program.Instructions); + inst_add->U.I.Opcode = RC_OPCODE_ADD; + + inst_add->U.I.DstReg.File = RC_FILE_TEMPORARY; + inst_add->U.I.DstReg.Index = tempregi; + inst_add->U.I.DstReg.WriteMask = RC_MASK_X; + + inst_add->U.I.SrcReg[0].File = RC_FILE_NONE; + inst_add->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111; + + inst_add->U.I.SrcReg[1].File = RC_FILE_INPUT; + inst_add->U.I.SrcReg[1].Index = face; + inst_add->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XXXX; + inst_add->U.I.SrcReg[1].Negate = RC_MASK_XYZW; + + for (inst = inst_add->Next; inst != &c->Program.Instructions; inst = inst->Next) { + const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); + unsigned i; + + for(i = 0; i < opcode->NumSrcRegs; i++) { + if (inst->U.I.SrcReg[i].File == RC_FILE_INPUT && + inst->U.I.SrcReg[i].Index == face) { + inst->U.I.SrcReg[i].File = RC_FILE_TEMPORARY; + inst->U.I.SrcReg[i].Index = tempregi; + } + } + } +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h index f15905d79d4..7c42eb3ae57 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h @@ -81,6 +81,7 @@ void rc_move_output(struct radeon_compiler * c, unsigned output, unsigned new_ou void rc_copy_output(struct radeon_compiler * c, unsigned output, unsigned dup_output); void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input, int full_vtransform); +void rc_transform_fragment_face(struct radeon_compiler *c, unsigned face); struct r300_fragment_program_compiler { struct radeon_compiler Base; @@ -110,8 +111,12 @@ struct r300_vertex_program_compiler { void * UserData; void (*SetHwInputOutput)(struct r300_vertex_program_compiler * c); + + int PredicateIndex; + unsigned int PredicateMask; }; void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* c); +void r300_vertex_program_dump(struct r300_vertex_program_compiler * c); #endif /* RADEON_COMPILER_H */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c index fbb4235c223..faf531b412e 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c @@ -43,6 +43,12 @@ struct instruction_state { unsigned char SrcReg[3]; }; +struct loopinfo { + struct updatemask_state * Breaks; + unsigned int BreakCount; + unsigned int BreaksReserved; +}; + struct branchinfo { unsigned int HaveElse:1; @@ -59,6 +65,10 @@ struct deadcode_state { struct branchinfo * BranchStack; unsigned int BranchStackSize; unsigned int BranchStackReserved; + + struct loopinfo * LoopStack; + unsigned int LoopStackSize; + unsigned int LoopStackReserved; }; @@ -78,6 +88,22 @@ static void or_updatemasks( dst->Address = a->Address | b->Address; } +static void push_break(struct deadcode_state *s) +{ + struct loopinfo * loop = &s->LoopStack[s->LoopStackSize - 1]; + memory_pool_array_reserve(&s->C->Pool, struct updatemask_state, + loop->Breaks, loop->BreakCount, loop->BreaksReserved, 1); + + memcpy(&loop->Breaks[loop->BreakCount++], &s->R, sizeof(s->R)); +} + +static void push_loop(struct deadcode_state * s) +{ + memory_pool_array_reserve(&s->C->Pool, struct loopinfo, s->LoopStack, + s->LoopStackSize, s->LoopStackReserved, 1); + memset(&s->LoopStack[s->LoopStackSize++], 0, sizeof(struct loopinfo)); +} + static void push_branch(struct deadcode_state * s) { memory_pool_array_reserve(&s->C->Pool, struct branchinfo, s->BranchStack, @@ -233,11 +259,22 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f } } } + push_loop(&s); break; } - case RC_OPCODE_CONTINUE: case RC_OPCODE_BRK: + push_break(&s); + break; case RC_OPCODE_BGNLOOP: + { + unsigned int i; + struct loopinfo * loop = &s.LoopStack[s.LoopStackSize-1]; + for(i = 0; i < loop->BreakCount; i++) { + or_updatemasks(&s.R, &s.R, &loop->Breaks[i]); + } + break; + } + case RC_OPCODE_CONT: break; case RC_OPCODE_ENDIF: push_branch(&s); diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.c b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.c index 131e9e7436d..32d4b45dd6d 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.c @@ -39,7 +39,6 @@ #define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0) struct const_value { - struct radeon_compiler * C; struct rc_src_register * Src; float Value; @@ -78,17 +77,17 @@ static int src_reg_is_immediate(struct rc_src_register * src, c->Program.Constants.Constants[src->Index].Type==RC_CONSTANT_IMMEDIATE; } -static unsigned int loop_calc_iterations(struct emulate_loop_state *s, - struct loop_info * loop, unsigned int max_instructions) +static unsigned int loop_max_possible_iterations(struct radeon_compiler *c, + struct loop_info * loop, unsigned int prog_inst_limit) { - unsigned int total_i = rc_recompute_ips(s->C); + unsigned int total_i = rc_recompute_ips(c); unsigned int loop_i = (loop->EndLoop->IP - loop->BeginLoop->IP) - 1; /* +1 because the program already has one iteration of the loop. */ - return 1 + ((max_instructions - total_i) / (s->LoopCount * loop_i)); + return 1 + ((prog_inst_limit - total_i) / loop_i); } -static void loop_unroll(struct emulate_loop_state * s, - struct loop_info *loop, unsigned int iterations) +static void unroll_loop(struct radeon_compiler * c, struct loop_info * loop, + unsigned int iterations) { unsigned int i; struct rc_instruction * ptr; @@ -99,7 +98,7 @@ static void loop_unroll(struct emulate_loop_state * s, rc_remove_instruction(loop->EndLoop); for( i = 1; i < iterations; i++){ for(ptr = first; ptr != last->Next; ptr = ptr->Next){ - struct rc_instruction *new = rc_alloc_instruction(s->C); + struct rc_instruction *new = rc_alloc_instruction(c); memcpy(new, ptr, sizeof(struct rc_instruction)); rc_insert_instruction(append_to, new); append_to = new; @@ -115,7 +114,7 @@ static void update_const_value(void * data, struct rc_instruction * inst, if(value->Src->File != file || value->Src->Index != index || !(1 << GET_SWZ(value->Src->Swizzle, 0) & mask)){ - return; + return; } switch(inst->U.I.Opcode){ case RC_OPCODE_MOV: @@ -140,7 +139,7 @@ static void get_incr_amount(void * data, struct rc_instruction * inst, if(file != RC_FILE_TEMPORARY || count_inst->Index != index || (1 << GET_SWZ(count_inst->Swz,0) != mask)){ - return; + return; } /* Find the index of the counter register. */ opcode = rc_get_opcode_info(inst->U.I.Opcode); @@ -185,13 +184,16 @@ static void get_incr_amount(void * data, struct rc_instruction * inst, count_inst->Unknown = 1; return; } - } -static int transform_const_loop(struct emulate_loop_state * s, - struct loop_info * loop) +/** + * If prog_inst_limit is -1, then all eligible loops will be unrolled regardless + * of how many iterations they have. + */ +static int try_unroll_loop(struct radeon_compiler * c, struct loop_info * loop, + unsigned int prog_inst_limit) { - int end_loops = 1; + int end_loops; int iterations; struct count_inst count_inst; float limit_value; @@ -201,12 +203,12 @@ static int transform_const_loop(struct emulate_loop_state * s, struct rc_instruction * inst; /* Find the counter and the upper limit */ - - if(src_reg_is_immediate(&loop->Cond->U.I.SrcReg[0], s->C)){ + + if(src_reg_is_immediate(&loop->Cond->U.I.SrcReg[0], c)){ limit = &loop->Cond->U.I.SrcReg[0]; counter = &loop->Cond->U.I.SrcReg[1]; } - else if(src_reg_is_immediate(&loop->Cond->U.I.SrcReg[1], s->C)){ + else if(src_reg_is_immediate(&loop->Cond->U.I.SrcReg[1], c)){ limit = &loop->Cond->U.I.SrcReg[1]; counter = &loop->Cond->U.I.SrcReg[0]; } @@ -214,13 +216,13 @@ static int transform_const_loop(struct emulate_loop_state * s, DBG("No constant limit.\n"); return 0; } - + /* Find the initial value of the counter */ counter_value.Src = counter; counter_value.Value = 0.0f; counter_value.HasValue = 0; - counter_value.C = s->C; - for(inst = s->C->Program.Instructions.Next; inst != loop->BeginLoop; + counter_value.C = c; + for(inst = c->Program.Instructions.Next; inst != loop->BeginLoop; inst = inst->Next){ rc_for_all_writes_mask(inst, update_const_value, &counter_value); } @@ -230,11 +232,12 @@ static int transform_const_loop(struct emulate_loop_state * s, } DBG("Initial counter value is %f\n", counter_value.Value); /* Determine how the counter is modified each loop */ - count_inst.C = s->C; + count_inst.C = c; count_inst.Index = counter->Index; count_inst.Swz = counter->Swizzle; count_inst.Amount = 0.0f; count_inst.Unknown = 0; + end_loops = 1; for(inst = loop->BeginLoop->Next; end_loops > 0; inst = inst->Next){ switch(inst->U.I.Opcode){ /* XXX In the future we might want to try to unroll nested @@ -246,6 +249,16 @@ static int transform_const_loop(struct emulate_loop_state * s, loop->EndLoop = inst; end_loops--; break; + case RC_OPCODE_BRK: + /* Don't unroll loops if it has a BRK instruction + * other one used when testing the main conditional + * of the loop. */ + + /* Make sure we haven't entered a nested loops. */ + if(inst != loop->Brk && end_loops == 1) { + return 0; + } + break; /* XXX Check if the counter is modified within an if statement. */ case RC_OPCODE_IF: @@ -266,17 +279,20 @@ static int transform_const_loop(struct emulate_loop_state * s, /* Calculate the number of iterations of this loop. Keeping this * simple, since we only support increment and decrement loops. */ - limit_value = get_constant_value(s->C, limit, 0); + limit_value = get_constant_value(c, limit, 0); DBG("Limit is %f.\n", limit_value); + /* The iteration calculations are opposite of what you would expect. + * In a normal loop, if the condition is met, then loop continues, but + * with our loops, if the condition is met, the is exited. */ switch(loop->Cond->U.I.Opcode){ - case RC_OPCODE_SGT: - case RC_OPCODE_SLT: + case RC_OPCODE_SGE: + case RC_OPCODE_SLE: iterations = (int) ceilf((limit_value - counter_value.Value) / count_inst.Amount); break; - case RC_OPCODE_SLE: - case RC_OPCODE_SGE: + case RC_OPCODE_SGT: + case RC_OPCODE_SLT: iterations = (int) floorf((limit_value - counter_value.Value) / count_inst.Amount) + 1; break; @@ -284,77 +300,85 @@ static int transform_const_loop(struct emulate_loop_state * s, return 0; } + if (prog_inst_limit > 0 + && iterations > loop_max_possible_iterations(c, loop, + prog_inst_limit)) { + return 0; + } + DBG("Loop will have %d iterations.\n", iterations); - + /* Prepare loop for unrolling */ rc_remove_instruction(loop->Cond); rc_remove_instruction(loop->If); rc_remove_instruction(loop->Brk); rc_remove_instruction(loop->EndIf); - - loop_unroll(s, loop, iterations); + + unroll_loop(c, loop, iterations); loop->EndLoop = NULL; return 1; } -/** - * This function prepares a loop to be unrolled by converting it into an if - * statement. Here is an outline of the conversion process: - * BGNLOOP; -> BGNLOOP; - * <Additional conditional code> -> <Additional conditional code> - * SGE/SLT temp[0], temp[1], temp[2]; -> SLT/SGE temp[0], temp[1], temp[2]; - * IF temp[0]; -> IF temp[0]; - * BRK; -> - * ENDIF; -> <Loop Body> - * <Loop Body> -> ENDIF; - * ENDLOOP; -> ENDLOOP - * +/** + * @param c + * @param loop * @param inst A pointer to a BGNLOOP instruction. - * @return If the loop can be unrolled, a pointer to the first instruction of - * the unrolled loop. - * Otherwise, A pointer to the ENDLOOP instruction. - * Null if there is an error. + * @return 1 if all of the members of loop where set. + * @return 0 if there was an error and some members of loop are still NULL. */ -static struct rc_instruction * transform_loop(struct emulate_loop_state * s, +static int build_loop_info(struct radeon_compiler * c, struct loop_info * loop, struct rc_instruction * inst) { - struct loop_info *loop; struct rc_instruction * ptr; - memory_pool_array_reserve(&s->C->Pool, struct loop_info, - s->Loops, s->LoopCount, s->LoopReserved, 1); - - loop = &s->Loops[s->LoopCount++]; - memset(loop, 0, sizeof(struct loop_info)); if(inst->U.I.Opcode != RC_OPCODE_BGNLOOP){ - rc_error(s->C, "expected BGNLOOP\n", __FUNCTION__); - return NULL; + rc_error(c, "%s: expected BGNLOOP", __FUNCTION__); + return 0; } + + memset(loop, 0, sizeof(struct loop_info)); + loop->BeginLoop = inst; - for(ptr = loop->BeginLoop->Next; !loop->EndLoop; ptr = ptr->Next){ + for(ptr = loop->BeginLoop->Next; !loop->EndLoop; ptr = ptr->Next) { + + if (ptr == &c->Program.Instructions) { + rc_error(c, "%s: BGNLOOP without an ENDLOOOP.\n", + __FUNCTION__); + return 0; + } + switch(ptr->U.I.Opcode){ case RC_OPCODE_BGNLOOP: - /* Nested loop */ - ptr = transform_loop(s, ptr); - if(!ptr){ - return NULL; + { + /* Nested loop, skip ahead to the end. */ + unsigned int loop_depth = 1; + for(ptr = ptr->Next; ptr != &c->Program.Instructions; + ptr = ptr->Next){ + if (ptr->U.I.Opcode == RC_OPCODE_BGNLOOP) { + loop_depth++; + } else if (ptr->U.I.Opcode == RC_OPCODE_ENDLOOP) { + if (!--loop_depth) { + break; + } + } + } + if (ptr == &c->Program.Instructions) { + rc_error(c, "%s: BGNLOOP without an ENDLOOOP\n", + __FUNCTION__); + return 0; } break; + } case RC_OPCODE_BRK: - loop->Brk = ptr; - if(ptr->Next->U.I.Opcode != RC_OPCODE_ENDIF){ - rc_error(s->C, - "%s: expected ENDIF\n",__FUNCTION__); - return NULL; - } - loop->EndIf = ptr->Next; - if(ptr->Prev->U.I.Opcode != RC_OPCODE_IF){ - rc_error(s->C, - "%s: expected IF\n", __FUNCTION__); - return NULL; + if(ptr->Next->U.I.Opcode != RC_OPCODE_ENDIF + || ptr->Prev->U.I.Opcode != RC_OPCODE_IF + || loop->Brk){ + continue; } + loop->Brk = ptr; loop->If = ptr->Prev; + loop->EndIf = ptr->Next; switch(loop->If->Prev->U.I.Opcode){ case RC_OPCODE_SLT: case RC_OPCODE_SGE: @@ -364,18 +388,58 @@ static struct rc_instruction * transform_loop(struct emulate_loop_state * s, case RC_OPCODE_SNE: break; default: - rc_error(s->C, "%s expected conditional\n", + rc_error(c, "%s: expected conditional", __FUNCTION__); - return NULL; + return 0; } loop->Cond = loop->If->Prev; - ptr = loop->EndIf; break; + case RC_OPCODE_ENDLOOP: loop->EndLoop = ptr; break; } } + + if (loop->BeginLoop && loop->Brk && loop->If && loop->EndIf + && loop->Cond && loop->EndLoop) { + return 1; + } + return 0; +} + +/** + * This function prepares a loop to be unrolled by converting it into an if + * statement. Here is an outline of the conversion process: + * BGNLOOP; -> BGNLOOP; + * <Additional conditional code> -> <Additional conditional code> + * SGE/SLT temp[0], temp[1], temp[2]; -> SLT/SGE temp[0], temp[1], temp[2]; + * IF temp[0]; -> IF temp[0]; + * BRK; -> + * ENDIF; -> <Loop Body> + * <Loop Body> -> ENDIF; + * ENDLOOP; -> ENDLOOP + * + * @param inst A pointer to a BGNLOOP instruction. + * @return 1 for success, 0 for failure + */ +static int transform_loop(struct emulate_loop_state * s, + struct rc_instruction * inst) +{ + struct loop_info * loop; + + memory_pool_array_reserve(&s->C->Pool, struct loop_info, + s->Loops, s->LoopCount, s->LoopReserved, 1); + + loop = &s->Loops[s->LoopCount++]; + + if (!build_loop_info(s->C, loop, inst)) + return 0; + + if(try_unroll_loop(s->C, loop, s->prog_inst_limit)){ + return 1; + } + /* Reverse the conditional instruction */ switch(loop->Cond->U.I.Opcode){ case RC_OPCODE_SGE: @@ -398,43 +462,51 @@ static struct rc_instruction * transform_loop(struct emulate_loop_state * s, break; default: rc_error(s->C, "loop->Cond is not a conditional.\n"); - return NULL; - } - - /* Check if the number of loops is known at compile time. */ - if(transform_const_loop(s, loop)){ - return loop->BeginLoop->Next; + return 0; } - /* Prepare the loop to be unrolled */ + /* Prepare the loop to be emulated */ rc_remove_instruction(loop->Brk); rc_remove_instruction(loop->EndIf); rc_insert_instruction(loop->EndLoop->Prev, loop->EndIf); - return loop->EndLoop; + return 1; } -void rc_transform_unroll_loops(struct radeon_compiler *c, - struct emulate_loop_state * s) +void rc_transform_loops(struct radeon_compiler *c, + struct emulate_loop_state * s, int prog_inst_limit) { struct rc_instruction * ptr; - + memset(s, 0, sizeof(struct emulate_loop_state)); s->C = c; - ptr = s->C->Program.Instructions.Next; - while(ptr != &s->C->Program.Instructions) { + s->prog_inst_limit = prog_inst_limit; + for(ptr = s->C->Program.Instructions.Next; + ptr != &s->C->Program.Instructions; ptr = ptr->Next) { if(ptr->Type == RC_INSTRUCTION_NORMAL && ptr->U.I.Opcode == RC_OPCODE_BGNLOOP){ - ptr = transform_loop(s, ptr); - if(!ptr){ + if (!transform_loop(s, ptr)) return; + } + } +} + +void rc_unroll_loops(struct radeon_compiler *c, int prog_inst_limit) +{ + struct rc_instruction * inst; + struct loop_info loop; + + for(inst = c->Program.Instructions.Next; + inst != &c->Program.Instructions; inst = inst->Next) { + + if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP) { + if (build_loop_info(c, &loop, inst)) { + try_unroll_loop(c, &loop, prog_inst_limit); } } - ptr = ptr->Next; } } -void rc_emulate_loops(struct emulate_loop_state *s, - unsigned int max_instructions) +void rc_emulate_loops(struct emulate_loop_state *s, int prog_inst_limit) { int i; /* Iterate backwards of the list of loops so that loops that nested @@ -444,8 +516,8 @@ void rc_emulate_loops(struct emulate_loop_state *s, if(!s->Loops[i].EndLoop){ continue; } - unsigned int iterations = loop_calc_iterations(s, &s->Loops[i], - max_instructions); - loop_unroll(s, &s->Loops[i], iterations); + unsigned int iterations = loop_max_possible_iterations( + s->C, &s->Loops[i], prog_inst_limit); + unroll_loop(s->C, &s->Loops[i], iterations); } } diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.h b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.h index 7748813c4eb..bba1f68e308 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.h @@ -21,12 +21,14 @@ struct emulate_loop_state { struct loop_info * Loops; unsigned int LoopCount; unsigned int LoopReserved; + int prog_inst_limit; }; -void rc_transform_unroll_loops(struct radeon_compiler *c, - struct emulate_loop_state * s); +void rc_transform_loops(struct radeon_compiler *c, + struct emulate_loop_state * s, int prog_inst_limit); -void rc_emulate_loops(struct emulate_loop_state *s, - unsigned int max_instructions); +void rc_unroll_loops(struct radeon_compiler * c, int prog_inst_limit); + +void rc_emulate_loops(struct emulate_loop_state * s, int prog_inst_limit); #endif /* RADEON_EMULATE_LOOPS_H */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c index 04f234f11d8..2ea830be7f9 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c @@ -386,8 +386,8 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = { .NumSrcRegs = 0, }, { - .Opcode = RC_OPCODE_CONTINUE, - .Name = "CONTINUE", + .Opcode = RC_OPCODE_CONT, + .Name = "CONT", .IsFlowControl = 1, .NumSrcRegs = 0 }, diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h index 8b9fa07dde2..6e18d6eb3f1 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h @@ -187,7 +187,7 @@ typedef enum { RC_OPCODE_ENDLOOP, - RC_OPCODE_CONTINUE, + RC_OPCODE_CONT, /** special instruction, used in R300-R500 fragment program pair instructions * indicates that the result of the alpha operation shall be replicated diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c b/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c index eca06515367..7a3f35950a6 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c @@ -164,7 +164,8 @@ static void peephole(struct radeon_compiler * c, struct rc_instruction * inst_mo inst = inst->Next) { /* XXX In the future we might be able to make the optimizer * smart enough to handle loops. */ - if(inst->U.I.Opcode == RC_OPCODE_BGNLOOP){ + if(inst->U.I.Opcode == RC_OPCODE_BGNLOOP + || inst->U.I.Opcode == RC_OPCODE_ENDLOOP){ return; } rc_for_all_reads_mask(inst, peephole_scan_read, &s); diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c index 8a912da4613..ce72cd97ab2 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c @@ -65,6 +65,11 @@ struct regalloc_state { struct hardware_register * HwTemporary; unsigned int NumHwTemporaries; + /** + * If an instruction is inside of a loop, end_loop will be the + * IP of the ENDLOOP instruction, otherwise end_loop will be 0 + */ + int end_loop; }; static void print_live_intervals(struct live_intervals * src) @@ -178,10 +183,10 @@ static void scan_callback(void * data, struct rc_instruction * inst, else reg->Live.Start = inst->IP; reg->Live.End = inst->IP; - } else { - if (inst->IP > reg->Live.End) - reg->Live.End = inst->IP; - } + } else if (s->end_loop) + reg->Live.End = s->end_loop; + else if (inst->IP > reg->Live.End) + reg->Live.End = inst->IP; } static void compute_live_intervals(struct regalloc_state * s) @@ -191,6 +196,31 @@ static void compute_live_intervals(struct regalloc_state * s) for(struct rc_instruction * inst = s->C->Program.Instructions.Next; inst != &s->C->Program.Instructions; inst = inst->Next) { + + /* For all instructions inside of a loop, the ENDLOOP + * instruction is used as the end of the live interval. */ + if (inst->U.I.Opcode == RC_OPCODE_BGNLOOP && !s->end_loop) { + int loops = 1; + struct rc_instruction * tmp; + for(tmp = inst->Next; + tmp != &s->C->Program.Instructions; + tmp = tmp->Next) { + if (tmp->U.I.Opcode == RC_OPCODE_BGNLOOP) { + loops++; + break; + } else if (tmp->U.I.Opcode + == RC_OPCODE_ENDLOOP) { + if(!--loops) { + s->end_loop = tmp->IP; + break; + } + } + } + } + + if (inst->IP == s->end_loop) + s->end_loop = 0; + rc_for_all_reads_mask(inst, scan_callback, s); rc_for_all_writes_mask(inst, scan_callback, s); } diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c index 3cc28972934..857aae55145 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c @@ -988,17 +988,22 @@ void radeonTransformKILP(struct radeon_compiler * c) for (inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) { - if (inst->U.I.Opcode != RC_OPCODE_KILP - || inst->Prev->U.I.Opcode != RC_OPCODE_IF - || inst->Next->U.I.Opcode != RC_OPCODE_ENDIF) { + if (inst->U.I.Opcode != RC_OPCODE_KILP) continue; - } + inst->U.I.Opcode = RC_OPCODE_KIL; - inst->U.I.SrcReg[0] = negate(absolute(inst->Prev->U.I.SrcReg[0])); - /* Remove IF */ - rc_remove_instruction(inst->Prev); - /* Remove ENDIF */ - rc_remove_instruction(inst->Next); + if (inst->Prev->U.I.Opcode != RC_OPCODE_IF + || inst->Next->U.I.Opcode != RC_OPCODE_ENDIF) { + inst->U.I.SrcReg[0] = negate(builtin_one); + } else { + + inst->U.I.SrcReg[0] = + negate(absolute(inst->Prev->U.I.SrcReg[0])); + /* Remove IF */ + rc_remove_instruction(inst->Prev); + /* Remove ENDIF */ + rc_remove_instruction(inst->Next); + } } } diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index e4b302bbad9..3d2f8928fa6 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -461,7 +461,7 @@ static void r300InitGLExtensions(GLcontext *ctx) if (!r300->radeon.radeonScreen->drmSupportsOcclusionQueries) { _mesa_disable_extension(ctx, "GL_ARB_occlusion_query"); } - if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV350) + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_R420) _mesa_enable_extension(ctx, "GL_ARB_half_float_vertex"); if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index f25264b6f2d..f7705b0f6fe 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -441,6 +441,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R300_VAP_GB_HORZ_CLIP_ADJ 0x2228 #define R300_VAP_GB_HORZ_DISC_ADJ 0x222c +#define R300_VAP_PVS_FLOW_CNTL_ADDRS_0 0x2230 +#define R300_PVS_FC_ACT_ADRS(x) ((x) << 0) +#define R300_PVS_FC_LOOP_CNT_JMP_INST(x) ((x) << 8) +#define R300_PVS_FC_LAST_INST(x) ((x) << 16) +#define R300_PVS_FC_RTN_INST(x) ((x) << 24) + /* gap */ /* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between @@ -459,6 +465,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_2288_R300 0x00750000 /* -- nh */ # define R300_2288_RV350 0x0000FFFF /* -- Vladimir */ +#define R300_VAP_PVS_FLOW_CNTL_LOOP_INDEX_0 0x2290 +#define R300_PVS_FC_LOOP_INIT_VAL(x) ((x) << 0) +#define R300_PVS_FC_LOOP_STEP_VAL(x) ((x) << 8) + /* gap */ /* Addresses are relative to the vertex program instruction area of the @@ -489,6 +499,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R300_VAP_PVS_CODE_CNTL_1 0x22D8 # define R300_PVS_LAST_VTX_SRC_INST_SHIFT 0 #define R300_VAP_PVS_FLOW_CNTL_OPC 0x22DC +#define R300_VAP_PVS_FC_OPC_JUMP(x) (1 << (2 * (x))) +#define R300_VAP_PVS_FC_OPC_LOOP(x) (2 << (2 * (x))) +#define R300_VAP_PVS_FC_OPC_JSR(x) (3 << (2 * (x))) /* The entire range from 0x2300 to 0x2AC inclusive seems to be used for * immediate vertices @@ -505,6 +518,14 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* write 0 to indicate end of packet? */ #define R300_VAP_VTX_END_OF_PKT 0x24AC +#define R500_VAP_PVS_FLOW_CNTL_ADDRS_LW_0 0x2500 +#define R500_PVS_FC_ACT_ADRS(x) ((x) << 0) +#define R500_PVS_FC_LOOP_CNT_JMP_INST(x) ((x) << 16) + +#define R500_VAP_PVS_FLOW_CNTL_ADDRS_UW_0 0x2504 +#define R500_PVS_FC_LAST_INST(x) ((x) << 0) +#define R500_PVS_FC_RTN_INST(x) ((x) << 16) + /* gap */ /* These are values from r300_reg/r300_reg.h - they are known to be correct diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index bb8f91491f5..cf89ab7ec3d 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -327,6 +327,8 @@ void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim) BATCH_LOCALS(&rmesa->radeon); int type, num_verts; + radeon_prepare_render(&rmesa->radeon); + type = r300PrimitiveType(rmesa, prim); num_verts = r300NumVerts(rmesa, end - start, prim); diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 4ba6740e3d9..94588698265 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -152,8 +152,8 @@ int32_t r300TranslateTexFormat(gl_format mesaFormat) case MESA_FORMAT_Z32: return R300_EASY_TX_FORMAT(X, X, X, X, X32); /* EXT_texture_sRGB */ - case MESA_FORMAT_SRGBA8: - return R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8) | R300_TX_FORMAT_GAMMA; + case MESA_FORMAT_SARGB8: + return R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8) | R300_TX_FORMAT_GAMMA; case MESA_FORMAT_SLA8: return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8) | R300_TX_FORMAT_GAMMA; case MESA_FORMAT_SL8: diff --git a/src/mesa/drivers/dri/r600/r600_blit.c b/src/mesa/drivers/dri/r600/r600_blit.c index 172f85eb264..27acff9c166 100644 --- a/src/mesa/drivers/dri/r600/r600_blit.c +++ b/src/mesa/drivers/dri/r600/r600_blit.c @@ -72,7 +72,7 @@ unsigned r600_check_blit(gl_format mesa_format) case MESA_FORMAT_Z24_S8: case MESA_FORMAT_Z16: case MESA_FORMAT_Z32: - case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SARGB8: case MESA_FORMAT_SLA8: case MESA_FORMAT_SL8: break; @@ -320,9 +320,9 @@ set_render_target(context_t *context, struct radeon_bo *bo, gl_format mesa_forma CLEARbit(cb_color0_info, SOURCE_FORMAT_bit); SETfield(cb_color0_info, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask); break; - case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SARGB8: format = COLOR_8_8_8_8; - comp_swap = SWAP_STD_REV; + comp_swap = SWAP_ALT; SETbit(cb_color0_info, SOURCE_FORMAT_bit); SETfield(cb_color0_info, NUMBER_SRGB, NUMBER_TYPE_shift, NUMBER_TYPE_mask); break; @@ -390,13 +390,20 @@ set_render_target(context_t *context, struct radeon_bo *bo, gl_format mesa_forma 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); END_BATCH(); - BEGIN_BATCH_NO_AUTOSTATE(12); + BEGIN_BATCH_NO_AUTOSTATE(9); R600_OUT_BATCH_REGVAL(CB_COLOR0_SIZE + (4 * id), cb_color0_size); R600_OUT_BATCH_REGVAL(CB_COLOR0_VIEW + (4 * id), cb_color0_view); - R600_OUT_BATCH_REGVAL(CB_COLOR0_INFO + (4 * id), cb_color0_info); R600_OUT_BATCH_REGVAL(CB_COLOR0_MASK + (4 * id), 0); END_BATCH(); + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGVAL(CB_COLOR0_INFO + (4 * id), cb_color0_info); + R600_OUT_BATCH_RELOC(0, + bo, + 0, + 0, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0); + END_BATCH(); + COMMIT_BATCH(); } @@ -1043,17 +1050,17 @@ set_tex_resource(context_t * context, SETfield(sq_tex_resource4, SQ_SEL_X, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); break; - case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SARGB8: SETfield(sq_tex_resource1, FMT_8_8_8_8, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); - SETfield(sq_tex_resource4, SQ_SEL_W, - SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); SETfield(sq_tex_resource4, SQ_SEL_Z, - SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); SETfield(sq_tex_resource4, SQ_SEL_Y, - SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); SETfield(sq_tex_resource4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(sq_tex_resource4, SQ_SEL_W, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); SETbit(sq_tex_resource4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit); break; @@ -1477,7 +1484,6 @@ set_default_state(context_t *context) (CLRCMP_SEL_SRC << CLRCMP_FCN_SEL_shift)); R600_OUT_BATCH_REGVAL(SQ_VTX_BASE_VTX_LOC, 0); R600_OUT_BATCH_REGVAL(SQ_VTX_START_INST_LOC, 0); - R600_OUT_BATCH_REGVAL(DB_DEPTH_INFO, 0); R600_OUT_BATCH_REGVAL(DB_DEPTH_CONTROL, 0); R600_OUT_BATCH_REGVAL(CB_SHADER_MASK, (OUTPUT0_ENABLE_mask)); R600_OUT_BATCH_REGVAL(CB_TARGET_MASK, (TARGET0_ENABLE_mask)); @@ -1526,6 +1532,7 @@ set_default_state(context_t *context) R600_OUT_BATCH(0); R600_OUT_BATCH_REGVAL(VGT_STRMOUT_BUFFER_EN, 0); + R600_OUT_BATCH_REGVAL(SX_ALPHA_TEST_CONTROL, 0); END_BATCH(); COMMIT_BATCH(); @@ -1607,7 +1614,7 @@ unsigned r600_blit(GLcontext *ctx, /* Flush is needed to make sure that source buffer has correct data */ radeonFlush(ctx); - rcommonEnsureCmdBufSpace(&context->radeon, 304, __FUNCTION__); + rcommonEnsureCmdBufSpace(&context->radeon, 308, __FUNCTION__); /* load shaders */ load_shaders(context->radeon.glCtx); @@ -1632,7 +1639,7 @@ unsigned r600_blit(GLcontext *ctx, set_tex_sampler(context); /* dst */ - /* 27 */ + /* 31 */ set_render_target(context, dst_bo, dst_mesaformat, dst_pitch, dst_width, dst_height, dst_offset); /* scissors */ diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c index 84d9d423124..389b0412baa 100644 --- a/src/mesa/drivers/dri/r600/r600_context.c +++ b/src/mesa/drivers/dri/r600/r600_context.c @@ -72,6 +72,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define R600_ENABLE_GLSL_TEST 1 #define need_GL_VERSION_2_0 +#define need_GL_VERSION_2_1 +#define need_GL_ARB_draw_elements_base_vertex #define need_GL_ARB_occlusion_query #define need_GL_ARB_point_parameters #define need_GL_ARB_vertex_program @@ -140,6 +142,7 @@ static const struct dri_extension card_extensions[] = { {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, {"GL_SGIS_generate_mipmap", NULL}, {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_draw_elements_base_vertex", GL_ARB_draw_elements_base_vertex_functions }, {NULL, NULL} /* *INDENT-ON* */ }; @@ -157,6 +160,7 @@ static const struct dri_extension mm_extensions[] = { static const struct dri_extension gl_20_extension[] = { #ifdef R600_ENABLE_GLSL_TEST {"GL_ARB_shading_language_100", GL_VERSION_2_0_functions }, + {"GL_ARB_shading_language_120", GL_VERSION_2_1_functions }, #else {"GL_VERSION_2_0", GL_VERSION_2_0_functions }, #endif /* R600_ENABLE_GLSL_TEST */ diff --git a/src/mesa/drivers/dri/r600/r600_tex.c b/src/mesa/drivers/dri/r600/r600_tex.c index 41419f84601..512a52ede3e 100644 --- a/src/mesa/drivers/dri/r600/r600_tex.c +++ b/src/mesa/drivers/dri/r600/r600_tex.c @@ -431,7 +431,7 @@ unsigned r600IsFormatRenderable(gl_format mesa_format) case MESA_FORMAT_Z24_S8: case MESA_FORMAT_Z16: case MESA_FORMAT_Z32: - case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SARGB8: case MESA_FORMAT_SLA8: case MESA_FORMAT_SL8: return 1; diff --git a/src/mesa/drivers/dri/r600/r600_texstate.c b/src/mesa/drivers/dri/r600/r600_texstate.c index 1600033b9bd..ba3690b70ed 100644 --- a/src/mesa/drivers/dri/r600/r600_texstate.c +++ b/src/mesa/drivers/dri/r600/r600_texstate.c @@ -605,17 +605,17 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, gl_format mesa } break; /* EXT_texture_sRGB */ - case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SARGB8: SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask); - SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W, - SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z, - SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask); SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y, - SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask); SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X, + SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask); + SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask); SETbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit); break; diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c index 99a33df4fcb..9c954cbf70c 100644 --- a/src/mesa/drivers/dri/r600/r700_assembler.c +++ b/src/mesa/drivers/dri/r600/r700_assembler.c @@ -275,7 +275,10 @@ GLuint GetSurfaceFormat(GLenum eType, GLuint nChannels, GLuint * pClient_size) case 2: format = FMT_8_8; break; case 3: - format = FMT_8_8_8; break; + /* for some (small/unaligned) strides using 4 comps works + * better, probably same as GL_SHORT below + * test piglit/draw-vertices */ + format = FMT_8_8_8_8; break; case 4: format = FMT_8_8_8_8; break; default: @@ -2872,25 +2875,92 @@ GLboolean assemble_CMP(r700_AssemblerBase *pAsm) GLboolean assemble_TRIG(r700_AssemblerBase *pAsm, BITS opcode) { + /* + * r600 - trunc to -PI..PI range + * r700 - normalize by dividing by 2PI + * see fdo bug 27901 + */ + int tmp; checkop1(pAsm); tmp = gethelpr(pAsm); - pAsm->D.dst.opcode = SQ_OP2_INST_MUL; + pAsm->D.dst.opcode = SQ_OP3_INST_MULADD; + pAsm->D.dst.op3 = 1; + setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE); pAsm->D.dst.rtype = DST_REG_TEMPORARY; pAsm->D.dst.reg = tmp; - pAsm->D.dst.writex = 1; assemble_src(pAsm, 0, -1); pAsm->S[1].src.rtype = SRC_REC_LITERAL; setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_X); + + pAsm->S[2].src.rtype = SRC_REC_LITERAL; + setswizzle_PVSSRC(&(pAsm->S[2].src), SQ_SEL_Y); + pAsm->D2.dst2.literal_slots = 1; pAsm->C[0].f = 1/(3.1415926535 * 2); - pAsm->C[1].f = 0.0F; - next_ins(pAsm); + pAsm->C[1].f = 0.5f; + + if ( GL_FALSE == next_ins(pAsm) ) + { + return GL_FALSE; + } + + pAsm->D.dst.opcode = SQ_OP2_INST_FRACT; + + setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE); + pAsm->D.dst.rtype = DST_REG_TEMPORARY; + pAsm->D.dst.reg = tmp; + pAsm->D.dst.writex = 1; + + setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE); + pAsm->S[0].src.rtype = SRC_REG_TEMPORARY; + pAsm->S[0].src.reg = tmp; + setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X); + + if(( GL_FALSE == next_ins(pAsm) )) + { + return GL_FALSE; + } + pAsm->D.dst.opcode = SQ_OP3_INST_MULADD; + pAsm->D.dst.op3 = 1; + + setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE); + pAsm->D.dst.rtype = DST_REG_TEMPORARY; + pAsm->D.dst.reg = tmp; + + setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE); + pAsm->S[0].src.rtype = SRC_REG_TEMPORARY; + pAsm->S[0].src.reg = tmp; + setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X); + + pAsm->S[1].src.rtype = SRC_REC_LITERAL; + setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_X); + + pAsm->S[2].src.rtype = SRC_REC_LITERAL; + setswizzle_PVSSRC(&(pAsm->S[2].src), SQ_SEL_Y); + + pAsm->D2.dst2.literal_slots = 1; + + if (pAsm->bR6xx) + { + pAsm->C[0].f = 3.1415926535897f * 2.0f; + pAsm->C[1].f = -3.1415926535897f; + } + else + { + pAsm->C[0].f = 1.0f; + pAsm->C[1].f = -0.5f; + } + + if(( GL_FALSE == next_ins(pAsm) )) + { + return GL_FALSE; + } pAsm->D.dst.opcode = opcode; pAsm->D.dst.math = 1; @@ -4030,22 +4100,79 @@ GLboolean assemble_SCS(r700_AssemblerBase *pAsm) checkop1(pAsm); tmp = gethelpr(pAsm); - /* tmp.x = src /2*PI */ - pAsm->D.dst.opcode = SQ_OP2_INST_MUL; + + pAsm->D.dst.opcode = SQ_OP3_INST_MULADD; + pAsm->D.dst.op3 = 1; + setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE); pAsm->D.dst.rtype = DST_REG_TEMPORARY; pAsm->D.dst.reg = tmp; - pAsm->D.dst.writex = 1; assemble_src(pAsm, 0, -1); pAsm->S[1].src.rtype = SRC_REC_LITERAL; setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_X); + + pAsm->S[2].src.rtype = SRC_REC_LITERAL; + setswizzle_PVSSRC(&(pAsm->S[2].src), SQ_SEL_Y); + pAsm->D2.dst2.literal_slots = 1; pAsm->C[0].f = 1/(3.1415926535 * 2); - pAsm->C[1].f = 0.0F; + pAsm->C[1].f = 0.5F; - next_ins(pAsm); + if ( GL_FALSE == next_ins(pAsm) ) + { + return GL_FALSE; + } + + pAsm->D.dst.opcode = SQ_OP2_INST_FRACT; + + setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE); + pAsm->D.dst.rtype = DST_REG_TEMPORARY; + pAsm->D.dst.reg = tmp; + pAsm->D.dst.writex = 1; + + setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE); + pAsm->S[0].src.rtype = SRC_REG_TEMPORARY; + pAsm->S[0].src.reg = tmp; + setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X); + + if(( GL_FALSE == next_ins(pAsm) )) + { + return GL_FALSE; + } + pAsm->D.dst.opcode = SQ_OP3_INST_MULADD; + pAsm->D.dst.op3 = 1; + + setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE); + pAsm->D.dst.rtype = DST_REG_TEMPORARY; + pAsm->D.dst.reg = tmp; + + setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE); + pAsm->S[0].src.rtype = SRC_REG_TEMPORARY; + pAsm->S[0].src.reg = tmp; + setswizzle_PVSSRC(&(pAsm->S[0].src), SQ_SEL_X); + + pAsm->S[1].src.rtype = SRC_REC_LITERAL; + setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_X); + + pAsm->S[2].src.rtype = SRC_REC_LITERAL; + setswizzle_PVSSRC(&(pAsm->S[2].src), SQ_SEL_Y); + + pAsm->D2.dst2.literal_slots = 1; + + if(pAsm->bR6xx) { + pAsm->C[0].f = 3.1415926535897f * 2.0f; + pAsm->C[1].f = -3.1415926535897f; + } else { + pAsm->C[0].f = 1.0f; + pAsm->C[1].f = -0.5f; + } + + if(( GL_FALSE == next_ins(pAsm) )) + { + return GL_FALSE; + } // COS dst.x, a.x pAsm->D.dst.opcode = SQ_OP2_INST_COS; @@ -6473,7 +6600,7 @@ GLboolean Process_Fragment_Exports(r700_AssemblerBase *pR700AsmCode, * results are undefined anyway */ if(export_count == 0) { - Process_Export(pR700AsmCode, SQ_EXPORT_PIXEL, 0, 1, 0, GL_FALSE); + Process_Export(pR700AsmCode, SQ_EXPORT_PIXEL, 0, 1, pR700AsmCode->starting_export_register_number, GL_FALSE); } if(pR700AsmCode->cf_last_export_ptr != NULL) diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c index cefda3ac4ba..bf8063391a2 100644 --- a/src/mesa/drivers/dri/r600/r700_chip.c +++ b/src/mesa/drivers/dri/r600/r700_chip.c @@ -265,17 +265,6 @@ static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom) if (context->radeon.tcl.aos_count == 0) return; - BEGIN_BATCH_NO_AUTOSTATE(6); - R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1)); - R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX); - R600_OUT_BATCH(0); - - R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1)); - R600_OUT_BATCH(mmSQ_VTX_START_INST_LOC - ASIC_CTL_CONST_BASE_INDEX); - R600_OUT_BATCH(0); - END_BATCH(); - COMMIT_BATCH(); - for(i=0; i<VERT_ATTRIB_MAX; i++) { if(vp->mesa_program->Base.InputsRead & (1 << i)) { @@ -523,9 +512,9 @@ static void r700SetRenderTarget(context_t *context, int id) CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask); CLEARbit(r700->render_target[id].CB_COLOR0_INFO.u32All, SOURCE_FORMAT_bit); break; - case MESA_FORMAT_SRGBA8: + case MESA_FORMAT_SARGB8: format = COLOR_8_8_8_8; - comp_swap = SWAP_STD_REV; + comp_swap = SWAP_ALT; number_type = NUMBER_SRGB; SETbit(r700->render_target[id].CB_COLOR0_INFO.u32All, SOURCE_FORMAT_bit); break; @@ -617,18 +606,25 @@ static void r700SendDepthTargetState(GLcontext *ctx, struct radeon_state_atom *a r700SetDepthTarget(context); - BEGIN_BATCH_NO_AUTOSTATE(8 + 2); + BEGIN_BATCH_NO_AUTOSTATE(7 + 2); R600_OUT_BATCH_REGSEQ(DB_DEPTH_SIZE, 2); R600_OUT_BATCH(r700->DB_DEPTH_SIZE.u32All); R600_OUT_BATCH(r700->DB_DEPTH_VIEW.u32All); - R600_OUT_BATCH_REGSEQ(DB_DEPTH_BASE, 2); + R600_OUT_BATCH_REGSEQ(DB_DEPTH_BASE, 1); R600_OUT_BATCH(r700->DB_DEPTH_BASE.u32All); - R600_OUT_BATCH(r700->DB_DEPTH_INFO.u32All); R600_OUT_BATCH_RELOC(r700->DB_DEPTH_BASE.u32All, rrb->bo, r700->DB_DEPTH_BASE.u32All, 0, RADEON_GEM_DOMAIN_VRAM, 0); END_BATCH(); + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGSEQ(DB_DEPTH_INFO, 1); + R600_OUT_BATCH(r700->DB_DEPTH_INFO.u32All); + R600_OUT_BATCH_RELOC(r700->DB_DEPTH_INFO.u32All, + rrb->bo, + r700->DB_DEPTH_INFO.u32All, + 0, RADEON_GEM_DOMAIN_VRAM, 0); + END_BATCH(); if ((context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) && (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)) { @@ -687,27 +683,35 @@ static void r700SendRenderTargetState(GLcontext *ctx, struct radeon_state_atom * BEGIN_BATCH_NO_AUTOSTATE(3 + 2); R600_OUT_BATCH_REGSEQ(CB_COLOR0_TILE + (4 * id), 1); R600_OUT_BATCH(r700->render_target[id].CB_COLOR0_TILE.u32All); - R600_OUT_BATCH_RELOC(r700->render_target[id].CB_COLOR0_BASE.u32All, + R600_OUT_BATCH_RELOC(r700->render_target[id].CB_COLOR0_TILE.u32All, rrb->bo, - r700->render_target[id].CB_COLOR0_BASE.u32All, + r700->render_target[id].CB_COLOR0_TILE.u32All, 0, RADEON_GEM_DOMAIN_VRAM, 0); END_BATCH(); BEGIN_BATCH_NO_AUTOSTATE(3 + 2); R600_OUT_BATCH_REGSEQ(CB_COLOR0_FRAG + (4 * id), 1); R600_OUT_BATCH(r700->render_target[id].CB_COLOR0_FRAG.u32All); - R600_OUT_BATCH_RELOC(r700->render_target[id].CB_COLOR0_BASE.u32All, + R600_OUT_BATCH_RELOC(r700->render_target[id].CB_COLOR0_FRAG.u32All, rrb->bo, - r700->render_target[id].CB_COLOR0_BASE.u32All, + r700->render_target[id].CB_COLOR0_FRAG.u32All, 0, RADEON_GEM_DOMAIN_VRAM, 0); END_BATCH(); - BEGIN_BATCH_NO_AUTOSTATE(12); + BEGIN_BATCH_NO_AUTOSTATE(9); R600_OUT_BATCH_REGVAL(CB_COLOR0_SIZE + (4 * id), r700->render_target[id].CB_COLOR0_SIZE.u32All); R600_OUT_BATCH_REGVAL(CB_COLOR0_VIEW + (4 * id), r700->render_target[id].CB_COLOR0_VIEW.u32All); - R600_OUT_BATCH_REGVAL(CB_COLOR0_INFO + (4 * id), r700->render_target[id].CB_COLOR0_INFO.u32All); R600_OUT_BATCH_REGVAL(CB_COLOR0_MASK + (4 * id), r700->render_target[id].CB_COLOR0_MASK.u32All); END_BATCH(); + BEGIN_BATCH_NO_AUTOSTATE(3 + 2); + R600_OUT_BATCH_REGVAL(CB_COLOR0_INFO + (4 * id), r700->render_target[id].CB_COLOR0_INFO.u32All); + R600_OUT_BATCH_RELOC(r700->render_target[id].CB_COLOR0_INFO.u32All, + rrb->bo, + r700->render_target[id].CB_COLOR0_INFO.u32All, + 0, RADEON_GEM_DOMAIN_VRAM, 0); + + END_BATCH(); + COMMIT_BATCH(); } @@ -1465,9 +1469,6 @@ static int check_vtx(GLcontext *ctx, struct radeon_state_atom *atom) context_t *context = R700_CONTEXT(ctx); int count = context->radeon.tcl.aos_count * 18; - if (count) - count += 6; - radeon_print(RADEON_STATE, RADEON_TRACE, "%s %d\n", __func__, count); return count; } @@ -1567,7 +1568,7 @@ void r600InitAtoms(context_t *context) ALLOC_STATE(sq, always, 34, r700SendSQConfig); ALLOC_STATE(db, always, 17, r700SendDBState); ALLOC_STATE(stencil, always, 4, r700SendStencilState); - ALLOC_STATE(db_target, always, 12, r700SendDepthTargetState); + ALLOC_STATE(db_target, always, 16, r700SendDepthTargetState); ALLOC_STATE(sc, always, 15, r700SendSCState); ALLOC_STATE(scissor, always, 22, r700SendScissorState); ALLOC_STATE(aa, always, 12, r700SendAAState); @@ -1578,7 +1579,7 @@ void r600InitAtoms(context_t *context) ALLOC_STATE(poly, always, 10, r700SendPolyState); ALLOC_STATE(cb, cb, 18, r700SendCBState); ALLOC_STATE(clrcmp, always, 6, r700SendCBCLRCMPState); - ALLOC_STATE(cb_target, always, 29, r700SendRenderTargetState); + ALLOC_STATE(cb_target, always, 31, r700SendRenderTargetState); ALLOC_STATE(blnd, blnd, (6 + (R700_MAX_RENDER_TARGETS * 3)), r700SendCBBlendState); ALLOC_STATE(blnd_clr, always, 6, r700SendCBBlendColorState); ALLOC_STATE(sx, always, 9, r700SendSXState); @@ -1590,7 +1591,7 @@ void r600InitAtoms(context_t *context) ALLOC_STATE(ps, always, 24, r700SendPSState); ALLOC_STATE(vs_consts, vs_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendVSConsts); ALLOC_STATE(ps_consts, ps_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendPSConsts); - ALLOC_STATE(vtx, vtx, (6 + (VERT_ATTRIB_MAX * 18)), r700SendVTXState); + ALLOC_STATE(vtx, vtx, (VERT_ATTRIB_MAX * 18), r700SendVTXState); ALLOC_STATE(tx, tx, (R700_TEXTURE_NUMBERUNITS * 20), r700SendTexState); ALLOC_STATE(tx_smplr, tx, (R700_TEXTURE_NUMBERUNITS * 5), r700SendTexSamplerState); ALLOC_STATE(tx_brdr_clr, tx, (R700_TEXTURE_NUMBERUNITS * 6), r700SendTexBorderColorState); diff --git a/src/mesa/drivers/dri/r600/r700_clear.c b/src/mesa/drivers/dri/r600/r700_clear.c index 09c48565b68..d1008f28b9b 100644 --- a/src/mesa/drivers/dri/r600/r700_clear.c +++ b/src/mesa/drivers/dri/r600/r700_clear.c @@ -48,6 +48,7 @@ static GLboolean r700ClearFast(context_t *context, GLbitfield mask) void r700Clear(GLcontext * ctx, GLbitfield mask) { context_t *context = R700_CONTEXT(ctx); + radeonContextPtr radeon = &context->radeon; __DRIdrawable *dPriv = radeon_get_drawable(&context->radeon); const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask[0]); GLbitfield swrast_mask = 0, tri_mask = 0; @@ -60,6 +61,8 @@ void r700Clear(GLcontext * ctx, GLbitfield mask) context->radeon.front_buffer_dirty = GL_TRUE; } + radeon_prepare_render(radeon); + if( GL_TRUE == r700ClearFast(context, mask) ) { return; diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c index 1929b7cc129..c5771f9fd0b 100644 --- a/src/mesa/drivers/dri/r600/r700_render.c +++ b/src/mesa/drivers/dri/r600/r700_render.c @@ -244,7 +244,8 @@ static int r700NumVerts(int num_verts, int prim) return num_verts - verts_off; } -static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim) +static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, + int prim, GLint basevertex) { context_t *context = R700_CONTEXT(ctx); BATCH_LOCALS(&context->radeon); @@ -282,6 +283,7 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim total_emit = 3 /* VGT_PRIMITIVE_TYPE */ + 2 /* VGT_INDEX_TYPE */ + 2 /* NUM_INSTANCES */ + + 4 /* VTX_BASE_VTX_LOC + VTX_START_INST_LOC */ + 5 + 2; /* DRAW_INDEX */ BEGIN_BATCH_NO_AUTOSTATE(total_emit); @@ -294,6 +296,11 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim // num instances R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); R600_OUT_BATCH(1); + /* offset */ + R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 2)); + R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX); + R600_OUT_BATCH(basevertex); //VTX_BASE_VTX_LOC + R600_OUT_BATCH(0); //VTX_START_INST_LOC // draw packet R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX, 3)); R600_OUT_BATCH(context->ind_buf.bo_offset); @@ -364,6 +371,7 @@ static void r700RunRenderPrimitiveImmediate(GLcontext * ctx, int start, int end, total_emit += 3 /* VGT_PRIMITIVE_TYPE */ + 2 /* VGT_INDEX_TYPE */ + 2 /* NUM_INSTANCES */ + + 4 /* VTX_BASE_VTX_LOC + VTX_START_INST_LOC */ + 3; /* DRAW */ BEGIN_BATCH_NO_AUTOSTATE(total_emit); @@ -376,6 +384,11 @@ static void r700RunRenderPrimitiveImmediate(GLcontext * ctx, int start, int end, // num instances R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0)); R600_OUT_BATCH(1); + /* offset */ + R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 2)); + R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX); + R600_OUT_BATCH(0); //VTX_BASE_VTX_LOC + R600_OUT_BATCH(0); //VTX_START_INST_LOC // draw packet if(start == 0) { @@ -433,16 +446,16 @@ static GLuint r700PredictRenderSize(GLcontext* ctx, dwords = PRE_EMIT_STATE_BUFSZ; if (ib) - dwords += nr_prims * 14; + dwords += nr_prims * 18; else { for (i = 0; i < nr_prims; ++i) { if (prim[i].start == 0) - dwords += 10; + dwords += 14; else if (prim[i].count > 0xffff) - dwords += prim[i].count + 10; + dwords += prim[i].count + 14; else - dwords += ((prim[i].count + 1) / 2) + 10; + dwords += ((prim[i].count + 1) / 2) + 14; } } @@ -625,11 +638,11 @@ static void r700SetupStreams(GLcontext *ctx, const struct gl_client_array *input stride = (input[i]->StrideB == 0) ? getTypeSize(input[i]->Type) * input[i]->Size : input[i]->StrideB; - if (input[i]->Type == GL_DOUBLE || input[i]->Type == GL_UNSIGNED_INT || input[i]->Type == GL_INT || + if (input[i]->Type == GL_DOUBLE || input[i]->Type == GL_UNSIGNED_INT || input[i]->Type == GL_INT #if MESA_BIG_ENDIAN - getTypeSize(input[i]->Type) != 4 || + || getTypeSize(input[i]->Type) != 4 #endif - stride < 4) + ) { r700ConvertAttrib(ctx, count, input[i], &context->stream_desc[index]); } @@ -637,19 +650,10 @@ static void r700SetupStreams(GLcontext *ctx, const struct gl_client_array *input { if (input[i]->BufferObj->Name) { - if (stride % 4 != 0) - { - assert(((intptr_t) input[i]->Ptr) % input[i]->StrideB == 0); - r700AlignDataToDword(ctx, input[i], count, &context->stream_desc[index]); - context->stream_desc[index].is_named_bo = GL_FALSE; - } - else - { - context->stream_desc[index].stride = input[i]->StrideB; - context->stream_desc[index].bo_offset = (intptr_t) input[i]->Ptr; - context->stream_desc[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo; - context->stream_desc[index].is_named_bo = GL_TRUE; - } + context->stream_desc[index].stride = input[i]->StrideB; + context->stream_desc[index].bo_offset = (intptr_t) input[i]->Ptr; + context->stream_desc[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo; + context->stream_desc[index].is_named_bo = GL_TRUE; } else { @@ -932,7 +936,8 @@ static GLboolean r700TryDrawPrims(GLcontext *ctx, r700RunRenderPrimitive(ctx, prim[i].start, prim[i].start + prim[i].count, - prim[i].mode); + prim[i].mode, + prim[i].basevertex); else r700RunRenderPrimitiveImmediate(ctx, prim[i].start, @@ -977,18 +982,24 @@ static void r700DrawPrims(GLcontext *ctx, { GLboolean retval = GL_FALSE; + context_t *context = R700_CONTEXT(ctx); + radeonContextPtr radeon = &context->radeon; + radeon_prepare_render(radeon); + /* This check should get folded into just the places that * min/max index are really needed. */ - if (!index_bounds_valid) { - vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index); - } - if (min_index) { + if (!vbo_all_varyings_in_vbos(arrays)) { + if (!index_bounds_valid) + vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index); + /* do we want to rebase, minimizes the + * amount of data to upload? */ + if (min_index) { vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r700DrawPrims ); return; + } } - /* Make an attempt at drawing */ retval = r700TryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c index 137f3007ced..6a2a09eaf1a 100644 --- a/src/mesa/drivers/dri/r600/r700_vertprog.c +++ b/src/mesa/drivers/dri/r600/r700_vertprog.c @@ -461,11 +461,11 @@ static void r700TranslateAttrib(GLcontext *ctx, GLuint unLoc, int count, const s stride = (input->StrideB == 0) ? getTypeSize(input->Type) * input->Size : input->StrideB; - if (input->Type == GL_DOUBLE || input->Type == GL_UNSIGNED_INT || input->Type == GL_INT || + if (input->Type == GL_DOUBLE || input->Type == GL_UNSIGNED_INT || input->Type == GL_INT #if MESA_BIG_ENDIAN - getTypeSize(input->Type) != 4 || + || getTypeSize(input->Type) != 4 #endif - stride < 4) + ) { pStreamDesc->type = GL_FLOAT; diff --git a/src/mesa/drivers/dri/radeon/radeon_chipset.h b/src/mesa/drivers/dri/radeon/radeon_chipset.h index b7ee9a134bf..7d54fabebbc 100644 --- a/src/mesa/drivers/dri/radeon/radeon_chipset.h +++ b/src/mesa/drivers/dri/radeon/radeon_chipset.h @@ -414,9 +414,9 @@ enum { CHIP_FAMILY_R350, CHIP_FAMILY_RV350, CHIP_FAMILY_RV380, + CHIP_FAMILY_RS400, CHIP_FAMILY_R420, CHIP_FAMILY_RV410, - CHIP_FAMILY_RS400, CHIP_FAMILY_RS600, CHIP_FAMILY_RS690, CHIP_FAMILY_RS740, diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c index 13f1f0611b8..c1a660af3d0 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common.c +++ b/src/mesa/drivers/dri/radeon/radeon_common.c @@ -708,7 +708,6 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb) if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) { rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer); radeon->front_cliprects = GL_TRUE; - radeon->front_buffer_dirty = GL_TRUE; } else { rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); radeon->front_cliprects = GL_FALSE; @@ -1132,17 +1131,13 @@ flush_front: if (screen->dri2.loader && (screen->dri2.loader->base.version >= 2) && (screen->dri2.loader->flushFrontBuffer != NULL)) { __DRIdrawable * drawable = radeon_get_drawable(radeon); - (*screen->dri2.loader->flushFrontBuffer)(drawable, drawable->loaderPrivate); - /* Only clear the dirty bit if front-buffer rendering is no longer - * enabled. This is done so that the dirty bit can only be set in - * glDrawBuffer. Otherwise the dirty bit would have to be set at - * each of N places that do rendering. This has worse performances, - * but it is much easier to get correct. + /* We set the dirty bit in radeon_prepare_render() if we're + * front buffer rendering once we get there. */ - if (!radeon->is_front_buffer_rendering) { - radeon->front_buffer_dirty = GL_FALSE; - } + radeon->front_buffer_dirty = GL_FALSE; + + (*screen->dri2.loader->flushFrontBuffer)(drawable, drawable->loaderPrivate); } } } diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c index 5a7d52c4d2f..92663bf66d7 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c @@ -493,6 +493,50 @@ radeon_bits_per_pixel(const struct radeon_renderbuffer *rb) return _mesa_get_format_bytes(rb->base.Format) * 8; } +/* + * Check if drawable has been invalidated by dri2InvalidateDrawable(). + * Update renderbuffers if so. This prevents a client from accessing + * a backbuffer that has a swap pending but not yet completed. + * + * See intel_prepare_render for equivalent code in intel driver. + * + */ +void radeon_prepare_render(radeonContextPtr radeon) +{ + __DRIcontext *driContext = radeon->dri.context; + __DRIdrawable *drawable; + __DRIscreen *screen; + + screen = driContext->driScreenPriv; + if (!screen->dri2.loader) + return; + + drawable = driContext->driDrawablePriv; + if (drawable->dri2.stamp != driContext->dri2.draw_stamp) { + if (drawable->lastStamp != drawable->dri2.stamp) + radeon_update_renderbuffers(driContext, drawable, GL_FALSE); + + /* Intel driver does the equivalent of this, no clue if it is needed: + * radeon_draw_buffer(radeon->glCtx, &(drawable->driverPrivate)->base); + */ + driContext->dri2.draw_stamp = drawable->dri2.stamp; + } + + drawable = driContext->driReadablePriv; + if (drawable->dri2.stamp != driContext->dri2.read_stamp) { + if (drawable->lastStamp != drawable->dri2.stamp) + radeon_update_renderbuffers(driContext, drawable, GL_FALSE); + driContext->dri2.read_stamp = drawable->dri2.stamp; + } + + /* If we're currently rendering to the front buffer, the rendering + * that will happen next will probably dirty the front buffer. So + * mark it as dirty here. + */ + if (radeon->is_front_buffer_rendering) + radeon->front_buffer_dirty = GL_TRUE; +} + void radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, GLboolean front_only) @@ -514,6 +558,11 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, screen = context->driScreenPriv; radeon = (radeonContextPtr) context->driverPrivate; + /* Set this up front, so that in case our buffers get invalidated + * while we're getting new buffers, we don't clobber the stamp and + * thus ignore the invalidate. */ + drawable->lastStamp = drawable->dri2.stamp; + if (screen->dri2.loader && (screen->dri2.loader->base.version > 2) && (screen->dri2.loader->getBuffersWithFormat != NULL)) { @@ -650,6 +699,13 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, rb->base.Height = drawable->h; rb->has_surface = 0; + /* r6xx+ tiling */ + rb->tile_config = radeon->radeonScreen->tile_config; + rb->group_bytes = radeon->radeonScreen->group_bytes; + rb->num_channels = radeon->radeonScreen->num_channels; + rb->num_banks = radeon->radeonScreen->num_banks; + rb->r7xx_bank_op = radeon->radeonScreen->r7xx_bank_op; + if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) { if (RADEON_DEBUG & RADEON_DRI) fprintf(stderr, "(reusing depth buffer as stencil)\n"); @@ -678,7 +734,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, bo->flags |= RADEON_BO_FLAGS_MACRO_TILE; if (tiling_flags & RADEON_TILING_MICRO) bo->flags |= RADEON_BO_FLAGS_MICRO_TILE; - + } if (buffers[i].attachment == __DRI_BUFFER_DEPTH) { diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index 5156c5d0d0a..f06e5fdf244 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -93,6 +93,13 @@ struct radeon_renderbuffer GLuint pf_pending; /**< sequence number of pending flip */ GLuint vbl_pending; /**< vblank sequence number of pending flip */ __DRIdrawable *dPriv; + + /* r6xx+ tiling */ + GLuint tile_config; + GLint group_bytes; + GLint num_channels; + GLint num_banks; + GLint r7xx_bank_op; }; struct radeon_framebuffer @@ -614,5 +621,6 @@ GLboolean radeonMakeCurrent(__DRIcontext * driContextPriv, __DRIdrawable * driDrawPriv, __DRIdrawable * driReadPriv); extern void radeonDestroyContext(__DRIcontext * driContextPriv); +void radeon_prepare_render(radeonContextPtr radeon); #endif diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index c877e6c1765..c6e5f110ea3 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -133,7 +133,7 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree height = _mesa_next_pow_two_32(lvl->height); lvl->rowstride = get_texture_image_row_stride(rmesa, mt->mesaFormat, lvl->width, mt->tilebits); - lvl->size = get_texture_image_size(mt->mesaFormat, lvl->rowstride, lvl->height, lvl->depth, mt->tilebits); + lvl->size = get_texture_image_size(mt->mesaFormat, lvl->rowstride, height, lvl->depth, mt->tilebits); assert(lvl->size > 0); diff --git a/src/mesa/drivers/dri/radeon/radeon_pixel_read.c b/src/mesa/drivers/dri/radeon/radeon_pixel_read.c index dadb8002c7d..fb741173ca8 100644 --- a/src/mesa/drivers/dri/radeon/radeon_pixel_read.c +++ b/src/mesa/drivers/dri/radeon/radeon_pixel_read.c @@ -179,6 +179,9 @@ radeonReadPixels(GLcontext * ctx, GLenum format, GLenum type, const struct gl_pixelstore_attrib *pack, GLvoid * pixels) { + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + radeon_prepare_render(radeon); + if (do_blit_readpixels(ctx, x, y, width, height, format, type, pack, pixels)) return; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 82107cc6aeb..fa97a19302c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -213,6 +213,10 @@ static const GLuint __driNConfigOptions = 17; static int getSwapInfo( __DRIdrawable *dPriv, __DRIswapInfo * sInfo ); +#ifndef RADEON_INFO_TILE_CONFIG +#define RADEON_INFO_TILE_CONFIG 0x6 +#endif + static int radeonGetParam(__DRIscreen *sPriv, int param, void *value) { @@ -232,6 +236,9 @@ radeonGetParam(__DRIscreen *sPriv, int param, void *value) case RADEON_PARAM_NUM_Z_PIPES: info.request = RADEON_INFO_NUM_Z_PIPES; break; + case RADEON_INFO_TILE_CONFIG: + info.request = RADEON_INFO_TILE_CONFIG; + break; default: return -EINVAL; } @@ -376,6 +383,21 @@ static const __DRItexBufferExtension r600TexBufferExtension = { }; #endif +static void +radeonDRI2Flush(__DRIdrawable *drawable) +{ + radeonContextPtr rmesa; + + rmesa = (radeonContextPtr) drawable->driContextPriv->driverPrivate; + radeonFlush(rmesa->glCtx); +} + +static const struct __DRI2flushExtensionRec radeonFlushExtension = { + { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, + radeonDRI2Flush, + dri2InvalidateDrawable, +}; + static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) { screen->device_id = device_id; @@ -1305,6 +1327,56 @@ radeonCreateScreen2(__DRIscreen *sPriv) else screen->chip_flags |= RADEON_CLASS_R600; + /* r6xx+ tiling */ + if (IS_R600_CLASS(screen) && (sPriv->drm_version.minor >= 6)) { + ret = radeonGetParam(sPriv, RADEON_INFO_TILE_CONFIG, &temp); + if (ret) + fprintf(stderr, "failed to get tiling info\n"); + else { + screen->tile_config = temp; + screen->r7xx_bank_op = 0; + switch((screen->tile_config & 0xe) >> 1) { + case 0: + screen->num_channels = 1; + break; + case 1: + screen->num_channels = 2; + break; + case 2: + screen->num_channels = 4; + break; + case 3: + screen->num_channels = 8; + break; + default: + fprintf(stderr, "bad channels\n"); + break; + } + switch((screen->tile_config & 0x30) >> 4) { + case 0: + screen->num_banks = 4; + break; + case 1: + screen->num_banks = 8; + break; + default: + fprintf(stderr, "bad banks\n"); + break; + } + switch((screen->tile_config & 0xc0) >> 6) { + case 0: + screen->group_bytes = 256; + break; + case 1: + screen->group_bytes = 512; + break; + default: + fprintf(stderr, "bad group_bytes\n"); + break; + } + } + } + if (IS_R300_CLASS(screen)) { ret = radeonGetParam(sPriv, RADEON_PARAM_NUM_GB_PIPES, &temp); if (ret) { @@ -1379,6 +1451,8 @@ radeonCreateScreen2(__DRIscreen *sPriv) screen->extensions[i++] = &r600TexBufferExtension.base; #endif + screen->extensions[i++] = &radeonFlushExtension.base; + screen->extensions[i++] = NULL; sPriv->extensions = screen->extensions; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h index 0d7e335fa3a..2b33201a538 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.h +++ b/src/mesa/drivers/dri/radeon/radeon_screen.h @@ -112,6 +112,13 @@ typedef struct radeon_screen { int kernel_mm; drm_radeon_sarea_t *sarea; /* Private SAREA data */ struct radeon_bo_manager *bom; + + /* r6xx+ tiling */ + GLuint tile_config; + GLint group_bytes; + GLint num_channels; + GLint num_banks; + GLint r7xx_bank_op; } radeonScreenRec, *radeonScreenPtr; #define IS_R100_CLASS(screen) \ diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index 1adb6096033..9dfe2dd2433 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -111,7 +111,6 @@ static GLubyte *r200_depth_4byte(const struct radeon_renderbuffer * rrb, * two main types: * - 1D (akin to macro-linear/micro-tiled on older asics) * - 2D (akin to macro-tiled/micro-tiled on older asics) - * only 1D tiling is implemented below */ #if defined(RADEON_R600) static inline GLint r600_1d_tile_helper(const struct radeon_renderbuffer * rrb, @@ -208,12 +207,190 @@ static inline GLint r600_1d_tile_helper(const struct radeon_renderbuffer * rrb, return offset; } +static inline GLint r600_log2(GLint n) +{ + GLint log2 = 0; + + while (n >>= 1) + ++log2; + return log2; +} + +static inline GLint r600_2d_tile_helper(const struct radeon_renderbuffer * rrb, + GLint x, GLint y, GLint is_depth, GLint is_stencil) +{ + GLint group_bytes = rrb->group_bytes; + GLint num_channels = rrb->num_channels; + GLint num_banks = rrb->num_banks; + GLint r7xx_bank_op = rrb->r7xx_bank_op; + /* */ + GLint group_bits = r600_log2(group_bytes); + GLint channel_bits = r600_log2(num_channels); + GLint bank_bits = r600_log2(num_banks); + GLint element_bytes = rrb->cpp; + GLint num_samples = 1; + GLint tile_width = 8; + GLint tile_height = 8; + GLint tile_thickness = 1; + GLint macro_tile_width = num_banks; + GLint macro_tile_height = num_channels; + GLint pitch_elements = (rrb->pitch / element_bytes) / tile_width; + GLint height = rrb->base.Height / tile_height; + GLint z = 0; + GLint sample_number = 0; + /* */ + GLint tile_bytes; + GLint macro_tile_bytes; + GLint macro_tiles_per_row; + GLint macro_tiles_per_slice; + GLint slice_offset; + GLint macro_tile_row_index; + GLint macro_tile_column_index; + GLint macro_tile_offset; + GLint pixel_number = 0; + GLint element_offset; + GLint bank = 0; + GLint channel = 0; + GLint total_offset; + GLint group_mask = (1 << group_bits) - 1; + GLint offset_low; + GLint offset_high; + GLint offset = 0; + + switch (num_channels) { + case 2: + default: + // channel[0] = x[3] ^ y[3] + channel |= (((x >> 3) ^ (y >> 3)) & 1) << 0; + break; + case 4: + // channel[0] = x[4] ^ y[3] + channel |= (((x >> 4) ^ (y >> 3)) & 1) << 0; + // channel[1] = x[3] ^ y[4] + channel |= (((x >> 3) ^ (y >> 4)) & 1) << 1; + break; + case 8: + // channel[0] = x[5] ^ y[3] + channel |= (((x >> 5) ^ (y >> 3)) & 1) << 0; + // channel[0] = x[4] ^ x[5] ^ y[4] + channel |= (((x >> 4) ^ (x >> 5) ^ (y >> 4)) & 1) << 1; + // channel[0] = x[3] ^ y[5] + channel |= (((x >> 3) ^ (y >> 5)) & 1) << 2; + break; + } + + switch (num_banks) { + case 4: + // bank[0] = x[3] ^ y[4 + log2(num_channels)] + bank |= (((x >> 3) ^ (y >> (4 + channel_bits))) & 1) << 0; + if (r7xx_bank_op) + // bank[1] = x[3] ^ y[4 + log2(num_channels)] ^ x[5] + bank |= (((x >> 4) ^ (y >> (3 + channel_bits)) ^ (x >> 5)) & 1) << 1; + else + // bank[1] = x[4] ^ y[3 + log2(num_channels)] + bank |= (((x >> 4) ^ (y >> (3 + channel_bits))) & 1) << 1; + break; + case 8: + // bank[0] = x[3] ^ y[5 + log2(num_channels)] + bank |= (((x >> 3) ^ (y >> (5 + channel_bits))) & 1) << 0; + // bank[1] = x[4] ^ y[4 + log2(num_channels)] ^ y[5 + log2(num_channels)] + bank |= (((x >> 4) ^ (y >> (4 + channel_bits)) ^ (y >> (5 + channel_bits))) & 1) << 1; + if (r7xx_bank_op) + // bank[2] = x[5] ^ y[3 + log2(num_channels)] ^ x[6] + bank |= (((x >> 5) ^ (y >> (3 + channel_bits)) ^ (x >> 6)) & 1) << 2; + else + // bank[2] = x[5] ^ y[3 + log2(num_channels)] + bank |= (((x >> 5) ^ (y >> (3 + channel_bits))) & 1) << 2; + break; + } + + tile_bytes = tile_width * tile_height * tile_thickness * element_bytes * num_samples; + macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes; + macro_tiles_per_row = pitch_elements / macro_tile_width; + macro_tiles_per_slice = macro_tiles_per_row * (height / macro_tile_height); + slice_offset = (z / tile_thickness) * macro_tiles_per_slice * macro_tile_bytes; + macro_tile_row_index = (y / tile_height) / macro_tile_height; + macro_tile_column_index = (x / tile_width) / macro_tile_width; + macro_tile_offset = ((macro_tile_row_index * macro_tiles_per_row) + macro_tile_column_index) * macro_tile_bytes; + + if (is_depth) { + GLint pixel_offset = 0; + + pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0] + pixel_number |= ((y >> 0) & 1) << 1; // pn[1] = y[0] + pixel_number |= ((x >> 1) & 1) << 2; // pn[2] = x[1] + pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1] + pixel_number |= ((x >> 2) & 1) << 4; // pn[4] = x[2] + pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2] + switch (element_bytes) { + case 2: + pixel_offset = pixel_number * element_bytes * num_samples; + break; + case 4: + /* stencil and depth data are stored separately within a tile. + * stencil is stored in a contiguous tile before the depth tile. + * stencil element is 1 byte, depth element is 3 bytes. + * stencil tile is 64 bytes. + */ + if (is_stencil) + pixel_offset = pixel_number * 1 * num_samples; + else + pixel_offset = (pixel_number * 3 * num_samples) + 64; + break; + } + element_offset = pixel_offset + (sample_number * element_bytes); + } else { + GLint sample_offset; + + switch (element_bytes) { + case 1: + pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0] + pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1] + pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2] + pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1] + pixel_number |= ((y >> 0) & 1) << 4; // pn[4] = y[0] + pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2] + break; + case 2: + pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0] + pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1] + pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2] + pixel_number |= ((y >> 0) & 1) << 3; // pn[3] = y[0] + pixel_number |= ((y >> 1) & 1) << 4; // pn[4] = y[1] + pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2] + break; + case 4: + pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0] + pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1] + pixel_number |= ((y >> 0) & 1) << 2; // pn[2] = y[0] + pixel_number |= ((x >> 2) & 1) << 3; // pn[3] = x[2] + pixel_number |= ((y >> 1) & 1) << 4; // pn[4] = y[1] + pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2] + break; + } + sample_offset = sample_number * (tile_bytes / num_samples); + element_offset = sample_offset + (pixel_number * element_bytes); + } + total_offset = (slice_offset + macro_tile_offset) >> (channel_bits + bank_bits); + total_offset += element_offset; + + offset_low = total_offset & group_mask; + offset_high = (total_offset & ~group_mask) << (channel_bits + bank_bits); + offset = (bank << (group_bits + channel_bits)) + (channel << group_bits) + offset_low + offset_high; + + return offset; +} + /* depth buffers */ static GLubyte *r600_ptr_depth(const struct radeon_renderbuffer * rrb, GLint x, GLint y) { GLubyte *ptr = rrb->bo->ptr; - GLint offset = r600_1d_tile_helper(rrb, x, y, 1, 0); + GLint offset; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) + offset = r600_2d_tile_helper(rrb, x, y, 1, 0); + else + offset = r600_1d_tile_helper(rrb, x, y, 1, 0); return &ptr[offset]; } @@ -221,7 +398,11 @@ static GLubyte *r600_ptr_stencil(const struct radeon_renderbuffer * rrb, GLint x, GLint y) { GLubyte *ptr = rrb->bo->ptr; - GLint offset = r600_1d_tile_helper(rrb, x, y, 1, 1); + GLint offset; + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) + offset = r600_2d_tile_helper(rrb, x, y, 1, 1); + else + offset = r600_1d_tile_helper(rrb, x, y, 1, 1); return &ptr[offset]; } @@ -235,7 +416,10 @@ static GLubyte *r600_ptr_color(const struct radeon_renderbuffer * rrb, if (rrb->has_surface || !(rrb->bo->flags & mask)) { offset = x * rrb->cpp + y * rrb->pitch; } else { - offset = r600_1d_tile_helper(rrb, x, y, 0, 0); + if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE) + offset = r600_2d_tile_helper(rrb, x, y, 0, 0); + else + offset = r600_1d_tile_helper(rrb, x, y, 0, 0); } return &ptr[offset]; } diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c index f2fcb46688a..29defe73a70 100644 --- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c @@ -40,7 +40,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "main/macros.h" #include "main/simple_list.h" +#include "math/m_xform.h" + #include "swrast_setup/swrast_setup.h" + #include "tnl/tnl.h" #include "tnl/t_context.h" #include "tnl/t_pipeline.h" @@ -408,6 +411,8 @@ static GLboolean radeon_run_render( GLcontext *ctx, !radeon_dma_validate_render( ctx, VB )) return GL_TRUE; + radeon_prepare_render(&rmesa->radeon); + tnl->Driver.Render.Start( ctx ); for (i = 0 ; i < VB->PrimitiveCount ; i++) diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index ea796e1a45f..5e1718f9dfc 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -252,6 +252,8 @@ void radeonTclPrimitive( GLcontext *ctx, GLuint se_cntl; GLuint newprim = hw_prim | RADEON_CP_VC_CNTL_TCL_ENABLE; + radeon_prepare_render(&rmesa->radeon); + if (newprim != rmesa->tcl.hw_primitive || !discrete_prim[hw_prim&0xf]) { RADEON_NEWPRIM( rmesa ); diff --git a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c index 29fd31ac23f..4cb0bb60c85 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c @@ -153,6 +153,9 @@ radeonCopyTexImage2D(GLcontext *ctx, GLenum target, GLint level, _mesa_select_tex_image(ctx, texObj, target, level); int srcx, srcy, dstx, dsty; + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + radeon_prepare_render(radeon); + if (border) goto fail; @@ -202,6 +205,9 @@ radeonCopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj = _mesa_select_tex_object(ctx, texUnit, target); struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texObj, target, level); + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + radeon_prepare_render(radeon); + if (!do_copy_texsubimage(ctx, target, level, radeon_tex_obj(texObj), (radeon_texture_image *)texImage, xoffset, yoffset, x, y, width, height)) { diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index d2b190e42e0..8c6a50d2f0d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -551,7 +551,7 @@ gl_format radeonChooseTextureFormat(GLcontext * ctx, case GL_SRGB8_ALPHA8: case GL_COMPRESSED_SRGB: case GL_COMPRESSED_SRGB_ALPHA: - return MESA_FORMAT_SRGBA8; + return MESA_FORMAT_SARGB8; case GL_SLUMINANCE: case GL_SLUMINANCE8: diff --git a/src/mesa/drivers/dri/savage/savagerender.c b/src/mesa/drivers/dri/savage/savagerender.c index c369bb124c2..2d9e80e29c4 100644 --- a/src/mesa/drivers/dri/savage/savagerender.c +++ b/src/mesa/drivers/dri/savage/savagerender.c @@ -33,6 +33,8 @@ #include "main/imports.h" #include "main/mtypes.h" +#include "math/m_xform.h" + #include "tnl/t_context.h" #include "savagecontext.h" diff --git a/src/mesa/drivers/dri/unichrome/via_render.c b/src/mesa/drivers/dri/unichrome/via_render.c index 896c43db1b0..4351f119555 100644 --- a/src/mesa/drivers/dri/unichrome/via_render.c +++ b/src/mesa/drivers/dri/unichrome/via_render.c @@ -33,6 +33,8 @@ #include "main/macros.h" #include "main/mtypes.h" +#include "math/m_xform.h" + #include "tnl/t_context.h" #include "via_context.h" diff --git a/src/mesa/main/arbprogram.h b/src/mesa/main/arbprogram.h index 787ffd62f4b..e2e535e911e 100644 --- a/src/mesa/main/arbprogram.h +++ b/src/mesa/main/arbprogram.h @@ -27,7 +27,6 @@ #define ARBPROGRAM_H -#include "compiler.h" #include "glheader.h" diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h index 8999edc724f..fdf7e2bca46 100644 --- a/src/mesa/main/arrayobj.h +++ b/src/mesa/main/arrayobj.h @@ -28,7 +28,7 @@ #ifndef ARRAYOBJ_H #define ARRAYOBJ_H -#include "context.h" +#include "mtypes.h" /** * \file arrayobj.h diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 002448fedb8..753949be503 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -41,6 +41,7 @@ #include "hint.h" #include "light.h" #include "lines.h" +#include "macros.h" #include "matrix.h" #include "multisample.h" #include "points.h" diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h index 912529cfdf9..f234d06c6cc 100644 --- a/src/mesa/main/bufferobj.h +++ b/src/mesa/main/bufferobj.h @@ -29,7 +29,7 @@ #define BUFFEROBJ_H -#include "context.h" +#include "mtypes.h" /* diff --git a/src/mesa/main/clear.c b/src/mesa/main/clear.c index e76ab5527b0..49d86b3b1f1 100644 --- a/src/mesa/main/clear.c +++ b/src/mesa/main/clear.c @@ -35,6 +35,7 @@ #include "context.h" #include "colormac.h" #include "enums.h" +#include "macros.h" #include "state.h" diff --git a/src/mesa/main/clear.h b/src/mesa/main/clear.h index 4c78eeda488..6657370c4b6 100644 --- a/src/mesa/main/clear.h +++ b/src/mesa/main/clear.h @@ -27,7 +27,7 @@ #define CLEAR_H -#include "main/mtypes.h" +#include "glheader.h" extern void GLAPIENTRY diff --git a/src/mesa/main/clip.h b/src/mesa/main/clip.h index d53afb45bdf..ac472d66e08 100644 --- a/src/mesa/main/clip.h +++ b/src/mesa/main/clip.h @@ -31,7 +31,7 @@ #ifndef CLIP_H #define CLIP_H -#include "mtypes.h" +#include "glheader.h" extern void GLAPIENTRY _mesa_ClipPlane( GLenum plane, const GLdouble *equation ); diff --git a/src/mesa/main/colormac.h b/src/mesa/main/colormac.h index 905f4e22837..245fb658bb3 100644 --- a/src/mesa/main/colormac.h +++ b/src/mesa/main/colormac.h @@ -33,9 +33,9 @@ #define COLORMAC_H -#include "imports.h" #include "config.h" #include "macros.h" +#include "mtypes.h" /** \def BYTE_TO_CHAN diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 32f7d969d8d..0f2d1a8f8da 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -177,7 +177,7 @@ /** * Per-program constants (power of two) * - * \c MAX_PROGRAM_LOCAL_PARAMS and \c MAX_UNIFORMS are just the assmebly shader + * \c MAX_PROGRAM_LOCAL_PARAMS and \c MAX_UNIFORMS are just the assembly shader * and GLSL shader names for the same thing. They should \b always have the * same value. Each refers to the number of vec4 values supplied as * per-program parameters. diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index a369532e99c..b01fed1781e 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -462,7 +462,7 @@ _mesa_init_current(GLcontext *ctx) /** - * Init vertex/fragment program limits. + * Init vertex/fragment/geometry program limits. * Important: drivers should override these with actual limits. */ static void @@ -477,16 +477,18 @@ init_program_limits(GLenum type, struct gl_program_constants *prog) prog->MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; prog->MaxUniformComponents = 4 * MAX_UNIFORMS; - if (type == GL_VERTEX_PROGRAM_ARB) { + switch (type) { + case GL_VERTEX_PROGRAM_ARB: prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS; prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; - } - else if (type == GL_FRAGMENT_PROGRAM_ARB) { + break; + case GL_FRAGMENT_PROGRAM_ARB: prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS; prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS; prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; - } else { + break; + case MESA_GEOMETRY_PROGRAM: prog->MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS; prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS; prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; @@ -497,6 +499,9 @@ init_program_limits(GLenum type, struct gl_program_constants *prog) prog->MaxGeometryUniformComponents = MAX_GEOMETRY_UNIFORM_COMPONENTS; prog->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES; prog->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS; + break; + default: + assert(0 && "Bad program type in init_program_limits()"); } /* Set the native limits to zero. This implies that there is no native diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c index 15e8dffc230..f63bddc44d5 100644 --- a/src/mesa/main/convolve.c +++ b/src/mesa/main/convolve.c @@ -37,6 +37,7 @@ #include "convolve.h" #include "context.h" #include "image.h" +#include "macros.h" #include "mtypes.h" #include "state.h" #include "main/dispatch.h" diff --git a/src/mesa/main/debug.h b/src/mesa/main/debug.h index 0449cb1798a..b517cc8259f 100644 --- a/src/mesa/main/debug.h +++ b/src/mesa/main/debug.h @@ -36,6 +36,9 @@ #ifndef _DEBUG_H #define _DEBUG_H +#include "glheader.h" +#include "mtypes.h" + #if _HAVE_FULL_GL extern void _mesa_print_tri_caps( const char *name, GLuint flags ); diff --git a/src/mesa/main/depthstencil.h b/src/mesa/main/depthstencil.h index 3dde081f5a5..afbac77f0e2 100644 --- a/src/mesa/main/depthstencil.h +++ b/src/mesa/main/depthstencil.h @@ -26,6 +26,7 @@ #ifndef DEPTHSTENCIL_H #define DEPTHSTENCIL_H +#include "mtypes.h" extern struct gl_renderbuffer * _mesa_new_z24_renderbuffer_wrapper(GLcontext *ctx, diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 8c86b392c7b..9a84e5a79cf 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -97,6 +97,11 @@ _mesa_init_fbobjects(GLcontext *ctx) DummyRenderbuffer.Delete = delete_dummy_renderbuffer; } +struct gl_framebuffer * +_mesa_get_incomplete_framebuffer(void) +{ + return &DummyFramebuffer; +} /** * Helper routine for getting a gl_renderbuffer. diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h index ff946033a4d..9850ee9aa23 100644 --- a/src/mesa/main/fbobject.h +++ b/src/mesa/main/fbobject.h @@ -26,10 +26,14 @@ #ifndef FBOBJECT_H #define FBOBJECT_H +#include "mtypes.h" extern void _mesa_init_fbobjects(GLcontext *ctx); +extern struct gl_framebuffer * +_mesa_get_incomplete_framebuffer(void); + extern struct gl_renderbuffer * _mesa_lookup_renderbuffer(GLcontext *ctx, GLuint id); diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c index 269ff3f8b99..9f26c012d66 100644 --- a/src/mesa/main/fog.c +++ b/src/mesa/main/fog.c @@ -27,6 +27,7 @@ #include "colormac.h" #include "context.h" #include "fog.h" +#include "macros.h" #include "mtypes.h" diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index 49463fcc3c2..90449cc04f0 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -26,7 +26,6 @@ #include "imports.h" #include "formats.h" -#include "config.h" /** diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h index aa14185628f..ad176caaa0f 100644 --- a/src/mesa/main/formats.h +++ b/src/mesa/main/formats.h @@ -33,7 +33,7 @@ #define FORMATS_H -#include "main/mtypes.h" +#include <GL/gl.h> diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index 56558cfcc1e..e0aac26f62b 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -75,7 +75,6 @@ compute_depth_max(struct gl_framebuffer *fb) fb->_MRD = (GLfloat)1.0 / fb->_DepthMaxF; } - /** * Create and initialize a gl_framebuffer object. * This is intended for creating _window_system_ framebuffers, not generic diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h index 1b6e3b1f0cb..2e9844282f8 100644 --- a/src/mesa/main/framebuffer.h +++ b/src/mesa/main/framebuffer.h @@ -26,6 +26,7 @@ #ifndef FRAMEBUFFER_H #define FRAMEBUFFER_H +#include "mtypes.h" extern struct gl_framebuffer * _mesa_create_framebuffer(const GLvisual *visual); diff --git a/src/mesa/main/get.h b/src/mesa/main/get.h index 320492b4ce2..99a004b71dd 100644 --- a/src/mesa/main/get.h +++ b/src/mesa/main/get.h @@ -32,7 +32,7 @@ #define GET_H -#include "mtypes.h" +#include "glheader.h" extern void GLAPIENTRY diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c index 3a65bb19260..4e482bcd54b 100644 --- a/src/mesa/main/histogram.c +++ b/src/mesa/main/histogram.c @@ -29,6 +29,7 @@ #include "context.h" #include "image.h" #include "histogram.h" +#include "macros.h" #include "main/dispatch.h" diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 63c28342f26..86aa6d0d702 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -32,7 +32,6 @@ #include "glheader.h" #include "colormac.h" -#include "context.h" #include "enums.h" #include "image.h" #include "imports.h" diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index 25080db40c4..46e5c932d0f 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -756,7 +756,7 @@ _mesa_strdup( const char *s ) float _mesa_strtof( const char *s, char **end ) { -#ifdef _GNU_SOURCE +#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) static locale_t loc = NULL; if (!loc) { loc = newlocale(LC_CTYPE_MASK, "C", NULL); diff --git a/src/mesa/main/mm.c b/src/mesa/main/mm.c index 3ef38e94be9..25a0293703c 100644 --- a/src/mesa/main/mm.c +++ b/src/mesa/main/mm.c @@ -22,6 +22,11 @@ * */ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +#include "compiler.h" #include "mm.h" diff --git a/src/mesa/main/mm.h b/src/mesa/main/mm.h index df340808ac9..228721ca2a5 100644 --- a/src/mesa/main/mm.h +++ b/src/mesa/main/mm.h @@ -32,9 +32,6 @@ #define MM_H -#include "imports.h" - - struct mem_block { struct mem_block *next, *prev; struct mem_block *next_free, *prev_free; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index cbb9eb84f33..8d92892ad7d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -36,7 +36,6 @@ #include "main/glheader.h" #include "main/config.h" -#include "main/compiler.h" #include "main/mfeatures.h" #include "glapi/glapi.h" #include "math/m_matrix.h" /* GLmatrix */ @@ -1808,6 +1807,11 @@ struct gl_program /** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */ gl_texture_index SamplerTargets[MAX_SAMPLERS]; + /** Bitmask of which register files are read/written with indirect + * addressing. Mask of (1 << PROGRAM_x) bits. + */ + GLbitfield IndirectRegisterFiles; + /** Logical counts */ /*@{*/ GLuint NumInstructions; @@ -2477,29 +2481,29 @@ struct gl_framebuffer /** - * Limits for vertex and fragment programs. + * Limits for vertex and fragment programs/shaders. */ struct gl_program_constants { /* logical limits */ GLuint MaxInstructions; - GLuint MaxAluInstructions; /* fragment programs only, for now */ - GLuint MaxTexInstructions; /* fragment programs only, for now */ - GLuint MaxTexIndirections; /* fragment programs only, for now */ + GLuint MaxAluInstructions; + GLuint MaxTexInstructions; + GLuint MaxTexIndirections; GLuint MaxAttribs; GLuint MaxTemps; - GLuint MaxAddressRegs; /* vertex program only, for now */ + GLuint MaxAddressRegs; GLuint MaxParameters; GLuint MaxLocalParams; GLuint MaxEnvParams; /* native/hardware limits */ GLuint MaxNativeInstructions; - GLuint MaxNativeAluInstructions; /* fragment programs only, for now */ - GLuint MaxNativeTexInstructions; /* fragment programs only, for now */ - GLuint MaxNativeTexIndirections; /* fragment programs only, for now */ + GLuint MaxNativeAluInstructions; + GLuint MaxNativeTexInstructions; + GLuint MaxNativeTexIndirections; GLuint MaxNativeAttribs; GLuint MaxNativeTemps; - GLuint MaxNativeAddressRegs; /* vertex program only, for now */ + GLuint MaxNativeAddressRegs; GLuint MaxNativeParameters; /* For shaders */ GLuint MaxUniformComponents; diff --git a/src/mesa/main/multisample.h b/src/mesa/main/multisample.h index 4305900cc49..998488ef420 100644 --- a/src/mesa/main/multisample.h +++ b/src/mesa/main/multisample.h @@ -26,6 +26,7 @@ #ifndef MULTISAMPLE_H #define MULTISAMPLE_H +#include "mtypes.h" extern void GLAPIENTRY _mesa_SampleCoverageARB(GLclampf value, GLboolean invert); diff --git a/src/mesa/main/nvprogram.h b/src/mesa/main/nvprogram.h index 8ee59661bd0..260a25ba9e9 100644 --- a/src/mesa/main/nvprogram.h +++ b/src/mesa/main/nvprogram.h @@ -29,6 +29,8 @@ #ifndef NVPROGRAM_H #define NVPROGRAM_H +#include "glheader.h" +#include "mtypes.h" extern void GLAPIENTRY _mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params); diff --git a/src/mesa/main/pixelstore.h b/src/mesa/main/pixelstore.h index ee963f9ba3c..47bff4276d1 100644 --- a/src/mesa/main/pixelstore.h +++ b/src/mesa/main/pixelstore.h @@ -33,6 +33,7 @@ #include "glheader.h" +#include "mtypes.h" extern void GLAPIENTRY diff --git a/src/mesa/main/querymatrix.c b/src/mesa/main/querymatrix.c index 6f62415ba8c..32aaa79f7fb 100644 --- a/src/mesa/main/querymatrix.c +++ b/src/mesa/main/querymatrix.c @@ -36,9 +36,9 @@ #define INT_TO_FIXED(x) ((GLfixed) ((x) << 16)) #define FLOAT_TO_FIXED(x) ((GLfixed) ((x) * 65536.0)) -#if defined(WIN32) || defined(_WIN32_WCE) +#if defined(_MSC_VER) /* Oddly, the fpclassify() function doesn't exist in such a form - * on Windows. This is an implementation using slightly different + * on MSVC. This is an implementation using slightly different * lower-level Windows functions. */ #include <float.h> @@ -72,7 +72,7 @@ fpclassify(double x) #elif defined(__APPLE__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \ defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ - (defined(__sun) && defined(__C99FEATURES__)) + (defined(__sun) && defined(__C99FEATURES__)) || defined(__MINGW32__) /* fpclassify is available. */ diff --git a/src/mesa/main/remap.h b/src/mesa/main/remap.h index 7afdee36f5b..a2a55f615d5 100644 --- a/src/mesa/main/remap.h +++ b/src/mesa/main/remap.h @@ -28,6 +28,7 @@ #define REMAP_H +#include "main/compiler.h" #include "main/mfeatures.h" struct gl_function_pool_remap { diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h index 7c205e141c1..bc92b269821 100644 --- a/src/mesa/main/renderbuffer.h +++ b/src/mesa/main/renderbuffer.h @@ -26,6 +26,11 @@ #ifndef RENDERBUFFER_H #define RENDERBUFFER_H +#include "glheader.h" +#include "mtypes.h" + +struct gl_framebuffer; +struct gl_renderbuffer; extern void _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name); diff --git a/src/mesa/main/restart.h b/src/mesa/main/restart.h index 931cd701281..25f58f24c35 100644 --- a/src/mesa/main/restart.h +++ b/src/mesa/main/restart.h @@ -28,6 +28,7 @@ #ifndef RESTART_H #define RESTART_H +#include "glheader.h" extern void GLAPIENTRY _mesa_PrimitiveRestart(void); diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index f9d10f3bbea..cbe004518a0 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -32,7 +32,6 @@ #include "imports.h" #include "mtypes.h" #include "hash.h" -#include "arrayobj.h" #if FEATURE_ATI_fragment_shader #include "atifragshader.h" #endif diff --git a/src/mesa/main/shared.h b/src/mesa/main/shared.h index ef164a14590..5166a0ce51f 100644 --- a/src/mesa/main/shared.h +++ b/src/mesa/main/shared.h @@ -25,6 +25,7 @@ #ifndef SHARED_H #define SHARED_H +#include "mtypes.h" struct gl_shared_state * _mesa_alloc_shared_state(GLcontext *ctx); diff --git a/src/mesa/main/syncobj.h b/src/mesa/main/syncobj.h index f23fa281e20..c53511995b1 100644 --- a/src/mesa/main/syncobj.h +++ b/src/mesa/main/syncobj.h @@ -31,7 +31,10 @@ #ifndef SYNCOBJ_H #define SYNCOBJ_H -#include "context.h" +#include "glheader.h" +#include "mtypes.h" + +struct dd_function_table; extern void _mesa_init_sync_object_functions(struct dd_function_table *driver); diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index f4b1119eb17..e911524cbc5 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -33,7 +33,6 @@ #include "glheader.h" #include "imports.h" #include "colormac.h" -#include "context.h" #include "formats.h" #include "texcompress.h" diff --git a/src/mesa/main/texcompress_fxt1.c b/src/mesa/main/texcompress_fxt1.c index 04acf05e528..c8b45bd3a55 100644 --- a/src/mesa/main/texcompress_fxt1.c +++ b/src/mesa/main/texcompress_fxt1.c @@ -32,9 +32,9 @@ #include "glheader.h" #include "imports.h" #include "colormac.h" -#include "context.h" #include "convolve.h" #include "image.h" +#include "macros.h" #include "mipmap.h" #include "texcompress.h" #include "texcompress_fxt1.h" diff --git a/src/mesa/main/texcompress_fxt1.h b/src/mesa/main/texcompress_fxt1.h index d63ca71e212..38048b26ccb 100644 --- a/src/mesa/main/texcompress_fxt1.h +++ b/src/mesa/main/texcompress_fxt1.h @@ -25,9 +25,11 @@ #ifndef TEXCOMPRESS_FXT1_H #define TEXCOMPRESS_FXT1_H -#include "main/mtypes.h" +#include "glheader.h" #include "texstore.h" +struct gl_texture_image; + #if FEATURE_texture_fxt1 extern GLboolean diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index 85c394b051f..c70792cab61 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -36,10 +36,10 @@ #include "glheader.h" #include "imports.h" #include "colormac.h" -#include "context.h" #include "convolve.h" #include "dlopen.h" #include "image.h" +#include "macros.h" #include "texcompress.h" #include "texcompress_s3tc.h" #include "texstore.h" diff --git a/src/mesa/main/texfetch.c b/src/mesa/main/texfetch.c index fe002082cca..c03bc71cd7a 100644 --- a/src/mesa/main/texfetch.c +++ b/src/mesa/main/texfetch.c @@ -34,7 +34,7 @@ #include "colormac.h" -#include "context.h" +#include "macros.h" #include "texcompress.h" #include "texcompress_fxt1.h" #include "texcompress_s3tc.h" diff --git a/src/mesa/main/texgen.h b/src/mesa/main/texgen.h index 397d89e630f..2224a937611 100644 --- a/src/mesa/main/texgen.h +++ b/src/mesa/main/texgen.h @@ -27,7 +27,10 @@ #define TEXGEN_H -#include "main/mtypes.h" +#include "compiler.h" +#include "glheader.h" + +struct _glapi_table; #if FEATURE_texgen diff --git a/src/mesa/main/texgetimage.h b/src/mesa/main/texgetimage.h index 088d27c7e17..866ab704945 100644 --- a/src/mesa/main/texgetimage.h +++ b/src/mesa/main/texgetimage.h @@ -27,6 +27,7 @@ #ifndef TEXGETIMAGE_H #define TEXGETIMAGE_H +#include "mtypes.h" extern void _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, diff --git a/src/mesa/main/texrender.c b/src/mesa/main/texrender.c index d29af5a5b2f..c68105b3951 100644 --- a/src/mesa/main/texrender.c +++ b/src/mesa/main/texrender.c @@ -1,6 +1,7 @@ #include "context.h" #include "colormac.h" +#include "macros.h" #include "texfetch.h" #include "texrender.h" #include "renderbuffer.h" diff --git a/src/mesa/main/texrender.h b/src/mesa/main/texrender.h index 7c3fb0871bd..1e87d594a28 100644 --- a/src/mesa/main/texrender.h +++ b/src/mesa/main/texrender.h @@ -1,6 +1,7 @@ #ifndef TEXRENDER_H #define TEXRENDER_H +#include "mtypes.h" extern void _mesa_render_texture(GLcontext *ctx, diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h index 17ac68000c5..912cb677985 100644 --- a/src/mesa/main/texstate.h +++ b/src/mesa/main/texstate.h @@ -32,6 +32,7 @@ #define TEXSTATE_H +#include "compiler.h" #include "mtypes.h" diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 0f21395af39..2989fdb72ed 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -55,7 +55,6 @@ #include "glheader.h" #include "bufferobj.h" #include "colormac.h" -#include "context.h" #include "convolve.h" #include "image.h" #include "macros.h" diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h index 29f77cb35a0..ef98fe16bb1 100644 --- a/src/mesa/main/uniforms.h +++ b/src/mesa/main/uniforms.h @@ -25,6 +25,10 @@ #ifndef UNIFORMS_H #define UNIFORMS_H +#include "glheader.h" + +struct gl_program; +struct _glapi_table; extern void GLAPIENTRY _mesa_Uniform1fARB(GLint, GLfloat); diff --git a/src/mesa/main/viewport.h b/src/mesa/main/viewport.h index f08fef27978..ec054a7c597 100644 --- a/src/mesa/main/viewport.h +++ b/src/mesa/main/viewport.h @@ -27,6 +27,8 @@ #ifndef VIEWPORT_H #define VIEWPORT_H +#include "glheader.h" +#include "mtypes.h" extern void GLAPIENTRY _mesa_Viewport(GLint x, GLint y, GLsizei width, GLsizei height); diff --git a/src/mesa/main/vtxfmt.h b/src/mesa/main/vtxfmt.h index fb6c23abe98..aad38b87c35 100644 --- a/src/mesa/main/vtxfmt.h +++ b/src/mesa/main/vtxfmt.h @@ -33,6 +33,9 @@ #ifndef _VTXFMT_H_ #define _VTXFMT_H_ +#include "compiler.h" +#include "mtypes.h" + #if FEATURE_beginend extern void _mesa_init_exec_vtxfmt( GLcontext *ctx ); diff --git a/src/mesa/math/m_matrix.h b/src/mesa/math/m_matrix.h index 3bc5de6cd4d..a69afb8589a 100644 --- a/src/mesa/math/m_matrix.h +++ b/src/mesa/math/m_matrix.h @@ -32,6 +32,8 @@ #define _M_MATRIX_H +#include "main/glheader.h" + /** * \name Symbolic names to some of the entries in the matrix diff --git a/src/mesa/math/m_translate.c b/src/mesa/math/m_translate.c index b12b07957cb..51daf7bfd37 100644 --- a/src/mesa/math/m_translate.c +++ b/src/mesa/math/m_translate.c @@ -29,8 +29,8 @@ #include "main/glheader.h" +#include "main/macros.h" #include "main/mtypes.h" /* GLchan hack */ -#include "main/colormac.h" #include "m_translate.h" diff --git a/src/mesa/math/m_translate.h b/src/mesa/math/m_translate.h index c677682d506..58041031163 100644 --- a/src/mesa/math/m_translate.h +++ b/src/mesa/math/m_translate.h @@ -26,7 +26,8 @@ #ifndef _M_TRANSLATE_H_ #define _M_TRANSLATE_H_ -#include "main/config.h" +#include "main/compiler.h" +#include "main/glheader.h" #include "main/mtypes.h" /* hack for GLchan */ diff --git a/src/mesa/math/m_xform.h b/src/mesa/math/m_xform.h index 33421ad1c0a..14ac956a7bc 100644 --- a/src/mesa/math/m_xform.h +++ b/src/mesa/math/m_xform.h @@ -27,10 +27,10 @@ #define _M_XFORM_H +#include "main/compiler.h" #include "main/glheader.h" -#include "main/config.h" -#include "math/m_vector.h" #include "math/m_matrix.h" +#include "math/m_vector.h" #ifdef USE_X86_ASM #define _XFORMAPI _ASMAPI diff --git a/src/mesa/program/arbprogparse.c b/src/mesa/program/arbprogparse.c index 6373529e4e8..f834aaf5686 100644 --- a/src/mesa/program/arbprogparse.c +++ b/src/mesa/program/arbprogparse.c @@ -109,6 +109,7 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, program->Base.NumNativeTexIndirections = prog.NumTexIndirections; program->Base.InputsRead = prog.InputsRead; program->Base.OutputsWritten = prog.OutputsWritten; + program->Base.IndirectRegisterFiles = prog.IndirectRegisterFiles; for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) { program->Base.TexturesUsed[i] = prog.TexturesUsed[i]; if (prog.TexturesUsed[i]) @@ -199,6 +200,7 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs; program->Base.InputsRead = prog.InputsRead; program->Base.OutputsWritten = prog.OutputsWritten; + program->Base.IndirectRegisterFiles = prog.IndirectRegisterFiles; program->IsPositionInvariant = (state.option.PositionInvariant) ? GL_TRUE : GL_FALSE; diff --git a/src/mesa/program/hash_table.h b/src/mesa/program/hash_table.h index 7b302f5dbee..e750906f961 100644 --- a/src/mesa/program/hash_table.h +++ b/src/mesa/program/hash_table.h @@ -31,8 +31,6 @@ #ifndef HASH_TABLE_H #define HASH_TABLE_H -#include <string.h> - struct hash_table; typedef unsigned (*hash_func_t)(const void *key); diff --git a/src/mesa/program/nvfragparse.h b/src/mesa/program/nvfragparse.h index 544ab80c56c..e28a6c49349 100644 --- a/src/mesa/program/nvfragparse.h +++ b/src/mesa/program/nvfragparse.h @@ -30,6 +30,7 @@ #ifndef NVFRAGPARSE_H #define NVFRAGPARSE_H +#include "main/mtypes.h" extern void _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum target, diff --git a/src/mesa/program/nvvertparse.c b/src/mesa/program/nvvertparse.c index e2afcfd4ce6..1ac83d0e59d 100644 --- a/src/mesa/program/nvvertparse.c +++ b/src/mesa/program/nvvertparse.c @@ -64,6 +64,7 @@ struct parse_state { GLbitfield inputsRead; GLbitfield outputsWritten; GLboolean anyProgRegsWritten; + GLboolean indirectRegisterFiles; GLuint numInst; /* number of instructions parsed */ }; @@ -410,6 +411,7 @@ Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg) srcReg->RelAddr = GL_TRUE; srcReg->File = PROGRAM_ENV_PARAM; + parseState->indirectRegisterFiles |= (1 << srcReg->File); /* Look for +/-N offset */ if (!Peek_Token(parseState, token)) RETURN_ERROR; @@ -1308,6 +1310,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, parseState.inputsRead = 0; parseState.outputsWritten = 0; parseState.anyProgRegsWritten = GL_FALSE; + parseState.indirectRegisterFiles = 0x0; /* Reset error state */ _mesa_set_program_error(ctx, -1, NULL); @@ -1408,6 +1411,8 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, program->Base.Parameters = _mesa_new_parameter_list (); program->Base.NumParameters = 0; + program->Base.IndirectRegisterFiles = parseState.indirectRegisterFiles; + state_tokens[0] = STATE_VERTEX_PROGRAM; state_tokens[1] = STATE_ENV; /* Add refs to all of the potential params, in order. If we want to not diff --git a/src/mesa/program/nvvertparse.h b/src/mesa/program/nvvertparse.h index 9919e22388d..91ef79e6c3c 100644 --- a/src/mesa/program/nvvertparse.h +++ b/src/mesa/program/nvvertparse.h @@ -29,6 +29,7 @@ #ifndef NVVERTPARSE_H #define NVVERTPARSE_H +#include "main/mtypes.h" extern void _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum target, diff --git a/src/mesa/program/prog_cache.h b/src/mesa/program/prog_cache.h index 4e1ccac03ff..bfe8f99d445 100644 --- a/src/mesa/program/prog_cache.h +++ b/src/mesa/program/prog_cache.h @@ -30,6 +30,9 @@ #define PROG_CACHE_H +#include "main/mtypes.h" + + /** Opaque type */ struct gl_program_cache; diff --git a/src/mesa/program/prog_execute.c b/src/mesa/program/prog_execute.c index f85c6513f31..1670c91b6ad 100644 --- a/src/mesa/program/prog_execute.c +++ b/src/mesa/program/prog_execute.c @@ -37,7 +37,7 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" +#include "main/macros.h" #include "prog_execute.h" #include "prog_instruction.h" #include "prog_parameter.h" @@ -81,6 +81,22 @@ static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; /** + * Return TRUE for +0 and other positive values, FALSE otherwise. + * Used for RCC opcode. + */ +static INLINE GLboolean +positive(float x) +{ + fi_type fi; + fi.f = x; + if (fi.i & 0x80000000) + return GL_FALSE; + return GL_TRUE; +} + + + +/** * Return a pointer to the 4-element float vector specified by the given * source register. */ @@ -1340,6 +1356,44 @@ _mesa_execute_program(GLcontext * ctx, store_vector4(inst, machine, result); } break; + case OPCODE_RCC: /* clamped riciprocal */ + { + const float largest = 1.884467e+19, smallest = 5.42101e-20; + GLfloat a[4], r, result[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + if (DEBUG_PROG) { + if (a[0] == 0) + printf("RCC(0)\n"); + else if (IS_INF_OR_NAN(a[0])) + printf("RCC(inf)\n"); + } + if (a[0] == 1.0F) { + r = 1.0F; + } + else { + r = 1.0F / a[0]; + } + if (positive(r)) { + if (r > largest) { + r = largest; + } + else if (r < smallest) { + r = smallest; + } + } + else { + if (r < -largest) { + r = -largest; + } + else if (r > -smallest) { + r = -smallest; + } + } + result[0] = result[1] = result[2] = result[3] = r; + store_vector4(inst, machine, result); + } + break; + case OPCODE_RCP: { GLfloat a[4], result[4]; diff --git a/src/mesa/program/prog_execute.h b/src/mesa/program/prog_execute.h index adefc5439de..f59b65176ff 100644 --- a/src/mesa/program/prog_execute.h +++ b/src/mesa/program/prog_execute.h @@ -26,6 +26,7 @@ #define PROG_EXECUTE_H #include "main/config.h" +#include "main/mtypes.h" typedef void (*FetchTexelLodFunc)(GLcontext *ctx, const GLfloat texcoord[4], diff --git a/src/mesa/program/prog_instruction.h b/src/mesa/program/prog_instruction.h index dacbc33704b..098b366ab56 100644 --- a/src/mesa/program/prog_instruction.h +++ b/src/mesa/program/prog_instruction.h @@ -38,7 +38,7 @@ #define PROG_INSTRUCTION_H -#include "main/mfeatures.h" +#include "main/glheader.h" /** @@ -149,20 +149,20 @@ typedef enum prog_opcode { OPCODE_ADD, /* X X X X X */ OPCODE_AND, /* */ OPCODE_ARA, /* 2 */ - OPCODE_ARL, /* X X */ + OPCODE_ARL, /* X X X */ OPCODE_ARL_NV, /* 2 */ OPCODE_ARR, /* 2 */ OPCODE_BGNLOOP, /* opt */ OPCODE_BGNSUB, /* opt */ OPCODE_BRA, /* 2 X */ OPCODE_BRK, /* 2 opt */ - OPCODE_CAL, /* 2 2 */ - OPCODE_CMP, /* X */ + OPCODE_CAL, /* 2 2 X */ + OPCODE_CMP, /* X X */ OPCODE_CONT, /* opt */ OPCODE_COS, /* X 2 X X */ OPCODE_DDX, /* X X */ OPCODE_DDY, /* X X */ - OPCODE_DP2, /* 2 */ + OPCODE_DP2, /* 2 X */ OPCODE_DP2A, /* 2 */ OPCODE_DP3, /* X X X X X */ OPCODE_DP4, /* X X X X X */ @@ -185,7 +185,7 @@ typedef enum prog_opcode { OPCODE_LG2, /* X X 2 X X */ OPCODE_LIT, /* X X X X */ OPCODE_LOG, /* X X X */ - OPCODE_LRP, /* X X */ + OPCODE_LRP, /* X X X */ OPCODE_MAD, /* X X X X X */ OPCODE_MAX, /* X X X X X */ OPCODE_MIN, /* X X X X X */ @@ -196,8 +196,8 @@ typedef enum prog_opcode { OPCODE_NOISE3, /* X */ OPCODE_NOISE4, /* X */ OPCODE_NOT, /* */ - OPCODE_NRM3, /* */ - OPCODE_NRM4, /* */ + OPCODE_NRM3, /* X */ + OPCODE_NRM4, /* X */ OPCODE_OR, /* */ OPCODE_PK2H, /* X */ OPCODE_PK2US, /* X */ @@ -209,7 +209,7 @@ typedef enum prog_opcode { OPCODE_PUSHA, /* 3 */ OPCODE_RCC, /* 1.1 */ OPCODE_RCP, /* X X X X X */ - OPCODE_RET, /* 2 2 */ + OPCODE_RET, /* 2 2 X */ OPCODE_RFL, /* X X */ OPCODE_RSQ, /* X X X X X */ OPCODE_SCS, /* X */ diff --git a/src/mesa/program/prog_noise.h b/src/mesa/program/prog_noise.h index c4779479f9b..dd7986efcdb 100644 --- a/src/mesa/program/prog_noise.h +++ b/src/mesa/program/prog_noise.h @@ -25,6 +25,8 @@ #ifndef PROG_NOISE #define PROG_NOISE +#include "main/glheader.h" + extern GLfloat _mesa_noise1(GLfloat); extern GLfloat _mesa_noise2(GLfloat, GLfloat); extern GLfloat _mesa_noise3(GLfloat, GLfloat, GLfloat); diff --git a/src/mesa/program/prog_optimize.c b/src/mesa/program/prog_optimize.c index 2941a17da3f..c78187c983d 100644 --- a/src/mesa/program/prog_optimize.c +++ b/src/mesa/program/prog_optimize.c @@ -38,40 +38,117 @@ static GLboolean dbg = GL_FALSE; -/* Returns the mask of channels read from the given srcreg in this instruction. +#define NO_MASK 0xf + +/** + * Returns the mask of channels (bitmask of WRITEMASK_X,Y,Z,W) which + * are read from the given src in this instruction, We also provide + * one optional masks which may mask other components in the dst + * register */ static GLuint -get_src_arg_mask(const struct prog_instruction *inst, int arg) +get_src_arg_mask(const struct prog_instruction *inst, + GLuint arg, GLuint dst_mask) { - int writemask = inst->DstReg.WriteMask; + GLuint read_mask, channel_mask; + GLuint comp; - if (inst->CondUpdate) - writemask = WRITEMASK_XYZW; + ASSERT(arg < _mesa_num_inst_src_regs(inst->Opcode)); - switch (inst->Opcode) { - case OPCODE_MOV: - case OPCODE_ABS: - case OPCODE_ADD: - case OPCODE_MUL: - case OPCODE_SUB: - return writemask; - case OPCODE_RCP: - case OPCODE_SIN: - case OPCODE_COS: - case OPCODE_RSQ: - case OPCODE_POW: - case OPCODE_EX2: - return WRITEMASK_X; - case OPCODE_DP2: - return WRITEMASK_XY; - case OPCODE_DP3: - case OPCODE_XPD: - return WRITEMASK_XYZ; - default: - return WRITEMASK_XYZW; + /* Form the dst register, find the written channels */ + if (inst->CondUpdate) { + channel_mask = WRITEMASK_XYZW; + } + else { + switch (inst->Opcode) { + case OPCODE_MOV: + case OPCODE_MIN: + case OPCODE_MAX: + case OPCODE_ABS: + case OPCODE_ADD: + case OPCODE_MAD: + case OPCODE_MUL: + case OPCODE_SUB: + channel_mask = inst->DstReg.WriteMask & dst_mask; + break; + case OPCODE_RCP: + case OPCODE_SIN: + case OPCODE_COS: + case OPCODE_RSQ: + case OPCODE_POW: + case OPCODE_EX2: + case OPCODE_LOG: + channel_mask = WRITEMASK_X; + break; + case OPCODE_DP2: + channel_mask = WRITEMASK_XY; + break; + case OPCODE_DP3: + case OPCODE_XPD: + channel_mask = WRITEMASK_XYZ; + break; + default: + channel_mask = WRITEMASK_XYZW; + break; + } } + + /* Now, given the src swizzle and the written channels, find which + * components are actually read + */ + read_mask = 0x0; + for (comp = 0; comp < 4; ++comp) { + const GLuint coord = GET_SWZ(inst->SrcReg[arg].Swizzle, comp); + ASSERT(coord < 4); + if (channel_mask & (1 << comp) && coord <= SWIZZLE_W) + read_mask |= 1 << coord; + } + + return read_mask; +} + + +/** + * For a MOV instruction, compute a write mask when src register also has + * a mask + */ +static GLuint +get_dst_mask_for_mov(const struct prog_instruction *mov, GLuint src_mask) +{ + const GLuint mask = mov->DstReg.WriteMask; + GLuint comp; + GLuint updated_mask = 0x0; + + ASSERT(mov->Opcode == OPCODE_MOV); + + for (comp = 0; comp < 4; ++comp) { + GLuint src_comp; + if ((mask & (1 << comp)) == 0) + continue; + src_comp = GET_SWZ(mov->SrcReg[0].Swizzle, comp); + if ((src_mask & (1 << src_comp)) == 0) + continue; + updated_mask |= 1 << comp; + } + + return updated_mask; +} + + +/** + * Ensure that the swizzle is regular. That is, all of the swizzle + * terms are SWIZZLE_X,Y,Z,W and not SWIZZLE_ZERO or SWIZZLE_ONE. + */ +static GLboolean +is_swizzle_regular(GLuint swz) +{ + return GET_SWZ(swz,0) <= SWIZZLE_W && + GET_SWZ(swz,1) <= SWIZZLE_W && + GET_SWZ(swz,2) <= SWIZZLE_W && + GET_SWZ(swz,3) <= SWIZZLE_W; } + /** * In 'prog' remove instruction[i] if removeFlags[i] == TRUE. * \return number of instructions removed @@ -148,82 +225,13 @@ replace_regs(struct gl_program *prog, gl_register_file file, const GLint map[]) /** - * Consolidate temporary registers to use low numbers. For example, if the - * shader only uses temps 4, 5, 8, replace them with 0, 1, 2. - */ -static void -_mesa_consolidate_registers(struct gl_program *prog) -{ - GLboolean tempUsed[MAX_PROGRAM_TEMPS]; - GLint tempMap[MAX_PROGRAM_TEMPS]; - GLuint tempMax = 0, i; - - if (dbg) { - printf("Optimize: Begin register consolidation\n"); - } - - memset(tempUsed, 0, sizeof(tempUsed)); - - for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { - tempMap[i] = -1; - } - - /* set tempUsed[i] if temporary [i] is referenced */ - for (i = 0; i < prog->NumInstructions; i++) { - const struct prog_instruction *inst = prog->Instructions + i; - const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); - GLuint j; - for (j = 0; j < numSrc; j++) { - if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) { - const GLuint index = inst->SrcReg[j].Index; - ASSERT(index < MAX_PROGRAM_TEMPS); - tempUsed[index] = GL_TRUE; - tempMax = MAX2(tempMax, index); - break; - } - } - if (inst->DstReg.File == PROGRAM_TEMPORARY) { - const GLuint index = inst->DstReg.Index; - ASSERT(index < MAX_PROGRAM_TEMPS); - tempUsed[index] = GL_TRUE; - tempMax = MAX2(tempMax, index); - } - } - - /* allocate a new index for each temp that's used */ - { - GLuint freeTemp = 0; - for (i = 0; i <= tempMax; i++) { - if (tempUsed[i]) { - tempMap[i] = freeTemp++; - /*printf("replace %u with %u\n", i, tempMap[i]);*/ - } - } - if (freeTemp == tempMax + 1) { - /* no consolidation possible */ - return; - } - if (dbg) { - printf("Replace regs 0..%u with 0..%u\n", tempMax, freeTemp-1); - } - } - - replace_regs(prog, PROGRAM_TEMPORARY, tempMap); - - if (dbg) { - printf("Optimize: End register consolidation\n"); - } -} - - -/** * Remove dead instructions from the given program. * This is very primitive for now. Basically look for temp registers * that are written to but never read. Remove any instructions that * write to such registers. Be careful with condition code setters. */ -static void -_mesa_remove_dead_code(struct gl_program *prog) +static GLboolean +_mesa_remove_dead_code_global(struct gl_program *prog) { GLboolean tempRead[MAX_PROGRAM_TEMPS][4]; GLboolean *removeInst; /* per-instruction removal flag */ @@ -251,7 +259,7 @@ _mesa_remove_dead_code(struct gl_program *prog) const GLuint index = inst->SrcReg[j].Index; GLuint read_mask; ASSERT(index < MAX_PROGRAM_TEMPS); - read_mask = get_src_arg_mask(inst, j); + read_mask = get_src_arg_mask(inst, j, NO_MASK); if (inst->SrcReg[j].RelAddr) { if (dbg) @@ -260,25 +268,12 @@ _mesa_remove_dead_code(struct gl_program *prog) } for (comp = 0; comp < 4; comp++) { - GLuint swz = (inst->SrcReg[j].Swizzle >> (3 * comp)) & 0x7; - - if ((read_mask & (1 << comp)) == 0) + const GLuint swz = GET_SWZ(inst->SrcReg[j].Swizzle, comp); + ASSERT(swz < 4); + if ((read_mask & (1 << swz)) == 0) continue; - - switch (swz) { - case SWIZZLE_X: - tempRead[index][0] = GL_TRUE; - break; - case SWIZZLE_Y: - tempRead[index][1] = GL_TRUE; - break; - case SWIZZLE_Z: - tempRead[index][2] = GL_TRUE; - break; - case SWIZZLE_W: - tempRead[index][3] = GL_TRUE; - break; - } + if (swz <= SWIZZLE_W) + tempRead[index][swz] = GL_TRUE; } } } @@ -348,10 +343,11 @@ _mesa_remove_dead_code(struct gl_program *prog) done: free(removeInst); + return rem != 0; } -enum temp_use +enum inst_use { READ, WRITE, @@ -359,13 +355,19 @@ enum temp_use END }; + /** - * Scan forward in program from 'start' for the next occurance of TEMP[index]. + * Scan forward in program from 'start' for the next occurances of TEMP[index]. + * We look if an instruction reads the component given by the masks and if they + * are overwritten. * Return READ, WRITE, FLOW or END to indicate the next usage or an indicator * that we can't look further. */ -static enum temp_use -find_next_temp_use(const struct gl_program *prog, GLuint start, GLuint index) +static enum inst_use +find_next_use(const struct gl_program *prog, + GLuint start, + GLuint index, + GLuint mask) { GLuint i; @@ -373,30 +375,50 @@ find_next_temp_use(const struct gl_program *prog, GLuint start, GLuint index) const struct prog_instruction *inst = prog->Instructions + i; switch (inst->Opcode) { case OPCODE_BGNLOOP: - case OPCODE_ENDLOOP: case OPCODE_BGNSUB: + case OPCODE_BRA: + case OPCODE_CAL: + case OPCODE_CONT: + case OPCODE_IF: + case OPCODE_ELSE: + case OPCODE_ENDIF: + case OPCODE_ENDLOOP: case OPCODE_ENDSUB: + case OPCODE_RET: return FLOW; + case OPCODE_END: + return END; default: { const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); GLuint j; for (j = 0; j < numSrc; j++) { - if (inst->SrcReg[j].File == PROGRAM_TEMPORARY && - inst->SrcReg[j].Index == index) + if (inst->SrcReg[j].RelAddr || + (inst->SrcReg[j].File == PROGRAM_TEMPORARY && + inst->SrcReg[j].Index == index && + (get_src_arg_mask(inst,j,NO_MASK) & mask))) return READ; } - if (inst->DstReg.File == PROGRAM_TEMPORARY && - inst->DstReg.Index == index) - return WRITE; + if (_mesa_num_inst_dst_regs(inst->Opcode) == 1 && + inst->DstReg.File == PROGRAM_TEMPORARY && + inst->DstReg.Index == index) { + mask &= ~inst->DstReg.WriteMask; + if (mask == 0) + return WRITE; + } } } } - return END; } -static GLboolean _mesa_is_flow_control_opcode(enum prog_opcode opcode) + +/** + * Is the given instruction opcode a flow-control opcode? + * XXX maybe move this into prog_instruction.[ch] + */ +static GLboolean +_mesa_is_flow_control_opcode(enum prog_opcode opcode) { switch (opcode) { case OPCODE_BGNLOOP: @@ -417,6 +439,37 @@ static GLboolean _mesa_is_flow_control_opcode(enum prog_opcode opcode) } } + +/** + * Test if the given instruction is a simple MOV (no conditional updating, + * not relative addressing, no negation/abs, etc). + */ +static GLboolean +can_downward_mov_be_modifed(const struct prog_instruction *mov) +{ + return + mov->Opcode == OPCODE_MOV && + mov->CondUpdate == GL_FALSE && + mov->SrcReg[0].RelAddr == 0 && + mov->SrcReg[0].Negate == 0 && + mov->SrcReg[0].Abs == 0 && + mov->SrcReg[0].HasIndex2 == 0 && + mov->SrcReg[0].RelAddr2 == 0 && + mov->DstReg.RelAddr == 0 && + mov->DstReg.CondMask == COND_TR && + mov->SaturateMode == SATURATE_OFF; +} + + +static GLboolean +can_upward_mov_be_modifed(const struct prog_instruction *mov) +{ + return + can_downward_mov_be_modifed(mov) && + mov->DstReg.File == PROGRAM_TEMPORARY; +} + + /** * Try to remove use of extraneous MOV instructions, to free them up for dead * code removal. @@ -444,14 +497,15 @@ _mesa_remove_extra_move_use(struct gl_program *prog) for (i = 0; i + 1 < prog->NumInstructions; i++) { const struct prog_instruction *mov = prog->Instructions + i; + GLuint dst_mask, src_mask; + if (can_upward_mov_be_modifed(mov) == GL_FALSE) + continue; - if (mov->Opcode != OPCODE_MOV || - mov->DstReg.File != PROGRAM_TEMPORARY || - mov->DstReg.RelAddr || - mov->DstReg.CondMask != COND_TR || - mov->SaturateMode != SATURATE_OFF || - mov->SrcReg[0].RelAddr) - continue; + /* Scanning the code, we maintain the components which are still active in + * these two masks + */ + dst_mask = mov->DstReg.WriteMask; + src_mask = get_src_arg_mask(mov, 0, NO_MASK); /* Walk through remaining instructions until the or src reg gets * rewritten or we get into some flow-control, eliminating the use of @@ -459,61 +513,60 @@ _mesa_remove_extra_move_use(struct gl_program *prog) */ for (j = i + 1; j < prog->NumInstructions; j++) { struct prog_instruction *inst2 = prog->Instructions + j; - GLuint arg; + GLuint arg; if (_mesa_is_flow_control_opcode(inst2->Opcode)) break; /* First rewrite this instruction's args if appropriate. */ for (arg = 0; arg < _mesa_num_inst_src_regs(inst2->Opcode); arg++) { - int comp; - int read_mask = get_src_arg_mask(inst2, arg); + GLuint comp, read_mask; if (inst2->SrcReg[arg].File != mov->DstReg.File || inst2->SrcReg[arg].Index != mov->DstReg.Index || inst2->SrcReg[arg].RelAddr || inst2->SrcReg[arg].Abs) continue; + read_mask = get_src_arg_mask(inst2, arg, NO_MASK); - /* Check that all the sources for this arg of inst2 come from inst1 - * or constants. - */ - for (comp = 0; comp < 4; comp++) { - int src_swz = GET_SWZ(inst2->SrcReg[arg].Swizzle, comp); - - /* If the MOV didn't write that channel, can't use it. */ - if ((read_mask & (1 << comp)) && - src_swz <= SWIZZLE_W && - (mov->DstReg.WriteMask & (1 << src_swz)) == 0) - break; - } - if (comp != 4) - continue; - - /* Adjust the swizzles of inst2 to point at MOV's source */ - for (comp = 0; comp < 4; comp++) { - int inst2_swz = GET_SWZ(inst2->SrcReg[arg].Swizzle, comp); - - if (inst2_swz <= SWIZZLE_W) { - GLuint s = GET_SWZ(mov->SrcReg[0].Swizzle, inst2_swz); - inst2->SrcReg[arg].Swizzle &= ~(7 << (3 * comp)); - inst2->SrcReg[arg].Swizzle |= s << (3 * comp); - inst2->SrcReg[arg].Negate ^= (((mov->SrcReg[0].Negate >> - inst2_swz) & 0x1) << comp); - } - } - inst2->SrcReg[arg].File = mov->SrcReg[0].File; - inst2->SrcReg[arg].Index = mov->SrcReg[0].Index; + /* Adjust the swizzles of inst2 to point at MOV's source if ALL the + * components read still come from the mov instructions + */ + if (is_swizzle_regular(inst2->SrcReg[arg].Swizzle) && + (read_mask & dst_mask) == read_mask) { + for (comp = 0; comp < 4; comp++) { + const GLuint inst2_swz = + GET_SWZ(inst2->SrcReg[arg].Swizzle, comp); + const GLuint s = GET_SWZ(mov->SrcReg[0].Swizzle, inst2_swz); + inst2->SrcReg[arg].Swizzle &= ~(7 << (3 * comp)); + inst2->SrcReg[arg].Swizzle |= s << (3 * comp); + inst2->SrcReg[arg].Negate ^= (((mov->SrcReg[0].Negate >> + inst2_swz) & 0x1) << comp); + } + inst2->SrcReg[arg].File = mov->SrcReg[0].File; + inst2->SrcReg[arg].Index = mov->SrcReg[0].Index; + } } - /* If this instruction overwrote part of the move, our time is up. */ - if ((inst2->DstReg.File == mov->DstReg.File && - (inst2->DstReg.RelAddr || - inst2->DstReg.Index == mov->DstReg.Index)) || - (inst2->DstReg.File == mov->SrcReg[0].File && - (inst2->DstReg.RelAddr || - inst2->DstReg.Index == mov->SrcReg[0].Index))) - break; + /* The source of MOV is written. This potentially deactivates some + * components from the src and dst of the MOV instruction + */ + if (inst2->DstReg.File == mov->DstReg.File && + (inst2->DstReg.RelAddr || + inst2->DstReg.Index == mov->DstReg.Index)) { + dst_mask &= ~inst2->DstReg.WriteMask; + src_mask = get_src_arg_mask(mov, 0, dst_mask); + } + + /* Idem when the destination of mov is written */ + if (inst2->DstReg.File == mov->SrcReg[0].File && + (inst2->DstReg.RelAddr || + inst2->DstReg.Index == mov->SrcReg[0].Index)) { + src_mask &= ~inst2->DstReg.WriteMask; + dst_mask &= get_dst_mask_for_mov(mov, src_mask); + } + if (dst_mask == 0) + break; } } @@ -523,14 +576,151 @@ _mesa_remove_extra_move_use(struct gl_program *prog) } } + +/** + * Complements dead_code_global. Try to remove code in block of code by + * carefully monitoring the swizzles. Both functions should be merged into one + * with a proper control flow graph + */ +static GLboolean +_mesa_remove_dead_code_local(struct gl_program *prog) +{ + GLboolean *removeInst; + GLuint i, arg, rem = 0; + + removeInst = (GLboolean *) + calloc(1, prog->NumInstructions * sizeof(GLboolean)); + + for (i = 0; i < prog->NumInstructions; i++) { + const struct prog_instruction *inst = prog->Instructions + i; + const GLuint index = inst->DstReg.Index; + const GLuint mask = inst->DstReg.WriteMask; + enum inst_use use; + + /* We must deactivate the pass as soon as some indirection is used */ + if (inst->DstReg.RelAddr) + goto done; + for (arg = 0; arg < _mesa_num_inst_src_regs(inst->Opcode); arg++) + if (inst->SrcReg[arg].RelAddr) + goto done; + + if (_mesa_is_flow_control_opcode(inst->Opcode) || + _mesa_num_inst_dst_regs(inst->Opcode) == 0 || + inst->DstReg.File != PROGRAM_TEMPORARY || + inst->DstReg.RelAddr) + continue; + + use = find_next_use(prog, i+1, index, mask); + if (use == WRITE || use == END) + removeInst[i] = GL_TRUE; + } + + rem = remove_instructions(prog, removeInst); + +done: + free(removeInst); + return rem != 0; +} + + +/** + * Try to inject the destination of mov as the destination of inst and recompute + * the swizzles operators for the sources of inst if required. Return GL_TRUE + * of the substitution was possible, GL_FALSE otherwise + */ +static GLboolean +_mesa_merge_mov_into_inst(struct prog_instruction *inst, + const struct prog_instruction *mov) +{ + /* Indirection table which associates destination and source components for + * the mov instruction + */ + const GLuint mask = get_src_arg_mask(mov, 0, NO_MASK); + + /* Some components are not written by inst. We cannot remove the mov */ + if (mask != (inst->DstReg.WriteMask & mask)) + return GL_FALSE; + + /* Depending on the instruction, we may need to recompute the swizzles. + * Also, some other instructions (like TEX) are not linear. We will only + * consider completely active sources and destinations + */ + switch (inst->Opcode) { + + /* Carstesian instructions: we compute the swizzle */ + case OPCODE_MOV: + case OPCODE_MIN: + case OPCODE_MAX: + case OPCODE_ABS: + case OPCODE_ADD: + case OPCODE_MAD: + case OPCODE_MUL: + case OPCODE_SUB: + { + GLuint dst_to_src_comp[4] = {0,0,0,0}; + GLuint dst_comp, arg; + for (dst_comp = 0; dst_comp < 4; ++dst_comp) { + if (mov->DstReg.WriteMask & (1 << dst_comp)) { + const GLuint src_comp = GET_SWZ(mov->SrcReg[0].Swizzle, dst_comp); + ASSERT(src_comp < 4); + dst_to_src_comp[dst_comp] = src_comp; + } + } + + /* Patch each source of the instruction */ + for (arg = 0; arg < _mesa_num_inst_src_regs(inst->Opcode); arg++) { + const GLuint arg_swz = inst->SrcReg[arg].Swizzle; + inst->SrcReg[arg].Swizzle = 0; + + /* Reset each active component of the swizzle */ + for (dst_comp = 0; dst_comp < 4; ++dst_comp) { + GLuint src_comp, arg_comp; + if ((mov->DstReg.WriteMask & (1 << dst_comp)) == 0) + continue; + src_comp = dst_to_src_comp[dst_comp]; + ASSERT(src_comp < 4); + arg_comp = GET_SWZ(arg_swz, src_comp); + ASSERT(arg_comp < 4); + inst->SrcReg[arg].Swizzle |= arg_comp << (3*dst_comp); + } + } + inst->DstReg = mov->DstReg; + return GL_TRUE; + } + + /* Dot products and scalar instructions: we only change the destination */ + case OPCODE_RCP: + case OPCODE_SIN: + case OPCODE_COS: + case OPCODE_RSQ: + case OPCODE_POW: + case OPCODE_EX2: + case OPCODE_LOG: + case OPCODE_DP2: + case OPCODE_DP3: + case OPCODE_DP4: + inst->DstReg = mov->DstReg; + return GL_TRUE; + + /* All other instructions require fully active components with no swizzle */ + default: + if (mov->SrcReg[0].Swizzle != SWIZZLE_XYZW || + inst->DstReg.WriteMask != WRITEMASK_XYZW) + return GL_FALSE; + inst->DstReg = mov->DstReg; + return GL_TRUE; + } +} + + /** * Try to remove extraneous MOV instructions from the given program. */ -static void +static GLboolean _mesa_remove_extra_moves(struct gl_program *prog) { GLboolean *removeInst; /* per-instruction removal flag */ - GLuint i, rem, loopNesting = 0, subroutineNesting = 0; + GLuint i, rem = 0, nesting = 0; if (dbg) { printf("Optimize: Begin remove extra moves\n"); @@ -549,29 +739,24 @@ _mesa_remove_extra_moves(struct gl_program *prog) */ for (i = 0; i < prog->NumInstructions; i++) { - const struct prog_instruction *inst = prog->Instructions + i; + const struct prog_instruction *mov = prog->Instructions + i; - switch (inst->Opcode) { + switch (mov->Opcode) { case OPCODE_BGNLOOP: - loopNesting++; - break; - case OPCODE_ENDLOOP: - loopNesting--; - break; case OPCODE_BGNSUB: - subroutineNesting++; + case OPCODE_IF: + nesting++; break; + case OPCODE_ENDLOOP: case OPCODE_ENDSUB: - subroutineNesting--; + case OPCODE_ENDIF: + nesting--; break; case OPCODE_MOV: - if (i > 0 && - loopNesting == 0 && - subroutineNesting == 0 && - inst->SrcReg[0].File == PROGRAM_TEMPORARY && - inst->SrcReg[0].Swizzle == SWIZZLE_XYZW) { + if (i > 0 && can_downward_mov_be_modifed(mov) && nesting == 0) { + /* see if this MOV can be removed */ - const GLuint tempIndex = inst->SrcReg[0].Index; + const GLuint id = mov->SrcReg[0].Index; struct prog_instruction *prevInst; GLuint prevI; @@ -582,11 +767,13 @@ _mesa_remove_extra_moves(struct gl_program *prog) prevInst = prog->Instructions + prevI; if (prevInst->DstReg.File == PROGRAM_TEMPORARY && - prevInst->DstReg.Index == tempIndex && - prevInst->DstReg.WriteMask == WRITEMASK_XYZW) { + prevInst->DstReg.Index == id && + prevInst->DstReg.RelAddr == 0 && + prevInst->DstReg.CondSrc == 0 && + prevInst->DstReg.CondMask == COND_TR) { - enum temp_use next_use = - find_next_temp_use(prog, i + 1, tempIndex); + const GLuint dst_mask = prevInst->DstReg.WriteMask; + enum inst_use next_use = find_next_use(prog, i+1, id, dst_mask); if (next_use == WRITE || next_use == END) { /* OK, we can safely remove this MOV instruction. @@ -596,18 +783,13 @@ _mesa_remove_extra_moves(struct gl_program *prog) * Into: * prevI: FOO z, x, y; */ - - /* patch up prev inst */ - prevInst->DstReg.File = inst->DstReg.File; - prevInst->DstReg.Index = inst->DstReg.Index; - - /* flag this instruction for removal */ - removeInst[i] = GL_TRUE; - - if (dbg) { - printf("Remove MOV at %u\n", i); - printf("new prev inst %u: ", prevI); - _mesa_print_instruction(prevInst); + if (_mesa_merge_mov_into_inst(prevInst, mov)) { + removeInst[i] = GL_TRUE; + if (dbg) { + printf("Remove MOV at %u\n", i); + printf("new prev inst %u: ", prevI); + _mesa_print_instruction(prevInst); + } } } } @@ -627,6 +809,8 @@ _mesa_remove_extra_moves(struct gl_program *prog) printf("Optimize: End remove extra moves. %u instructions removed\n", rem); /*_mesa_print_program(prog);*/ } + + return rem != 0; } @@ -713,6 +897,7 @@ compare_start(const void *a, const void *b) return 0; } + /** sort the interval list according to interval starts */ static void sort_interval_list_by_start(struct interval_list *list) @@ -1013,6 +1198,17 @@ _mesa_reallocate_registers(struct gl_program *prog) } +#if 0 +static void +print_it(GLcontext *ctx, struct gl_program *program, const char *txt) { + fprintf(stderr, "%s (%u inst):\n", txt, program->NumInstructions); + _mesa_print_program(program); + _mesa_print_program_parameters(ctx, program); + fprintf(stderr, "\n\n"); +} +#endif + + /** * Apply optimizations to the given program to eliminate unnecessary * instructions, temp regs, etc. @@ -1020,16 +1216,19 @@ _mesa_reallocate_registers(struct gl_program *prog) void _mesa_optimize_program(GLcontext *ctx, struct gl_program *program) { - _mesa_remove_extra_move_use(program); - - if (1) - _mesa_remove_dead_code(program); - - if (0) /* not tested much yet */ - _mesa_remove_extra_moves(program); - - if (0) - _mesa_consolidate_registers(program); - else + GLboolean any_change; + + /* Stop when no modifications were output */ + do { + any_change = GL_FALSE; + _mesa_remove_extra_move_use(program); + if (_mesa_remove_dead_code_global(program)) + any_change = GL_TRUE; + if (_mesa_remove_extra_moves(program)) + any_change = GL_TRUE; + if (_mesa_remove_dead_code_local(program)) + any_change = GL_TRUE; _mesa_reallocate_registers(program); + } while (any_change); } + diff --git a/src/mesa/program/prog_optimize.h b/src/mesa/program/prog_optimize.h index 43894a27237..06cd9cb2c20 100644 --- a/src/mesa/program/prog_optimize.h +++ b/src/mesa/program/prog_optimize.h @@ -27,6 +27,7 @@ #include "main/config.h" +#include "main/mtypes.h" struct gl_program; diff --git a/src/mesa/program/prog_parameter_layout.c b/src/mesa/program/prog_parameter_layout.c index a8885738321..d7dc97edbfb 100644 --- a/src/mesa/program/prog_parameter_layout.c +++ b/src/mesa/program/prog_parameter_layout.c @@ -28,6 +28,7 @@ * \author Ian Romanick <[email protected]> */ +#include "main/compiler.h" #include "main/mtypes.h" #include "prog_parameter.h" #include "prog_parameter_layout.h" diff --git a/src/mesa/program/prog_print.c b/src/mesa/program/prog_print.c index 6ab199aa02b..6056c459e4c 100644 --- a/src/mesa/program/prog_print.c +++ b/src/mesa/program/prog_print.c @@ -924,6 +924,8 @@ _mesa_fprint_program_parameters(FILE *f, fprintf(f, "NumParameters=%d\n", prog->NumParameters); fprintf(f, "NumAttributes=%d\n", prog->NumAttributes); fprintf(f, "NumAddressRegs=%d\n", prog->NumAddressRegs); + fprintf(f, "IndirectRegisterFiles: 0x%x (0b%s)\n", + prog->IndirectRegisterFiles, binary(prog->IndirectRegisterFiles)); fprintf(f, "SamplersUsed: 0x%x (0b%s)\n", prog->SamplersUsed, binary(prog->SamplersUsed)); fprintf(f, "Samplers=[ "); diff --git a/src/mesa/program/prog_print.h b/src/mesa/program/prog_print.h index 9ab74560169..4667373f379 100644 --- a/src/mesa/program/prog_print.h +++ b/src/mesa/program/prog_print.h @@ -26,6 +26,16 @@ #ifndef PROG_PRINT_H #define PROG_PRINT_H +#include <stdio.h> + +#include "main/glheader.h" +#include "main/mtypes.h" + +struct gl_program; +struct gl_program_parameter_list; +struct gl_shader; +struct prog_instruction; + /** * The output style to use when printing programs. diff --git a/src/mesa/program/prog_uniform.h b/src/mesa/program/prog_uniform.h index a671d30bfe8..7988d534a7d 100644 --- a/src/mesa/program/prog_uniform.h +++ b/src/mesa/program/prog_uniform.h @@ -31,8 +31,7 @@ #ifndef PROG_UNIFORM_H #define PROG_UNIFORM_H -#include "main/mtypes.h" -#include "prog_statevars.h" +#include "main/glheader.h" /** diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c index cf46095ce84..3b6d6827446 100644 --- a/src/mesa/program/program.c +++ b/src/mesa/program/program.c @@ -55,13 +55,21 @@ _mesa_init_program(GLcontext *ctx) /* * If this assertion fails, we need to increase the field - * size for register indexes. + * size for register indexes (see INST_INDEX_BITS). */ ASSERT(ctx->Const.VertexProgram.MaxUniformComponents / 4 <= (1 << INST_INDEX_BITS)); ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents / 4 <= (1 << INST_INDEX_BITS)); + ASSERT(ctx->Const.VertexProgram.MaxTemps <= (1 << INST_INDEX_BITS)); + ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= (1 << INST_INDEX_BITS)); + ASSERT(ctx->Const.FragmentProgram.MaxTemps <= (1 << INST_INDEX_BITS)); + ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= (1 << INST_INDEX_BITS)); + + ASSERT(ctx->Const.VertexProgram.MaxUniformComponents <= 4 * MAX_UNIFORMS); + ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents <= 4 * MAX_UNIFORMS); + /* If this fails, increase prog_instruction::TexSrcUnit size */ ASSERT(MAX_TEXTURE_UNITS < (1 << 5)); @@ -512,6 +520,7 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) if (prog->Attributes) clone->Attributes = _mesa_clone_parameter_list(prog->Attributes); memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams)); + clone->IndirectRegisterFiles = prog->IndirectRegisterFiles; clone->NumInstructions = prog->NumInstructions; clone->NumTemporaries = prog->NumTemporaries; clone->NumParameters = prog->NumParameters; diff --git a/src/mesa/program/program_parse.tab.c b/src/mesa/program/program_parse.tab.c index 6421d1f58aa..31a609600b7 100644 --- a/src/mesa/program/program_parse.tab.c +++ b/src/mesa/program/program_parse.tab.c @@ -798,29 +798,29 @@ static const yytype_uint16 yyrline[] = 415, 459, 464, 474, 518, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 538, 550, 558, 575, 582, 601, 612, 632, 657, 664, 697, 704, 719, - 774, 817, 826, 847, 857, 861, 890, 909, 909, 911, - 918, 930, 931, 932, 935, 949, 963, 983, 994, 1006, - 1008, 1009, 1010, 1011, 1014, 1014, 1014, 1014, 1015, 1018, - 1022, 1027, 1034, 1041, 1048, 1071, 1094, 1095, 1096, 1097, - 1098, 1099, 1102, 1121, 1125, 1131, 1135, 1139, 1143, 1152, - 1161, 1165, 1170, 1176, 1187, 1187, 1188, 1190, 1194, 1198, - 1202, 1208, 1208, 1210, 1228, 1254, 1257, 1268, 1274, 1280, - 1281, 1288, 1294, 1300, 1308, 1314, 1320, 1328, 1334, 1340, - 1348, 1349, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, - 1360, 1361, 1362, 1365, 1374, 1378, 1382, 1388, 1397, 1401, - 1405, 1414, 1418, 1424, 1430, 1437, 1442, 1450, 1460, 1462, - 1470, 1476, 1480, 1484, 1490, 1501, 1510, 1514, 1519, 1523, - 1527, 1531, 1537, 1544, 1548, 1554, 1562, 1573, 1580, 1584, - 1590, 1600, 1611, 1615, 1633, 1642, 1645, 1651, 1655, 1659, - 1665, 1676, 1681, 1686, 1691, 1696, 1701, 1709, 1712, 1717, - 1730, 1738, 1749, 1757, 1757, 1759, 1759, 1761, 1771, 1776, - 1783, 1793, 1802, 1807, 1814, 1824, 1834, 1846, 1846, 1847, - 1847, 1849, 1859, 1867, 1877, 1885, 1893, 1902, 1913, 1917, - 1923, 1924, 1925, 1928, 1928, 1931, 1966, 1970, 1970, 1973, - 1980, 1989, 2003, 2012, 2021, 2025, 2034, 2043, 2054, 2061, - 2066, 2075, 2087, 2090, 2099, 2110, 2111, 2112, 2115, 2116, - 2117, 2120, 2121, 2124, 2125, 2128, 2129, 2132, 2143, 2154, - 2165, 2191, 2192 + 774, 817, 826, 848, 858, 862, 891, 910, 910, 912, + 919, 931, 932, 933, 936, 950, 964, 984, 995, 1007, + 1009, 1010, 1011, 1012, 1015, 1015, 1015, 1015, 1016, 1019, + 1023, 1028, 1035, 1042, 1049, 1072, 1095, 1096, 1097, 1098, + 1099, 1100, 1103, 1122, 1126, 1132, 1136, 1140, 1144, 1153, + 1162, 1166, 1171, 1177, 1188, 1188, 1189, 1191, 1195, 1199, + 1203, 1209, 1209, 1211, 1229, 1255, 1258, 1269, 1275, 1281, + 1282, 1289, 1295, 1301, 1309, 1315, 1321, 1329, 1335, 1341, + 1349, 1350, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, + 1361, 1362, 1363, 1366, 1375, 1379, 1383, 1389, 1398, 1402, + 1406, 1415, 1419, 1425, 1431, 1438, 1443, 1451, 1461, 1463, + 1471, 1477, 1481, 1485, 1491, 1502, 1511, 1515, 1520, 1524, + 1528, 1532, 1538, 1545, 1549, 1555, 1563, 1574, 1581, 1585, + 1591, 1601, 1612, 1616, 1634, 1643, 1646, 1652, 1656, 1660, + 1666, 1677, 1682, 1687, 1692, 1697, 1702, 1710, 1713, 1718, + 1731, 1739, 1750, 1758, 1758, 1760, 1760, 1762, 1772, 1777, + 1784, 1794, 1803, 1808, 1815, 1825, 1835, 1847, 1847, 1848, + 1848, 1850, 1860, 1868, 1878, 1886, 1894, 1903, 1914, 1918, + 1924, 1925, 1926, 1929, 1929, 1932, 1967, 1971, 1971, 1974, + 1981, 1990, 2004, 2013, 2022, 2026, 2035, 2044, 2055, 2062, + 2067, 2076, 2088, 2091, 2100, 2111, 2112, 2113, 2116, 2117, + 2118, 2121, 2122, 2125, 2126, 2129, 2130, 2133, 2144, 2155, + 2166, 2192, 2193 }; #endif @@ -2844,6 +2844,7 @@ yyreduce: (yyval.src_reg).Base.File = (yyvsp[(1) - (4)].sym)->param_binding_type; if ((yyvsp[(3) - (4)].src_reg).Base.RelAddr) { + state->prog->IndirectRegisterFiles |= (1 << (yyval.src_reg).Base.File); (yyvsp[(1) - (4)].sym)->param_accessed_indirectly = 1; (yyval.src_reg).Base.RelAddr = 1; @@ -2858,7 +2859,7 @@ yyreduce: case 63: /* Line 1455 of yacc.c */ -#line 848 "program_parse.y" +#line 849 "program_parse.y" { gl_register_file file = ((yyvsp[(1) - (1)].temp_sym).name != NULL) ? (yyvsp[(1) - (1)].temp_sym).param_binding_type @@ -2871,7 +2872,7 @@ yyreduce: case 64: /* Line 1455 of yacc.c */ -#line 858 "program_parse.y" +#line 859 "program_parse.y" { set_dst_reg(& (yyval.dst_reg), PROGRAM_OUTPUT, (yyvsp[(1) - (1)].result)); ;} @@ -2880,7 +2881,7 @@ yyreduce: case 65: /* Line 1455 of yacc.c */ -#line 862 "program_parse.y" +#line 863 "program_parse.y" { struct asm_symbol *const s = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); @@ -2912,7 +2913,7 @@ yyreduce: case 66: /* Line 1455 of yacc.c */ -#line 891 "program_parse.y" +#line 892 "program_parse.y" { struct asm_symbol *const s = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); @@ -2934,7 +2935,7 @@ yyreduce: case 69: /* Line 1455 of yacc.c */ -#line 912 "program_parse.y" +#line 913 "program_parse.y" { init_src_reg(& (yyval.src_reg)); (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].integer); @@ -2944,7 +2945,7 @@ yyreduce: case 70: /* Line 1455 of yacc.c */ -#line 919 "program_parse.y" +#line 920 "program_parse.y" { /* FINISHME: Add support for multiple address registers. */ @@ -2959,30 +2960,30 @@ yyreduce: case 71: /* Line 1455 of yacc.c */ -#line 930 "program_parse.y" +#line 931 "program_parse.y" { (yyval.integer) = 0; ;} break; case 72: /* Line 1455 of yacc.c */ -#line 931 "program_parse.y" +#line 932 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;} break; case 73: /* Line 1455 of yacc.c */ -#line 932 "program_parse.y" +#line 933 "program_parse.y" { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;} break; case 74: /* Line 1455 of yacc.c */ -#line 936 "program_parse.y" +#line 937 "program_parse.y" { - if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 63)) { + if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 4095)) { char s[100]; _mesa_snprintf(s, sizeof(s), "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer)); @@ -2997,9 +2998,9 @@ yyreduce: case 75: /* Line 1455 of yacc.c */ -#line 950 "program_parse.y" +#line 951 "program_parse.y" { - if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 64)) { + if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 4096)) { char s[100]; _mesa_snprintf(s, sizeof(s), "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer)); @@ -3014,7 +3015,7 @@ yyreduce: case 76: /* Line 1455 of yacc.c */ -#line 964 "program_parse.y" +#line 965 "program_parse.y" { struct asm_symbol *const s = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); @@ -3037,7 +3038,7 @@ yyreduce: case 77: /* Line 1455 of yacc.c */ -#line 984 "program_parse.y" +#line 985 "program_parse.y" { if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) { yyerror(& (yylsp[(1) - (1)]), state, "invalid address component selector"); @@ -3051,7 +3052,7 @@ yyreduce: case 78: /* Line 1455 of yacc.c */ -#line 995 "program_parse.y" +#line 996 "program_parse.y" { if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) { yyerror(& (yylsp[(1) - (1)]), state, @@ -3066,21 +3067,21 @@ yyreduce: case 83: /* Line 1455 of yacc.c */ -#line 1011 "program_parse.y" +#line 1012 "program_parse.y" { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;} break; case 88: /* Line 1455 of yacc.c */ -#line 1015 "program_parse.y" +#line 1016 "program_parse.y" { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;} break; case 89: /* Line 1455 of yacc.c */ -#line 1019 "program_parse.y" +#line 1020 "program_parse.y" { (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg); ;} @@ -3089,7 +3090,7 @@ yyreduce: case 90: /* Line 1455 of yacc.c */ -#line 1023 "program_parse.y" +#line 1024 "program_parse.y" { (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg); ;} @@ -3098,7 +3099,7 @@ yyreduce: case 91: /* Line 1455 of yacc.c */ -#line 1027 "program_parse.y" +#line 1028 "program_parse.y" { (yyval.dst_reg).CondMask = COND_TR; (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP; @@ -3109,7 +3110,7 @@ yyreduce: case 92: /* Line 1455 of yacc.c */ -#line 1035 "program_parse.y" +#line 1036 "program_parse.y" { (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg); (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle; @@ -3119,7 +3120,7 @@ yyreduce: case 93: /* Line 1455 of yacc.c */ -#line 1042 "program_parse.y" +#line 1043 "program_parse.y" { (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg); (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle; @@ -3129,7 +3130,7 @@ yyreduce: case 94: /* Line 1455 of yacc.c */ -#line 1049 "program_parse.y" +#line 1050 "program_parse.y" { const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string)); if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) { @@ -3155,7 +3156,7 @@ yyreduce: case 95: /* Line 1455 of yacc.c */ -#line 1072 "program_parse.y" +#line 1073 "program_parse.y" { const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string)); if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) { @@ -3181,7 +3182,7 @@ yyreduce: case 102: /* Line 1455 of yacc.c */ -#line 1103 "program_parse.y" +#line 1104 "program_parse.y" { struct asm_symbol *const s = declare_variable(state, (yyvsp[(2) - (4)].string), at_attrib, & (yylsp[(2) - (4)])); @@ -3203,7 +3204,7 @@ yyreduce: case 103: /* Line 1455 of yacc.c */ -#line 1122 "program_parse.y" +#line 1123 "program_parse.y" { (yyval.attrib) = (yyvsp[(2) - (2)].attrib); ;} @@ -3212,7 +3213,7 @@ yyreduce: case 104: /* Line 1455 of yacc.c */ -#line 1126 "program_parse.y" +#line 1127 "program_parse.y" { (yyval.attrib) = (yyvsp[(2) - (2)].attrib); ;} @@ -3221,7 +3222,7 @@ yyreduce: case 105: /* Line 1455 of yacc.c */ -#line 1132 "program_parse.y" +#line 1133 "program_parse.y" { (yyval.attrib) = VERT_ATTRIB_POS; ;} @@ -3230,7 +3231,7 @@ yyreduce: case 106: /* Line 1455 of yacc.c */ -#line 1136 "program_parse.y" +#line 1137 "program_parse.y" { (yyval.attrib) = VERT_ATTRIB_WEIGHT; ;} @@ -3239,7 +3240,7 @@ yyreduce: case 107: /* Line 1455 of yacc.c */ -#line 1140 "program_parse.y" +#line 1141 "program_parse.y" { (yyval.attrib) = VERT_ATTRIB_NORMAL; ;} @@ -3248,7 +3249,7 @@ yyreduce: case 108: /* Line 1455 of yacc.c */ -#line 1144 "program_parse.y" +#line 1145 "program_parse.y" { if (!state->ctx->Extensions.EXT_secondary_color) { yyerror(& (yylsp[(2) - (2)]), state, "GL_EXT_secondary_color not supported"); @@ -3262,7 +3263,7 @@ yyreduce: case 109: /* Line 1455 of yacc.c */ -#line 1153 "program_parse.y" +#line 1154 "program_parse.y" { if (!state->ctx->Extensions.EXT_fog_coord) { yyerror(& (yylsp[(1) - (1)]), state, "GL_EXT_fog_coord not supported"); @@ -3276,7 +3277,7 @@ yyreduce: case 110: /* Line 1455 of yacc.c */ -#line 1162 "program_parse.y" +#line 1163 "program_parse.y" { (yyval.attrib) = VERT_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer); ;} @@ -3285,7 +3286,7 @@ yyreduce: case 111: /* Line 1455 of yacc.c */ -#line 1166 "program_parse.y" +#line 1167 "program_parse.y" { yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported"); YYERROR; @@ -3295,7 +3296,7 @@ yyreduce: case 112: /* Line 1455 of yacc.c */ -#line 1171 "program_parse.y" +#line 1172 "program_parse.y" { (yyval.attrib) = VERT_ATTRIB_GENERIC0 + (yyvsp[(3) - (4)].integer); ;} @@ -3304,7 +3305,7 @@ yyreduce: case 113: /* Line 1455 of yacc.c */ -#line 1177 "program_parse.y" +#line 1178 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxAttribs) { yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex attribute reference"); @@ -3318,7 +3319,7 @@ yyreduce: case 117: /* Line 1455 of yacc.c */ -#line 1191 "program_parse.y" +#line 1192 "program_parse.y" { (yyval.attrib) = FRAG_ATTRIB_WPOS; ;} @@ -3327,7 +3328,7 @@ yyreduce: case 118: /* Line 1455 of yacc.c */ -#line 1195 "program_parse.y" +#line 1196 "program_parse.y" { (yyval.attrib) = FRAG_ATTRIB_COL0 + (yyvsp[(2) - (2)].integer); ;} @@ -3336,7 +3337,7 @@ yyreduce: case 119: /* Line 1455 of yacc.c */ -#line 1199 "program_parse.y" +#line 1200 "program_parse.y" { (yyval.attrib) = FRAG_ATTRIB_FOGC; ;} @@ -3345,7 +3346,7 @@ yyreduce: case 120: /* Line 1455 of yacc.c */ -#line 1203 "program_parse.y" +#line 1204 "program_parse.y" { (yyval.attrib) = FRAG_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer); ;} @@ -3354,7 +3355,7 @@ yyreduce: case 123: /* Line 1455 of yacc.c */ -#line 1211 "program_parse.y" +#line 1212 "program_parse.y" { struct asm_symbol *const s = declare_variable(state, (yyvsp[(2) - (3)].string), at_param, & (yylsp[(2) - (3)])); @@ -3375,7 +3376,7 @@ yyreduce: case 124: /* Line 1455 of yacc.c */ -#line 1229 "program_parse.y" +#line 1230 "program_parse.y" { if (((yyvsp[(4) - (6)].integer) != 0) && ((unsigned) (yyvsp[(4) - (6)].integer) != (yyvsp[(6) - (6)].temp_sym).param_binding_length)) { free((yyvsp[(2) - (6)].string)); @@ -3403,7 +3404,7 @@ yyreduce: case 125: /* Line 1455 of yacc.c */ -#line 1254 "program_parse.y" +#line 1255 "program_parse.y" { (yyval.integer) = 0; ;} @@ -3412,7 +3413,7 @@ yyreduce: case 126: /* Line 1455 of yacc.c */ -#line 1258 "program_parse.y" +#line 1259 "program_parse.y" { if (((yyvsp[(1) - (1)].integer) < 1) || ((unsigned) (yyvsp[(1) - (1)].integer) > state->limits->MaxParameters)) { yyerror(& (yylsp[(1) - (1)]), state, "invalid parameter array size"); @@ -3426,7 +3427,7 @@ yyreduce: case 127: /* Line 1455 of yacc.c */ -#line 1269 "program_parse.y" +#line 1270 "program_parse.y" { (yyval.temp_sym) = (yyvsp[(2) - (2)].temp_sym); ;} @@ -3435,7 +3436,7 @@ yyreduce: case 128: /* Line 1455 of yacc.c */ -#line 1275 "program_parse.y" +#line 1276 "program_parse.y" { (yyval.temp_sym) = (yyvsp[(3) - (4)].temp_sym); ;} @@ -3444,7 +3445,7 @@ yyreduce: case 130: /* Line 1455 of yacc.c */ -#line 1282 "program_parse.y" +#line 1283 "program_parse.y" { (yyvsp[(1) - (3)].temp_sym).param_binding_length += (yyvsp[(3) - (3)].temp_sym).param_binding_length; (yyval.temp_sym) = (yyvsp[(1) - (3)].temp_sym); @@ -3454,7 +3455,7 @@ yyreduce: case 131: /* Line 1455 of yacc.c */ -#line 1289 "program_parse.y" +#line 1290 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3465,7 +3466,7 @@ yyreduce: case 132: /* Line 1455 of yacc.c */ -#line 1295 "program_parse.y" +#line 1296 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3476,7 +3477,7 @@ yyreduce: case 133: /* Line 1455 of yacc.c */ -#line 1301 "program_parse.y" +#line 1302 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3487,7 +3488,7 @@ yyreduce: case 134: /* Line 1455 of yacc.c */ -#line 1309 "program_parse.y" +#line 1310 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3498,7 +3499,7 @@ yyreduce: case 135: /* Line 1455 of yacc.c */ -#line 1315 "program_parse.y" +#line 1316 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3509,7 +3510,7 @@ yyreduce: case 136: /* Line 1455 of yacc.c */ -#line 1321 "program_parse.y" +#line 1322 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3520,7 +3521,7 @@ yyreduce: case 137: /* Line 1455 of yacc.c */ -#line 1329 "program_parse.y" +#line 1330 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3531,7 +3532,7 @@ yyreduce: case 138: /* Line 1455 of yacc.c */ -#line 1335 "program_parse.y" +#line 1336 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3542,7 +3543,7 @@ yyreduce: case 139: /* Line 1455 of yacc.c */ -#line 1341 "program_parse.y" +#line 1342 "program_parse.y" { memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); (yyval.temp_sym).param_binding_begin = ~0; @@ -3553,98 +3554,98 @@ yyreduce: case 140: /* Line 1455 of yacc.c */ -#line 1348 "program_parse.y" +#line 1349 "program_parse.y" { memcpy((yyval.state), (yyvsp[(1) - (1)].state), sizeof((yyval.state))); ;} break; case 141: /* Line 1455 of yacc.c */ -#line 1349 "program_parse.y" +#line 1350 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 142: /* Line 1455 of yacc.c */ -#line 1352 "program_parse.y" +#line 1353 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 143: /* Line 1455 of yacc.c */ -#line 1353 "program_parse.y" +#line 1354 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 144: /* Line 1455 of yacc.c */ -#line 1354 "program_parse.y" +#line 1355 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 145: /* Line 1455 of yacc.c */ -#line 1355 "program_parse.y" +#line 1356 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 146: /* Line 1455 of yacc.c */ -#line 1356 "program_parse.y" +#line 1357 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 147: /* Line 1455 of yacc.c */ -#line 1357 "program_parse.y" +#line 1358 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 148: /* Line 1455 of yacc.c */ -#line 1358 "program_parse.y" +#line 1359 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 149: /* Line 1455 of yacc.c */ -#line 1359 "program_parse.y" +#line 1360 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 150: /* Line 1455 of yacc.c */ -#line 1360 "program_parse.y" +#line 1361 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 151: /* Line 1455 of yacc.c */ -#line 1361 "program_parse.y" +#line 1362 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 152: /* Line 1455 of yacc.c */ -#line 1362 "program_parse.y" +#line 1363 "program_parse.y" { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} break; case 153: /* Line 1455 of yacc.c */ -#line 1366 "program_parse.y" +#line 1367 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_MATERIAL; @@ -3656,7 +3657,7 @@ yyreduce: case 154: /* Line 1455 of yacc.c */ -#line 1375 "program_parse.y" +#line 1376 "program_parse.y" { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} @@ -3665,7 +3666,7 @@ yyreduce: case 155: /* Line 1455 of yacc.c */ -#line 1379 "program_parse.y" +#line 1380 "program_parse.y" { (yyval.integer) = STATE_EMISSION; ;} @@ -3674,7 +3675,7 @@ yyreduce: case 156: /* Line 1455 of yacc.c */ -#line 1383 "program_parse.y" +#line 1384 "program_parse.y" { (yyval.integer) = STATE_SHININESS; ;} @@ -3683,7 +3684,7 @@ yyreduce: case 157: /* Line 1455 of yacc.c */ -#line 1389 "program_parse.y" +#line 1390 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_LIGHT; @@ -3695,7 +3696,7 @@ yyreduce: case 158: /* Line 1455 of yacc.c */ -#line 1398 "program_parse.y" +#line 1399 "program_parse.y" { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} @@ -3704,7 +3705,7 @@ yyreduce: case 159: /* Line 1455 of yacc.c */ -#line 1402 "program_parse.y" +#line 1403 "program_parse.y" { (yyval.integer) = STATE_POSITION; ;} @@ -3713,7 +3714,7 @@ yyreduce: case 160: /* Line 1455 of yacc.c */ -#line 1406 "program_parse.y" +#line 1407 "program_parse.y" { if (!state->ctx->Extensions.EXT_point_parameters) { yyerror(& (yylsp[(1) - (1)]), state, "GL_ARB_point_parameters not supported"); @@ -3727,7 +3728,7 @@ yyreduce: case 161: /* Line 1455 of yacc.c */ -#line 1415 "program_parse.y" +#line 1416 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;} @@ -3736,7 +3737,7 @@ yyreduce: case 162: /* Line 1455 of yacc.c */ -#line 1419 "program_parse.y" +#line 1420 "program_parse.y" { (yyval.integer) = STATE_HALF_VECTOR; ;} @@ -3745,7 +3746,7 @@ yyreduce: case 163: /* Line 1455 of yacc.c */ -#line 1425 "program_parse.y" +#line 1426 "program_parse.y" { (yyval.integer) = STATE_SPOT_DIRECTION; ;} @@ -3754,7 +3755,7 @@ yyreduce: case 164: /* Line 1455 of yacc.c */ -#line 1431 "program_parse.y" +#line 1432 "program_parse.y" { (yyval.state)[0] = (yyvsp[(2) - (2)].state)[0]; (yyval.state)[1] = (yyvsp[(2) - (2)].state)[1]; @@ -3764,7 +3765,7 @@ yyreduce: case 165: /* Line 1455 of yacc.c */ -#line 1438 "program_parse.y" +#line 1439 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_LIGHTMODEL_AMBIENT; @@ -3774,7 +3775,7 @@ yyreduce: case 166: /* Line 1455 of yacc.c */ -#line 1443 "program_parse.y" +#line 1444 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_LIGHTMODEL_SCENECOLOR; @@ -3785,7 +3786,7 @@ yyreduce: case 167: /* Line 1455 of yacc.c */ -#line 1451 "program_parse.y" +#line 1452 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_LIGHTPROD; @@ -3798,7 +3799,7 @@ yyreduce: case 169: /* Line 1455 of yacc.c */ -#line 1463 "program_parse.y" +#line 1464 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = (yyvsp[(3) - (3)].integer); @@ -3809,7 +3810,7 @@ yyreduce: case 170: /* Line 1455 of yacc.c */ -#line 1471 "program_parse.y" +#line 1472 "program_parse.y" { (yyval.integer) = STATE_TEXENV_COLOR; ;} @@ -3818,7 +3819,7 @@ yyreduce: case 171: /* Line 1455 of yacc.c */ -#line 1477 "program_parse.y" +#line 1478 "program_parse.y" { (yyval.integer) = STATE_AMBIENT; ;} @@ -3827,7 +3828,7 @@ yyreduce: case 172: /* Line 1455 of yacc.c */ -#line 1481 "program_parse.y" +#line 1482 "program_parse.y" { (yyval.integer) = STATE_DIFFUSE; ;} @@ -3836,7 +3837,7 @@ yyreduce: case 173: /* Line 1455 of yacc.c */ -#line 1485 "program_parse.y" +#line 1486 "program_parse.y" { (yyval.integer) = STATE_SPECULAR; ;} @@ -3845,7 +3846,7 @@ yyreduce: case 174: /* Line 1455 of yacc.c */ -#line 1491 "program_parse.y" +#line 1492 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxLights) { yyerror(& (yylsp[(1) - (1)]), state, "invalid light selector"); @@ -3859,7 +3860,7 @@ yyreduce: case 175: /* Line 1455 of yacc.c */ -#line 1502 "program_parse.y" +#line 1503 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_TEXGEN; @@ -3871,7 +3872,7 @@ yyreduce: case 176: /* Line 1455 of yacc.c */ -#line 1511 "program_parse.y" +#line 1512 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_EYE_S; ;} @@ -3880,7 +3881,7 @@ yyreduce: case 177: /* Line 1455 of yacc.c */ -#line 1515 "program_parse.y" +#line 1516 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_OBJECT_S; ;} @@ -3889,7 +3890,7 @@ yyreduce: case 178: /* Line 1455 of yacc.c */ -#line 1520 "program_parse.y" +#line 1521 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S; ;} @@ -3898,7 +3899,7 @@ yyreduce: case 179: /* Line 1455 of yacc.c */ -#line 1524 "program_parse.y" +#line 1525 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S; ;} @@ -3907,7 +3908,7 @@ yyreduce: case 180: /* Line 1455 of yacc.c */ -#line 1528 "program_parse.y" +#line 1529 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S; ;} @@ -3916,7 +3917,7 @@ yyreduce: case 181: /* Line 1455 of yacc.c */ -#line 1532 "program_parse.y" +#line 1533 "program_parse.y" { (yyval.integer) = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S; ;} @@ -3925,7 +3926,7 @@ yyreduce: case 182: /* Line 1455 of yacc.c */ -#line 1538 "program_parse.y" +#line 1539 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = (yyvsp[(2) - (2)].integer); @@ -3935,7 +3936,7 @@ yyreduce: case 183: /* Line 1455 of yacc.c */ -#line 1545 "program_parse.y" +#line 1546 "program_parse.y" { (yyval.integer) = STATE_FOG_COLOR; ;} @@ -3944,7 +3945,7 @@ yyreduce: case 184: /* Line 1455 of yacc.c */ -#line 1549 "program_parse.y" +#line 1550 "program_parse.y" { (yyval.integer) = STATE_FOG_PARAMS; ;} @@ -3953,7 +3954,7 @@ yyreduce: case 185: /* Line 1455 of yacc.c */ -#line 1555 "program_parse.y" +#line 1556 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_CLIPPLANE; @@ -3964,7 +3965,7 @@ yyreduce: case 186: /* Line 1455 of yacc.c */ -#line 1563 "program_parse.y" +#line 1564 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxClipPlanes) { yyerror(& (yylsp[(1) - (1)]), state, "invalid clip plane selector"); @@ -3978,7 +3979,7 @@ yyreduce: case 187: /* Line 1455 of yacc.c */ -#line 1574 "program_parse.y" +#line 1575 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = (yyvsp[(2) - (2)].integer); @@ -3988,7 +3989,7 @@ yyreduce: case 188: /* Line 1455 of yacc.c */ -#line 1581 "program_parse.y" +#line 1582 "program_parse.y" { (yyval.integer) = STATE_POINT_SIZE; ;} @@ -3997,7 +3998,7 @@ yyreduce: case 189: /* Line 1455 of yacc.c */ -#line 1585 "program_parse.y" +#line 1586 "program_parse.y" { (yyval.integer) = STATE_POINT_ATTENUATION; ;} @@ -4006,7 +4007,7 @@ yyreduce: case 190: /* Line 1455 of yacc.c */ -#line 1591 "program_parse.y" +#line 1592 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (5)].state)[0]; (yyval.state)[1] = (yyvsp[(1) - (5)].state)[1]; @@ -4019,7 +4020,7 @@ yyreduce: case 191: /* Line 1455 of yacc.c */ -#line 1601 "program_parse.y" +#line 1602 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (2)].state)[0]; (yyval.state)[1] = (yyvsp[(1) - (2)].state)[1]; @@ -4032,7 +4033,7 @@ yyreduce: case 192: /* Line 1455 of yacc.c */ -#line 1611 "program_parse.y" +#line 1612 "program_parse.y" { (yyval.state)[2] = 0; (yyval.state)[3] = 3; @@ -4042,7 +4043,7 @@ yyreduce: case 193: /* Line 1455 of yacc.c */ -#line 1616 "program_parse.y" +#line 1617 "program_parse.y" { /* It seems logical that the matrix row range specifier would have * to specify a range or more than one row (i.e., $5 > $3). @@ -4063,7 +4064,7 @@ yyreduce: case 194: /* Line 1455 of yacc.c */ -#line 1634 "program_parse.y" +#line 1635 "program_parse.y" { (yyval.state)[0] = (yyvsp[(2) - (3)].state)[0]; (yyval.state)[1] = (yyvsp[(2) - (3)].state)[1]; @@ -4074,7 +4075,7 @@ yyreduce: case 195: /* Line 1455 of yacc.c */ -#line 1642 "program_parse.y" +#line 1643 "program_parse.y" { (yyval.integer) = 0; ;} @@ -4083,7 +4084,7 @@ yyreduce: case 196: /* Line 1455 of yacc.c */ -#line 1646 "program_parse.y" +#line 1647 "program_parse.y" { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} @@ -4092,7 +4093,7 @@ yyreduce: case 197: /* Line 1455 of yacc.c */ -#line 1652 "program_parse.y" +#line 1653 "program_parse.y" { (yyval.integer) = STATE_MATRIX_INVERSE; ;} @@ -4101,7 +4102,7 @@ yyreduce: case 198: /* Line 1455 of yacc.c */ -#line 1656 "program_parse.y" +#line 1657 "program_parse.y" { (yyval.integer) = STATE_MATRIX_TRANSPOSE; ;} @@ -4110,7 +4111,7 @@ yyreduce: case 199: /* Line 1455 of yacc.c */ -#line 1660 "program_parse.y" +#line 1661 "program_parse.y" { (yyval.integer) = STATE_MATRIX_INVTRANS; ;} @@ -4119,7 +4120,7 @@ yyreduce: case 200: /* Line 1455 of yacc.c */ -#line 1666 "program_parse.y" +#line 1667 "program_parse.y" { if ((yyvsp[(1) - (1)].integer) > 3) { yyerror(& (yylsp[(1) - (1)]), state, "invalid matrix row reference"); @@ -4133,7 +4134,7 @@ yyreduce: case 201: /* Line 1455 of yacc.c */ -#line 1677 "program_parse.y" +#line 1678 "program_parse.y" { (yyval.state)[0] = STATE_MODELVIEW_MATRIX; (yyval.state)[1] = (yyvsp[(2) - (2)].integer); @@ -4143,7 +4144,7 @@ yyreduce: case 202: /* Line 1455 of yacc.c */ -#line 1682 "program_parse.y" +#line 1683 "program_parse.y" { (yyval.state)[0] = STATE_PROJECTION_MATRIX; (yyval.state)[1] = 0; @@ -4153,7 +4154,7 @@ yyreduce: case 203: /* Line 1455 of yacc.c */ -#line 1687 "program_parse.y" +#line 1688 "program_parse.y" { (yyval.state)[0] = STATE_MVP_MATRIX; (yyval.state)[1] = 0; @@ -4163,7 +4164,7 @@ yyreduce: case 204: /* Line 1455 of yacc.c */ -#line 1692 "program_parse.y" +#line 1693 "program_parse.y" { (yyval.state)[0] = STATE_TEXTURE_MATRIX; (yyval.state)[1] = (yyvsp[(2) - (2)].integer); @@ -4173,7 +4174,7 @@ yyreduce: case 205: /* Line 1455 of yacc.c */ -#line 1697 "program_parse.y" +#line 1698 "program_parse.y" { yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported"); YYERROR; @@ -4183,7 +4184,7 @@ yyreduce: case 206: /* Line 1455 of yacc.c */ -#line 1702 "program_parse.y" +#line 1703 "program_parse.y" { (yyval.state)[0] = STATE_PROGRAM_MATRIX; (yyval.state)[1] = (yyvsp[(3) - (4)].integer); @@ -4193,7 +4194,7 @@ yyreduce: case 207: /* Line 1455 of yacc.c */ -#line 1709 "program_parse.y" +#line 1710 "program_parse.y" { (yyval.integer) = 0; ;} @@ -4202,7 +4203,7 @@ yyreduce: case 208: /* Line 1455 of yacc.c */ -#line 1713 "program_parse.y" +#line 1714 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} @@ -4211,7 +4212,7 @@ yyreduce: case 209: /* Line 1455 of yacc.c */ -#line 1718 "program_parse.y" +#line 1719 "program_parse.y" { /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix * zero is valid. @@ -4228,7 +4229,7 @@ yyreduce: case 210: /* Line 1455 of yacc.c */ -#line 1731 "program_parse.y" +#line 1732 "program_parse.y" { /* Since GL_ARB_matrix_palette isn't supported, just let any value * through here. The error will be generated later. @@ -4240,7 +4241,7 @@ yyreduce: case 211: /* Line 1455 of yacc.c */ -#line 1739 "program_parse.y" +#line 1740 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxProgramMatrices) { yyerror(& (yylsp[(1) - (1)]), state, "invalid program matrix selector"); @@ -4254,7 +4255,7 @@ yyreduce: case 212: /* Line 1455 of yacc.c */ -#line 1750 "program_parse.y" +#line 1751 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = STATE_DEPTH_RANGE; @@ -4264,7 +4265,7 @@ yyreduce: case 217: /* Line 1455 of yacc.c */ -#line 1762 "program_parse.y" +#line 1763 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = state->state_param_enum; @@ -4277,7 +4278,7 @@ yyreduce: case 218: /* Line 1455 of yacc.c */ -#line 1772 "program_parse.y" +#line 1773 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (1)].integer); (yyval.state)[1] = (yyvsp[(1) - (1)].integer); @@ -4287,7 +4288,7 @@ yyreduce: case 219: /* Line 1455 of yacc.c */ -#line 1777 "program_parse.y" +#line 1778 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (3)].integer); (yyval.state)[1] = (yyvsp[(3) - (3)].integer); @@ -4297,7 +4298,7 @@ yyreduce: case 220: /* Line 1455 of yacc.c */ -#line 1784 "program_parse.y" +#line 1785 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = state->state_param_enum; @@ -4310,7 +4311,7 @@ yyreduce: case 221: /* Line 1455 of yacc.c */ -#line 1794 "program_parse.y" +#line 1795 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = state->state_param_enum; @@ -4323,7 +4324,7 @@ yyreduce: case 222: /* Line 1455 of yacc.c */ -#line 1803 "program_parse.y" +#line 1804 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (1)].integer); (yyval.state)[1] = (yyvsp[(1) - (1)].integer); @@ -4333,7 +4334,7 @@ yyreduce: case 223: /* Line 1455 of yacc.c */ -#line 1808 "program_parse.y" +#line 1809 "program_parse.y" { (yyval.state)[0] = (yyvsp[(1) - (3)].integer); (yyval.state)[1] = (yyvsp[(3) - (3)].integer); @@ -4343,7 +4344,7 @@ yyreduce: case 224: /* Line 1455 of yacc.c */ -#line 1815 "program_parse.y" +#line 1816 "program_parse.y" { memset((yyval.state), 0, sizeof((yyval.state))); (yyval.state)[0] = state->state_param_enum; @@ -4356,7 +4357,7 @@ yyreduce: case 225: /* Line 1455 of yacc.c */ -#line 1825 "program_parse.y" +#line 1826 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxEnvParams) { yyerror(& (yylsp[(1) - (1)]), state, "invalid environment parameter reference"); @@ -4369,7 +4370,7 @@ yyreduce: case 226: /* Line 1455 of yacc.c */ -#line 1835 "program_parse.y" +#line 1836 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxLocalParams) { yyerror(& (yylsp[(1) - (1)]), state, "invalid local parameter reference"); @@ -4382,7 +4383,7 @@ yyreduce: case 231: /* Line 1455 of yacc.c */ -#line 1850 "program_parse.y" +#line 1851 "program_parse.y" { (yyval.vector).count = 4; (yyval.vector).data[0] = (yyvsp[(1) - (1)].real); @@ -4395,7 +4396,7 @@ yyreduce: case 232: /* Line 1455 of yacc.c */ -#line 1860 "program_parse.y" +#line 1861 "program_parse.y" { (yyval.vector).count = 1; (yyval.vector).data[0] = (yyvsp[(1) - (1)].real); @@ -4408,7 +4409,7 @@ yyreduce: case 233: /* Line 1455 of yacc.c */ -#line 1868 "program_parse.y" +#line 1869 "program_parse.y" { (yyval.vector).count = 1; (yyval.vector).data[0] = (float) (yyvsp[(1) - (1)].integer); @@ -4421,7 +4422,7 @@ yyreduce: case 234: /* Line 1455 of yacc.c */ -#line 1878 "program_parse.y" +#line 1879 "program_parse.y" { (yyval.vector).count = 4; (yyval.vector).data[0] = (yyvsp[(2) - (3)].real); @@ -4434,7 +4435,7 @@ yyreduce: case 235: /* Line 1455 of yacc.c */ -#line 1886 "program_parse.y" +#line 1887 "program_parse.y" { (yyval.vector).count = 4; (yyval.vector).data[0] = (yyvsp[(2) - (5)].real); @@ -4447,7 +4448,7 @@ yyreduce: case 236: /* Line 1455 of yacc.c */ -#line 1895 "program_parse.y" +#line 1896 "program_parse.y" { (yyval.vector).count = 4; (yyval.vector).data[0] = (yyvsp[(2) - (7)].real); @@ -4460,7 +4461,7 @@ yyreduce: case 237: /* Line 1455 of yacc.c */ -#line 1904 "program_parse.y" +#line 1905 "program_parse.y" { (yyval.vector).count = 4; (yyval.vector).data[0] = (yyvsp[(2) - (9)].real); @@ -4473,7 +4474,7 @@ yyreduce: case 238: /* Line 1455 of yacc.c */ -#line 1914 "program_parse.y" +#line 1915 "program_parse.y" { (yyval.real) = ((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].real) : (yyvsp[(2) - (2)].real); ;} @@ -4482,7 +4483,7 @@ yyreduce: case 239: /* Line 1455 of yacc.c */ -#line 1918 "program_parse.y" +#line 1919 "program_parse.y" { (yyval.real) = (float)(((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].integer) : (yyvsp[(2) - (2)].integer)); ;} @@ -4491,35 +4492,35 @@ yyreduce: case 240: /* Line 1455 of yacc.c */ -#line 1923 "program_parse.y" +#line 1924 "program_parse.y" { (yyval.negate) = FALSE; ;} break; case 241: /* Line 1455 of yacc.c */ -#line 1924 "program_parse.y" +#line 1925 "program_parse.y" { (yyval.negate) = TRUE; ;} break; case 242: /* Line 1455 of yacc.c */ -#line 1925 "program_parse.y" +#line 1926 "program_parse.y" { (yyval.negate) = FALSE; ;} break; case 243: /* Line 1455 of yacc.c */ -#line 1928 "program_parse.y" +#line 1929 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;} break; case 245: /* Line 1455 of yacc.c */ -#line 1932 "program_parse.y" +#line 1933 "program_parse.y" { /* NV_fragment_program_option defines the size qualifiers in a * fairly broken way. "SHORT" or "LONG" can optionally be used @@ -4558,7 +4559,7 @@ yyreduce: case 246: /* Line 1455 of yacc.c */ -#line 1966 "program_parse.y" +#line 1967 "program_parse.y" { ;} break; @@ -4566,14 +4567,14 @@ yyreduce: case 247: /* Line 1455 of yacc.c */ -#line 1970 "program_parse.y" +#line 1971 "program_parse.y" { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} break; case 249: /* Line 1455 of yacc.c */ -#line 1974 "program_parse.y" +#line 1975 "program_parse.y" { if (!declare_variable(state, (yyvsp[(3) - (3)].string), (yyvsp[(0) - (3)].integer), & (yylsp[(3) - (3)]))) { free((yyvsp[(3) - (3)].string)); @@ -4585,7 +4586,7 @@ yyreduce: case 250: /* Line 1455 of yacc.c */ -#line 1981 "program_parse.y" +#line 1982 "program_parse.y" { if (!declare_variable(state, (yyvsp[(1) - (1)].string), (yyvsp[(0) - (1)].integer), & (yylsp[(1) - (1)]))) { free((yyvsp[(1) - (1)].string)); @@ -4597,7 +4598,7 @@ yyreduce: case 251: /* Line 1455 of yacc.c */ -#line 1990 "program_parse.y" +#line 1991 "program_parse.y" { struct asm_symbol *const s = declare_variable(state, (yyvsp[(3) - (5)].string), at_output, & (yylsp[(3) - (5)])); @@ -4614,7 +4615,7 @@ yyreduce: case 252: /* Line 1455 of yacc.c */ -#line 2004 "program_parse.y" +#line 2005 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.result) = VERT_RESULT_HPOS; @@ -4628,7 +4629,7 @@ yyreduce: case 253: /* Line 1455 of yacc.c */ -#line 2013 "program_parse.y" +#line 2014 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.result) = VERT_RESULT_FOGC; @@ -4642,7 +4643,7 @@ yyreduce: case 254: /* Line 1455 of yacc.c */ -#line 2022 "program_parse.y" +#line 2023 "program_parse.y" { (yyval.result) = (yyvsp[(2) - (2)].result); ;} @@ -4651,7 +4652,7 @@ yyreduce: case 255: /* Line 1455 of yacc.c */ -#line 2026 "program_parse.y" +#line 2027 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.result) = VERT_RESULT_PSIZ; @@ -4665,7 +4666,7 @@ yyreduce: case 256: /* Line 1455 of yacc.c */ -#line 2035 "program_parse.y" +#line 2036 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.result) = VERT_RESULT_TEX0 + (yyvsp[(3) - (3)].integer); @@ -4679,7 +4680,7 @@ yyreduce: case 257: /* Line 1455 of yacc.c */ -#line 2044 "program_parse.y" +#line 2045 "program_parse.y" { if (state->mode == ARB_fragment) { (yyval.result) = FRAG_RESULT_DEPTH; @@ -4693,7 +4694,7 @@ yyreduce: case 258: /* Line 1455 of yacc.c */ -#line 2055 "program_parse.y" +#line 2056 "program_parse.y" { (yyval.result) = (yyvsp[(2) - (3)].integer) + (yyvsp[(3) - (3)].integer); ;} @@ -4702,7 +4703,7 @@ yyreduce: case 259: /* Line 1455 of yacc.c */ -#line 2061 "program_parse.y" +#line 2062 "program_parse.y" { (yyval.integer) = (state->mode == ARB_vertex) ? VERT_RESULT_COL0 @@ -4713,7 +4714,7 @@ yyreduce: case 260: /* Line 1455 of yacc.c */ -#line 2067 "program_parse.y" +#line 2068 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.integer) = VERT_RESULT_COL0; @@ -4727,7 +4728,7 @@ yyreduce: case 261: /* Line 1455 of yacc.c */ -#line 2076 "program_parse.y" +#line 2077 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.integer) = VERT_RESULT_BFC0; @@ -4741,7 +4742,7 @@ yyreduce: case 262: /* Line 1455 of yacc.c */ -#line 2087 "program_parse.y" +#line 2088 "program_parse.y" { (yyval.integer) = 0; ;} @@ -4750,7 +4751,7 @@ yyreduce: case 263: /* Line 1455 of yacc.c */ -#line 2091 "program_parse.y" +#line 2092 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.integer) = 0; @@ -4764,7 +4765,7 @@ yyreduce: case 264: /* Line 1455 of yacc.c */ -#line 2100 "program_parse.y" +#line 2101 "program_parse.y" { if (state->mode == ARB_vertex) { (yyval.integer) = 1; @@ -4778,91 +4779,91 @@ yyreduce: case 265: /* Line 1455 of yacc.c */ -#line 2110 "program_parse.y" +#line 2111 "program_parse.y" { (yyval.integer) = 0; ;} break; case 266: /* Line 1455 of yacc.c */ -#line 2111 "program_parse.y" +#line 2112 "program_parse.y" { (yyval.integer) = 0; ;} break; case 267: /* Line 1455 of yacc.c */ -#line 2112 "program_parse.y" +#line 2113 "program_parse.y" { (yyval.integer) = 1; ;} break; case 268: /* Line 1455 of yacc.c */ -#line 2115 "program_parse.y" +#line 2116 "program_parse.y" { (yyval.integer) = 0; ;} break; case 269: /* Line 1455 of yacc.c */ -#line 2116 "program_parse.y" +#line 2117 "program_parse.y" { (yyval.integer) = 0; ;} break; case 270: /* Line 1455 of yacc.c */ -#line 2117 "program_parse.y" +#line 2118 "program_parse.y" { (yyval.integer) = 1; ;} break; case 271: /* Line 1455 of yacc.c */ -#line 2120 "program_parse.y" +#line 2121 "program_parse.y" { (yyval.integer) = 0; ;} break; case 272: /* Line 1455 of yacc.c */ -#line 2121 "program_parse.y" +#line 2122 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} break; case 273: /* Line 1455 of yacc.c */ -#line 2124 "program_parse.y" +#line 2125 "program_parse.y" { (yyval.integer) = 0; ;} break; case 274: /* Line 1455 of yacc.c */ -#line 2125 "program_parse.y" +#line 2126 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} break; case 275: /* Line 1455 of yacc.c */ -#line 2128 "program_parse.y" +#line 2129 "program_parse.y" { (yyval.integer) = 0; ;} break; case 276: /* Line 1455 of yacc.c */ -#line 2129 "program_parse.y" +#line 2130 "program_parse.y" { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} break; case 277: /* Line 1455 of yacc.c */ -#line 2133 "program_parse.y" +#line 2134 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureCoordUnits) { yyerror(& (yylsp[(1) - (1)]), state, "invalid texture coordinate unit selector"); @@ -4876,7 +4877,7 @@ yyreduce: case 278: /* Line 1455 of yacc.c */ -#line 2144 "program_parse.y" +#line 2145 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureImageUnits) { yyerror(& (yylsp[(1) - (1)]), state, "invalid texture image unit selector"); @@ -4890,7 +4891,7 @@ yyreduce: case 279: /* Line 1455 of yacc.c */ -#line 2155 "program_parse.y" +#line 2156 "program_parse.y" { if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureUnits) { yyerror(& (yylsp[(1) - (1)]), state, "invalid texture unit selector"); @@ -4904,7 +4905,7 @@ yyreduce: case 280: /* Line 1455 of yacc.c */ -#line 2166 "program_parse.y" +#line 2167 "program_parse.y" { struct asm_symbol *exist = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(2) - (4)].string)); @@ -4933,7 +4934,7 @@ yyreduce: /* Line 1455 of yacc.c */ -#line 4937 "program_parse.tab.c" +#line 4938 "program_parse.tab.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -5152,7 +5153,7 @@ yyreturn: /* Line 1675 of yacc.c */ -#line 2195 "program_parse.y" +#line 2196 "program_parse.y" void diff --git a/src/mesa/program/program_parse.y b/src/mesa/program/program_parse.y index 861927c744c..fb6ef85a9fc 100644 --- a/src/mesa/program/program_parse.y +++ b/src/mesa/program/program_parse.y @@ -835,6 +835,7 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */ $$.Base.File = $1->param_binding_type; if ($3.Base.RelAddr) { + state->prog->IndirectRegisterFiles |= (1 << $$.Base.File); $1->param_accessed_indirectly = 1; $$.Base.RelAddr = 1; @@ -934,7 +935,7 @@ addrRegRelOffset: { $$ = 0; } addrRegPosOffset: INTEGER { - if (($1 < 0) || ($1 > 63)) { + if (($1 < 0) || ($1 > 4095)) { char s[100]; _mesa_snprintf(s, sizeof(s), "relative address offset too large (%d)", $1); @@ -948,7 +949,7 @@ addrRegPosOffset: INTEGER addrRegNegOffset: INTEGER { - if (($1 < 0) || ($1 > 64)) { + if (($1 < 0) || ($1 > 4096)) { char s[100]; _mesa_snprintf(s, sizeof(s), "relative address offset too large (%d)", $1); diff --git a/src/mesa/program/programopt.h b/src/mesa/program/programopt.h index 21fac07849a..4af6357f976 100644 --- a/src/mesa/program/programopt.h +++ b/src/mesa/program/programopt.h @@ -26,6 +26,7 @@ #ifndef PROGRAMOPT_H #define PROGRAMOPT_H 1 +#include "main/mtypes.h" extern void _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog); diff --git a/src/mesa/slang/library/slang_common_builtin.gc b/src/mesa/slang/library/slang_common_builtin.gc index d75354deffe..1f5ddbc1ee2 100644 --- a/src/mesa/slang/library/slang_common_builtin.gc +++ b/src/mesa/slang/library/slang_common_builtin.gc @@ -411,7 +411,7 @@ float atan(const float y, const float x) if (abs(x) > 1.0e-4) { r = atan(y / x); if (x < 0.0) { - r = r + sign(y) * 3.141593; + r = r + 3.141593 - 6.283186 * float(y < 0.0); } } else { diff --git a/src/mesa/slang/slang_builtin.h b/src/mesa/slang/slang_builtin.h index ed9ae80b3c3..dc92f83f8ef 100644 --- a/src/mesa/slang/slang_builtin.h +++ b/src/mesa/slang/slang_builtin.h @@ -26,8 +26,8 @@ #ifndef SLANG_BUILTIN_H #define SLANG_BUILTIN_H -#include "program/prog_parameter.h" -#include "slang_utility.h" +#include "main/glheader.h" +#include "main/mtypes.h" #include "slang_ir.h" diff --git a/src/mesa/slang/slang_codegen.h b/src/mesa/slang/slang_codegen.h index 461633fe346..ff0279bbfed 100644 --- a/src/mesa/slang/slang_codegen.h +++ b/src/mesa/slang/slang_codegen.h @@ -27,9 +27,13 @@ #define SLANG_CODEGEN_H -#include "main/imports.h" +#include "main/glheader.h" #include "slang_compile.h" +#include "slang_compile_variable.h" +#include "slang_typeinfo.h" +#include "slang_utility.h" +struct slang_function_; #define MAX_LOOP_DEPTH 30 diff --git a/src/mesa/slang/slang_compile.c b/src/mesa/slang/slang_compile.c index 12ab4666aed..de1bb56cd9a 100644 --- a/src/mesa/slang/slang_compile.c +++ b/src/mesa/slang/slang_compile.c @@ -36,6 +36,7 @@ #include "program/prog_print.h" #include "program/prog_parameter.h" #include "../../glsl/pp/sl_pp_public.h" +#include "../../glsl/pp/sl_pp_purify.h" #include "../../glsl/cl/sl_cl_parse.h" #include "slang_codegen.h" #include "slang_compile.h" diff --git a/src/mesa/slang/slang_compile.h b/src/mesa/slang/slang_compile.h index 71fcaa39931..6061f878e75 100644 --- a/src/mesa/slang/slang_compile.h +++ b/src/mesa/slang/slang_compile.h @@ -25,13 +25,14 @@ #if !defined SLANG_COMPILE_H #define SLANG_COMPILE_H -#include "main/imports.h" +#include "main/glheader.h" #include "main/mtypes.h" -#include "slang_typeinfo.h" -#include "slang_compile_variable.h" -#include "slang_compile_struct.h" -#include "slang_compile_operation.h" #include "slang_compile_function.h" +#include "slang_compile_struct.h" +#include "slang_compile_variable.h" +#include "slang_utility.h" + +struct slang_code_object_; #if defined __cplusplus extern "C" { diff --git a/src/mesa/slang/slang_compile_function.h b/src/mesa/slang/slang_compile_function.h index a5445ec2537..0eced3ca1a1 100644 --- a/src/mesa/slang/slang_compile_function.h +++ b/src/mesa/slang/slang_compile_function.h @@ -25,6 +25,14 @@ #ifndef SLANG_COMPILE_FUNCTION_H #define SLANG_COMPILE_FUNCTION_H +#include "main/glheader.h" +#include "slang_compile_operation.h" +#include "slang_compile_variable.h" +#include "slang_log.h" +#include "slang_utility.h" + +struct slang_name_space_; +struct slang_operation_; /** * Types of functions. diff --git a/src/mesa/slang/slang_compile_operation.h b/src/mesa/slang/slang_compile_operation.h index 1f15c198963..b8c5f214cf0 100644 --- a/src/mesa/slang/slang_compile_operation.h +++ b/src/mesa/slang/slang_compile_operation.h @@ -26,6 +26,10 @@ #define SLANG_COMPILE_OPERATION_H +#include "main/glheader.h" +#include "slang_compile_variable.h" +#include "slang_utility.h" + /** * Types of slang operations. * These are the types of the AST (abstract syntax tree) nodes. diff --git a/src/mesa/slang/slang_compile_struct.h b/src/mesa/slang/slang_compile_struct.h index 90c5512f4d3..7be6f204e11 100644 --- a/src/mesa/slang/slang_compile_struct.h +++ b/src/mesa/slang/slang_compile_struct.h @@ -29,6 +29,9 @@ extern "C" { #endif +#include "main/glheader.h" +#include "slang_utility.h" + struct slang_function_; typedef struct slang_struct_scope_ diff --git a/src/mesa/slang/slang_compile_variable.h b/src/mesa/slang/slang_compile_variable.h index 5c9d248b354..48dc6efca4b 100644 --- a/src/mesa/slang/slang_compile_variable.h +++ b/src/mesa/slang/slang_compile_variable.h @@ -26,7 +26,9 @@ #define SLANG_COMPILE_VARIABLE_H -struct slang_ir_storage_; +#include "main/glheader.h" +#include "slang_typeinfo.h" +#include "slang_utility.h" /** diff --git a/src/mesa/slang/slang_emit.h b/src/mesa/slang/slang_emit.h index ab4c202d673..f93d6b00d69 100644 --- a/src/mesa/slang/slang_emit.h +++ b/src/mesa/slang/slang_emit.h @@ -25,11 +25,9 @@ #ifndef SLANG_EMIT_H #define SLANG_EMIT_H - -#include "main/imports.h" -#include "slang_compile.h" +#include "main/glheader.h" #include "slang_ir.h" -#include "main/mtypes.h" +#include "slang_vartable.h" extern GLuint diff --git a/src/mesa/slang/slang_ir.h b/src/mesa/slang/slang_ir.h index b7a373746b4..ce9a6c5a483 100644 --- a/src/mesa/slang/slang_ir.h +++ b/src/mesa/slang/slang_ir.h @@ -37,6 +37,7 @@ #include "slang_compile.h" #include "slang_label.h" #include "main/mtypes.h" +#include "program/prog_instruction.h" /** diff --git a/src/mesa/slang/slang_label.c b/src/mesa/slang/slang_label.c index 8e3a8ebc1aa..24881d5b6e6 100644 --- a/src/mesa/slang/slang_label.c +++ b/src/mesa/slang/slang_label.c @@ -7,6 +7,8 @@ */ +#include "main/mtypes.h" +#include "program/prog_instruction.h" #include "slang_label.h" #include "slang_mem.h" diff --git a/src/mesa/slang/slang_label.h b/src/mesa/slang/slang_label.h index 4d04df18d25..b0cff3a8e89 100644 --- a/src/mesa/slang/slang_label.h +++ b/src/mesa/slang/slang_label.h @@ -1,10 +1,9 @@ #ifndef SLANG_LABEL_H #define SLANG_LABEL_H 1 -#include "main/imports.h" -#include "main/mtypes.h" -#include "program/prog_instruction.h" +#include "main/glheader.h" +struct gl_program; struct slang_label_ { diff --git a/src/mesa/slang/slang_link.c b/src/mesa/slang/slang_link.c index 00c2c13cc67..c21f67256a5 100644 --- a/src/mesa/slang/slang_link.c +++ b/src/mesa/slang/slang_link.c @@ -756,6 +756,8 @@ _slang_update_inputs_outputs(struct gl_program *prog) prog->InputsRead = 0x0; prog->OutputsWritten = 0x0; + prog->IndirectRegisterFiles = 0x0; + for (i = 0; i < prog->NumInstructions; i++) { const struct prog_instruction *inst = prog->Instructions + i; const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); @@ -774,6 +776,9 @@ _slang_update_inputs_outputs(struct gl_program *prog) else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) { maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1)); } + + if (inst->SrcReg[j].RelAddr) + prog->IndirectRegisterFiles |= (1 << inst->SrcReg[j].File); } if (inst->DstReg.File == PROGRAM_OUTPUT) { @@ -784,6 +789,8 @@ _slang_update_inputs_outputs(struct gl_program *prog) else if (inst->DstReg.File == PROGRAM_ADDRESS) { maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1); } + if (inst->DstReg.RelAddr) + prog->IndirectRegisterFiles |= (1 << inst->DstReg.File); } prog->NumAddressRegs = maxAddrReg; } @@ -1199,11 +1206,11 @@ _slang_link(GLcontext *ctx, vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, &shProg->FragmentProgram->Base); if (ctx->Shader.Flags & GLSL_DUMP) { - printf("Mesa pre-link fragment program:\n"); + fprintf(stderr, "Mesa pre-link fragment program:\n"); _mesa_print_program(&fragProg->Base); _mesa_print_program_parameters(ctx, &fragProg->Base); - printf("Mesa post-link fragment program:\n"); + fprintf(stderr, "Mesa post-link fragment program:\n"); _mesa_print_program(&shProg->FragmentProgram->Base); _mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base); } @@ -1222,11 +1229,11 @@ _slang_link(GLcontext *ctx, geomNotify = ctx->Driver.ProgramStringNotify(ctx, MESA_GEOMETRY_PROGRAM, &shProg->GeometryProgram->Base); if (ctx->Shader.Flags & GLSL_DUMP) { - printf("Mesa pre-link geometry program:\n"); + fprintf(stderr, "Mesa pre-link geometry program:\n"); _mesa_print_program(&geomProg->Base); _mesa_print_program_parameters(ctx, &geomProg->Base); - printf("Mesa post-link geometry program:\n"); + fprintf(stderr, "Mesa post-link geometry program:\n"); _mesa_print_program(&shProg->GeometryProgram->Base); _mesa_print_program_parameters(ctx, &shProg->GeometryProgram->Base); } @@ -1240,11 +1247,11 @@ _slang_link(GLcontext *ctx, fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, &shProg->VertexProgram->Base); if (ctx->Shader.Flags & GLSL_DUMP) { - printf("Mesa pre-link vertex program:\n"); + fprintf(stderr, "Mesa pre-link vertex program:\n"); _mesa_print_program(&vertProg->Base); _mesa_print_program_parameters(ctx, &vertProg->Base); - printf("Mesa post-link vertex program:\n"); + fprintf(stderr, "Mesa post-link vertex program:\n"); _mesa_print_program(&shProg->VertexProgram->Base); _mesa_print_program_parameters(ctx, &shProg->VertexProgram->Base); } @@ -1259,10 +1266,10 @@ _slang_link(GLcontext *ctx, } if (ctx->Shader.Flags & GLSL_DUMP) { - printf("Varying vars:\n"); + fprintf(stderr, "Varying vars:\n"); _mesa_print_parameter_list(shProg->Varying); if (shProg->InfoLog) { - printf("Info Log: %s\n", shProg->InfoLog); + fprintf(stderr, "Info Log: %s\n", shProg->InfoLog); } } diff --git a/src/mesa/slang/slang_link.h b/src/mesa/slang/slang_link.h index 2b44d20787a..3e9fa2d743d 100644 --- a/src/mesa/slang/slang_link.h +++ b/src/mesa/slang/slang_link.h @@ -25,7 +25,7 @@ #ifndef SLANG_LINK_H #define SLANG_LINK_H 1 -#include "slang_compile.h" +#include "main/mtypes.h" extern void diff --git a/src/mesa/slang/slang_log.h b/src/mesa/slang/slang_log.h index dcaba0285a7..544a26654e7 100644 --- a/src/mesa/slang/slang_log.h +++ b/src/mesa/slang/slang_log.h @@ -27,6 +27,8 @@ #define SLANG_LOG_H +#include "main/glheader.h" + typedef struct slang_info_log_ { char *text; diff --git a/src/mesa/slang/slang_print.h b/src/mesa/slang/slang_print.h index 46605c80610..99da3041437 100644 --- a/src/mesa/slang/slang_print.h +++ b/src/mesa/slang/slang_print.h @@ -3,6 +3,12 @@ #ifndef SLANG_PRINT #define SLANG_PRINT +#include "main/glheader.h" +#include "slang_compile_function.h" +#include "slang_compile_operation.h" +#include "slang_compile_variable.h" +#include "slang_typeinfo.h" + extern void slang_print_function(const slang_function *f, GLboolean body); diff --git a/src/mesa/slang/slang_simplify.h b/src/mesa/slang/slang_simplify.h index 8689c23b1a0..37fb938d4fb 100644 --- a/src/mesa/slang/slang_simplify.h +++ b/src/mesa/slang/slang_simplify.h @@ -26,6 +26,13 @@ #define SLANG_SIMPLIFY_H +#include "main/glheader.h" +#include "slang_compile.h" +#include "slang_compile_function.h" +#include "slang_compile_operation.h" +#include "slang_log.h" +#include "slang_utility.h" + extern GLint _slang_lookup_constant(const char *name); diff --git a/src/mesa/slang/slang_utility.h b/src/mesa/slang/slang_utility.h index 2c0d0bcbb2a..cb9b6d2aaaa 100644 --- a/src/mesa/slang/slang_utility.h +++ b/src/mesa/slang/slang_utility.h @@ -26,6 +26,8 @@ #define SLANG_UTILITY_H +#include "main/glheader.h" + /* Compile-time assertions. If the expression is zero, try to declare an * array of size [-1] to cause compilation error. */ diff --git a/src/mesa/slang/slang_vartable.h b/src/mesa/slang/slang_vartable.h index 94bcd63f45a..97945b89d03 100644 --- a/src/mesa/slang/slang_vartable.h +++ b/src/mesa/slang/slang_vartable.h @@ -2,6 +2,9 @@ #ifndef SLANG_VARTABLE_H #define SLANG_VARTABLE_H +#include "main/glheader.h" +#include "slang_utility.h" + struct slang_ir_storage_; typedef struct slang_var_table_ slang_var_table; diff --git a/src/mesa/state_tracker/st_atom.h b/src/mesa/state_tracker/st_atom.h index 1f0fef63df5..c7a04951bff 100644 --- a/src/mesa/state_tracker/st_atom.h +++ b/src/mesa/state_tracker/st_atom.h @@ -34,6 +34,8 @@ #ifndef ST_ATOM_H #define ST_ATOM_H +#include "main/glheader.h" + struct st_context; struct st_tracked_state; diff --git a/src/mesa/state_tracker/st_atom_constbuf.h b/src/mesa/state_tracker/st_atom_constbuf.h index f707534e2cf..97b076629ee 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.h +++ b/src/mesa/state_tracker/st_atom_constbuf.h @@ -29,6 +29,9 @@ #ifndef ST_ATOM_CONSTBUF_H #define ST_ATOM_CONSTBUF_H +struct gl_program_parameter_list; +struct st_context; + void st_upload_constants( struct st_context *st, struct gl_program_parameter_list *params, diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c index 3c07afba9aa..1616e945fea 100644 --- a/src/mesa/state_tracker/st_atom_depth.c +++ b/src/mesa/state_tracker/st_atom_depth.c @@ -33,6 +33,8 @@ */ +#include <assert.h> + #include "st_context.h" #include "st_atom.h" #include "pipe/p_context.h" diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index b88c74fa03a..8a8d17599ec 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -37,6 +37,7 @@ #include "main/image.h" #include "main/macros.h" #include "program/program.h" +#include "program/prog_cache.h" #include "program/prog_instruction.h" #include "program/prog_parameter.h" #include "program/prog_print.h" diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index cebaad5f000..05442ef91b5 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -40,7 +40,6 @@ #include "program/program.h" #include "pipe/p_context.h" -#include "pipe/p_shader_tokens.h" #include "util/u_simple_shaders.h" diff --git a/src/mesa/state_tracker/st_atom_shader.h b/src/mesa/state_tracker/st_atom_shader.h index 8403bc66c92..56d4c68f4f7 100644 --- a/src/mesa/state_tracker/st_atom_shader.h +++ b/src/mesa/state_tracker/st_atom_shader.h @@ -30,6 +30,9 @@ #define ST_ATOM_SHADER_H +struct st_context; +struct translated_vertex_program; + extern void st_free_translated_vertex_programs(struct st_context *st, struct translated_vertex_program *xvp); diff --git a/src/mesa/state_tracker/st_atom_stipple.c b/src/mesa/state_tracker/st_atom_stipple.c index 31e124b3293..ecdd9f06f6a 100644 --- a/src/mesa/state_tracker/st_atom_stipple.c +++ b/src/mesa/state_tracker/st_atom_stipple.c @@ -33,6 +33,8 @@ */ +#include <assert.h> + #include "st_context.h" #include "st_atom.h" #include "pipe/p_context.h" diff --git a/src/mesa/state_tracker/st_cache.h b/src/mesa/state_tracker/st_cache.h index b81de316ec9..6d5de7b13ad 100644 --- a/src/mesa/state_tracker/st_cache.h +++ b/src/mesa/state_tracker/st_cache.h @@ -33,10 +33,11 @@ #ifndef ST_CACHE_H #define ST_CACHE_H -#include "cso_cache/cso_cache.h" - struct pipe_blend_state; +struct pipe_depth_stencil_alpha_state; +struct pipe_rasterizer_state; struct pipe_sampler_state; +struct pipe_shader_state; struct st_context; diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index ba600ccef6d..0b8ecd27cb9 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -46,6 +46,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" #include "util/u_inlines.h" #include "util/u_draw_quad.h" #include "util/u_simple_shaders.h" diff --git a/src/mesa/state_tracker/st_cb_bitmap.h b/src/mesa/state_tracker/st_cb_bitmap.h index 8af975b74fc..d04b2b67795 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.h +++ b/src/mesa/state_tracker/st_cb_bitmap.h @@ -30,7 +30,10 @@ #define ST_CB_BITMAP_H -#include "main/mtypes.h" +#include "main/compiler.h" + +struct dd_function_table; +struct st_context; #if FEATURE_drawpix diff --git a/src/mesa/state_tracker/st_cb_blit.h b/src/mesa/state_tracker/st_cb_blit.h index 7ab9a54df90..c230652cefc 100644 --- a/src/mesa/state_tracker/st_cb_blit.h +++ b/src/mesa/state_tracker/st_cb_blit.h @@ -29,8 +29,10 @@ #define ST_CB_BLIT_H -#include "main/mtypes.h" -#include "st_context.h" +#include "main/compiler.h" + +struct dd_function_table; +struct st_context; extern void diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.h b/src/mesa/state_tracker/st_cb_bufferobjects.h index a27daac2bf0..1c991d20837 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.h +++ b/src/mesa/state_tracker/st_cb_bufferobjects.h @@ -28,9 +28,12 @@ #ifndef ST_CB_BUFFEROBJECTS_H #define ST_CB_BUFFEROBJECTS_H -struct st_context; -struct gl_buffer_object; +#include "main/compiler.h" +#include "main/mtypes.h" + +struct dd_function_table; struct pipe_resource; +struct st_context; /** * State_tracker vertex/pixel buffer object, derived from Mesa's diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index ea2414c4a00..246ab2e9579 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -45,6 +45,7 @@ #include "st_program.h" #include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" #include "pipe/p_state.h" #include "pipe/p_defines.h" #include "util/u_format.h" diff --git a/src/mesa/state_tracker/st_cb_clear.h b/src/mesa/state_tracker/st_cb_clear.h index bc035ac25ca..b27c09d10e4 100644 --- a/src/mesa/state_tracker/st_cb_clear.h +++ b/src/mesa/state_tracker/st_cb_clear.h @@ -30,6 +30,9 @@ #define ST_CB_CLEAR_H +struct dd_function_table; +struct st_context; + extern void st_init_clear(struct st_context *st); diff --git a/src/mesa/state_tracker/st_cb_condrender.h b/src/mesa/state_tracker/st_cb_condrender.h index 891f1cbcd8c..79d0db8d08a 100644 --- a/src/mesa/state_tracker/st_cb_condrender.h +++ b/src/mesa/state_tracker/st_cb_condrender.h @@ -29,6 +29,8 @@ #define ST_CB_CONDRENDER_H +struct dd_function_table; + extern void st_init_cond_render_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.h b/src/mesa/state_tracker/st_cb_drawpixels.h index 7d5e901ccc5..575f169e08e 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.h +++ b/src/mesa/state_tracker/st_cb_drawpixels.h @@ -30,7 +30,10 @@ #define ST_CB_DRAWPIXELS_H -#include "main/mtypes.h" +#include "main/compiler.h" + +struct dd_function_table; +struct st_context; #if FEATURE_drawpix diff --git a/src/mesa/state_tracker/st_cb_drawtex.c b/src/mesa/state_tracker/st_cb_drawtex.c index b191a7f8902..c99a8d792ed 100644 --- a/src/mesa/state_tracker/st_cb_drawtex.c +++ b/src/mesa/state_tracker/st_cb_drawtex.c @@ -14,7 +14,6 @@ #include "main/imports.h" #include "main/image.h" -#include "main/bufferobj.h" #include "main/macros.h" #include "program/program.h" #include "program/prog_print.h" diff --git a/src/mesa/state_tracker/st_cb_drawtex.h b/src/mesa/state_tracker/st_cb_drawtex.h index a3f54a349cc..d21262f8977 100644 --- a/src/mesa/state_tracker/st_cb_drawtex.h +++ b/src/mesa/state_tracker/st_cb_drawtex.h @@ -10,7 +10,10 @@ #define ST_CB_DRAWTEX_H -#include "main/mtypes.h" +#include "main/compiler.h" + +struct dd_function_table; +struct st_context; #if FEATURE_OES_draw_texture diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index 4aaf91d5a19..037e576fabe 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -33,6 +33,7 @@ #include "util/u_format.h" #include "st_cb_eglimage.h" #include "st_cb_fbo.h" +#include "st_context.h" #include "st_texture.h" #include "st_format.h" #include "st_manager.h" diff --git a/src/mesa/state_tracker/st_cb_eglimage.h b/src/mesa/state_tracker/st_cb_eglimage.h index d6953e99f69..b6e44d5aff5 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.h +++ b/src/mesa/state_tracker/st_cb_eglimage.h @@ -29,8 +29,9 @@ #ifndef ST_CB_EGLIMAGE_H #define ST_CB_EGLIMAGE_H -#include "main/mtypes.h" -#include "main/dd.h" +#include "main/compiler.h" + +struct dd_function_table; #if FEATURE_OES_EGL_image diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 43b6c1e75f4..62a9bbcb25f 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -29,6 +29,15 @@ #ifndef ST_CB_FBO_H #define ST_CB_FBO_H +#include "main/compiler.h" +#include "main/glheader.h" +#include "main/mtypes.h" + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" + +struct dd_function_table; +struct pipe_context; /** * Derived renderbuffer class. Just need to add a pointer to the diff --git a/src/mesa/state_tracker/st_cb_feedback.h b/src/mesa/state_tracker/st_cb_feedback.h index 706d84960f7..f2342f58238 100644 --- a/src/mesa/state_tracker/st_cb_feedback.h +++ b/src/mesa/state_tracker/st_cb_feedback.h @@ -30,7 +30,9 @@ #define ST_CB_FEEDBACK_H -#include "main/mtypes.h" +#include "main/compiler.h" + +struct dd_function_table; #if FEATURE_feedback diff --git a/src/mesa/state_tracker/st_cb_flush.h b/src/mesa/state_tracker/st_cb_flush.h index 7fca0176a30..7672b4cf1da 100644 --- a/src/mesa/state_tracker/st_cb_flush.h +++ b/src/mesa/state_tracker/st_cb_flush.h @@ -30,6 +30,12 @@ #define ST_CB_FLUSH_H +#include "pipe/p_compiler.h" + +struct dd_function_table; +struct pipe_fence_handle; +struct st_context; + extern void st_init_flush_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_cb_program.h b/src/mesa/state_tracker/st_cb_program.h index 0de96f2fd22..0fd179ef3df 100644 --- a/src/mesa/state_tracker/st_cb_program.h +++ b/src/mesa/state_tracker/st_cb_program.h @@ -29,6 +29,10 @@ #define ST_CB_PROGRAM_H +#include "main/mtypes.h" + +struct dd_function_table; + extern void st_init_program_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_cb_rasterpos.h b/src/mesa/state_tracker/st_cb_rasterpos.h index d2ed7297f15..2dc109bb184 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.h +++ b/src/mesa/state_tracker/st_cb_rasterpos.h @@ -29,7 +29,9 @@ #define ST_CB_RASTERPOS_H -#include "main/mtypes.h" +#include "main/compiler.h" + +struct dd_function_table; #if FEATURE_rastpos diff --git a/src/mesa/state_tracker/st_cb_readpixels.h b/src/mesa/state_tracker/st_cb_readpixels.h index c90ef029062..9e1f7b4925e 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.h +++ b/src/mesa/state_tracker/st_cb_readpixels.h @@ -29,6 +29,10 @@ #ifndef ST_CB_READPIXELS_H #define ST_CB_READPIXELS_H +#include "main/mtypes.h" + +struct dd_function_table; + extern struct st_renderbuffer * st_get_color_read_renderbuffer(GLcontext *ctx); diff --git a/src/mesa/state_tracker/st_cb_strings.h b/src/mesa/state_tracker/st_cb_strings.h index 3b765aaa592..92d5d2d9ba7 100644 --- a/src/mesa/state_tracker/st_cb_strings.h +++ b/src/mesa/state_tracker/st_cb_strings.h @@ -30,6 +30,8 @@ #define ST_CB_STRINGS_H +struct dd_function_table; + extern void st_init_string_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_cb_texture.h b/src/mesa/state_tracker/st_cb_texture.h index 1cd9fc3a50f..6942478e815 100644 --- a/src/mesa/state_tracker/st_cb_texture.h +++ b/src/mesa/state_tracker/st_cb_texture.h @@ -30,6 +30,13 @@ #define ST_CB_TEXTURE_H +#include "main/glheader.h" +#include "main/mtypes.h" + +struct dd_function_table; +struct pipe_context; +struct st_context; + extern GLboolean st_finalize_texture(GLcontext *ctx, struct pipe_context *pipe, diff --git a/src/mesa/state_tracker/st_cb_viewport.h b/src/mesa/state_tracker/st_cb_viewport.h index db7dd6eab82..bcfd7cb68af 100644 --- a/src/mesa/state_tracker/st_cb_viewport.h +++ b/src/mesa/state_tracker/st_cb_viewport.h @@ -25,5 +25,12 @@ * **************************************************************************/ +#ifndef ST_CB_VIEWPORT_H +#define ST_CB_VIEWPORT_H + +struct dd_function_table; + extern void st_init_viewport_functions(struct dd_function_table *functions); + +#endif /* ST_CB_VIEW_PORT_H */ diff --git a/src/mesa/state_tracker/st_cb_xformfb.h b/src/mesa/state_tracker/st_cb_xformfb.h index 50efcb9293f..574cf481e18 100644 --- a/src/mesa/state_tracker/st_cb_xformfb.h +++ b/src/mesa/state_tracker/st_cb_xformfb.h @@ -29,6 +29,10 @@ #define ST_CB_XFORMFB_H +#include "main/compiler.h" + +struct dd_function_table; + #if FEATURE_EXT_transform_feedback extern void diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 7eb5f32611d..2ce5f087536 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -28,6 +28,7 @@ #include "main/imports.h" #include "main/context.h" #include "main/shaderobj.h" +#include "program/prog_cache.h" #include "vbo/vbo.h" #include "glapi/glapi.h" #include "st_context.h" @@ -62,6 +63,9 @@ #include "cso_cache/cso_context.h" +DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE) + + /** * Called via ctx->Driver.UpdateState() */ @@ -169,7 +173,7 @@ struct st_context *st_create_context(gl_api api, struct pipe_context *pipe, /* XXX: need a capability bit in gallium to query if the pipe * driver prefers DP4 or MUL/MAD for vertex transformation. */ - if (debug_get_bool_option("MESA_MVP_DP4", FALSE)) + if (debug_get_option_mesa_mvp_dp4()) _mesa_set_mvp_with_dp4( ctx, GL_TRUE ); return st_create_context_priv(ctx, pipe); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index a147a021176..60c25fb8f00 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -1,3 +1,4 @@ +//struct dd_function_table; /************************************************************************** * * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. @@ -29,21 +30,17 @@ #define ST_CONTEXT_H #include "main/mtypes.h" -#include "program/prog_cache.h" #include "pipe/p_state.h" #include "state_tracker/st_api.h" - -struct st_context; -struct st_texture_object; -struct st_fragment_program; +struct bitmap_cache; +struct blit_state; +struct dd_function_table; struct draw_context; struct draw_stage; -struct cso_cache; -struct cso_blend; struct gen_mipmap_state; -struct blit_state; -struct bitmap_cache; +struct st_context; +struct st_fragment_program; #define ST_NEW_MESA 0x1 /* Mesa state has changed */ diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c index ebf6ec6e7e2..df32491d044 100644 --- a/src/mesa/state_tracker/st_debug.c +++ b/src/mesa/state_tracker/st_debug.c @@ -55,6 +55,8 @@ static const struct debug_named_value st_debug_flags[] = { { "query", DEBUG_QUERY, NULL }, DEBUG_NAMED_VALUE_END }; + +DEBUG_GET_ONCE_FLAGS_OPTION(st_debug, "ST_DEBUG", st_debug_flags, 0) #endif @@ -62,7 +64,7 @@ void st_debug_init(void) { #ifdef DEBUG - ST_DEBUG = debug_get_flags_option("ST_DEBUG", st_debug_flags, 0 ); + ST_DEBUG = debug_get_option_st_debug(); #endif } diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 5821da4889d..5b054892702 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -58,6 +58,7 @@ #include "util/u_inlines.h" #include "util/u_format.h" #include "util/u_prim.h" +#include "util/u_draw_quad.h" #include "draw/draw_context.h" #include "cso_cache/cso_context.h" @@ -494,6 +495,49 @@ setup_non_interleaved_attribs(GLcontext *ctx, } +static void +setup_index_buffer(GLcontext *ctx, + const struct _mesa_index_buffer *ib, + struct pipe_index_buffer *ibuffer) +{ + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = st->pipe; + + memset(ibuffer, 0, sizeof(*ibuffer)); + if (ib) { + struct gl_buffer_object *bufobj = ib->obj; + + switch (ib->type) { + case GL_UNSIGNED_INT: + ibuffer->index_size = 4; + break; + case GL_UNSIGNED_SHORT: + ibuffer->index_size = 2; + break; + case GL_UNSIGNED_BYTE: + ibuffer->index_size = 1; + break; + default: + assert(0); + return; + } + + /* get/create the index buffer object */ + if (bufobj && bufobj->Name) { + /* elements/indexes are in a real VBO */ + struct st_buffer_object *stobj = st_buffer_object(bufobj); + pipe_resource_reference(&ibuffer->buffer, stobj->buffer); + ibuffer->offset = pointer_to_offset(ib->ptr); + } + else { + /* element/indicies are in user space memory */ + ibuffer->buffer = + pipe_user_buffer_create(pipe->screen, (void *) ib->ptr, + ib->count * ibuffer->index_size, + PIPE_BIND_INDEX_BUFFER); + } + } +} /** * Prior to drawing, check that any uniforms referenced by the @@ -568,8 +612,11 @@ st_draw_vbo(GLcontext *ctx, GLuint attr; struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; unsigned num_vbuffers, num_velements; + struct pipe_index_buffer ibuffer; GLboolean userSpace = GL_FALSE; GLboolean vertDataEdgeFlags; + struct pipe_draw_info info; + unsigned i; /* Mesa core state should have been validated already */ assert(ctx->NewState == 0x0); @@ -647,113 +694,35 @@ st_draw_vbo(GLcontext *ctx, if (num_vbuffers == 0 || num_velements == 0) return; - /* do actual drawing */ - if (ib) { - /* indexed primitive */ - struct gl_buffer_object *bufobj = ib->obj; - struct pipe_resource *indexBuf = NULL; - unsigned indexSize, indexOffset, i; + setup_index_buffer(ctx, ib, &ibuffer); + pipe->set_index_buffer(pipe, &ibuffer); - switch (ib->type) { - case GL_UNSIGNED_INT: - indexSize = 4; - break; - case GL_UNSIGNED_SHORT: - indexSize = 2; - break; - case GL_UNSIGNED_BYTE: - indexSize = 1; - break; - default: - assert(0); - return; - } - - /* get/create the index buffer object */ - if (bufobj && bufobj->Name) { - /* elements/indexes are in a real VBO */ - struct st_buffer_object *stobj = st_buffer_object(bufobj); - pipe_resource_reference(&indexBuf, stobj->buffer); - indexOffset = pointer_to_offset(ib->ptr) / indexSize; - } - else { - /* element/indicies are in user space memory */ - indexBuf = pipe_user_buffer_create(pipe->screen, (void *) ib->ptr, - ib->count * indexSize, - PIPE_BIND_INDEX_BUFFER); - indexOffset = 0; + util_draw_init_info(&info); + if (ib) { + info.indexed = TRUE; + if (min_index != ~0 && max_index != ~0) { + info.min_index = min_index; + info.max_index = max_index; } + } - /* draw */ - if (pipe->draw_range_elements && min_index != ~0 && max_index != ~0) { - /* XXX: exercise temporary path to pass min/max directly - * through to driver & draw module. These interfaces still - * need a bit of work... - */ - for (i = 0; i < nr_prims; i++) { - unsigned vcount = prims[i].count; - unsigned prim = translate_prim(ctx, prims[i].mode); - - if (u_trim_pipe_prim(prims[i].mode, &vcount)) { - pipe->draw_range_elements(pipe, indexBuf, indexSize, - prims[i].basevertex, - min_index, max_index, prim, - prims[i].start + indexOffset, vcount); - } - } - } - else { - for (i = 0; i < nr_prims; i++) { - unsigned vcount = prims[i].count; - unsigned prim = translate_prim(ctx, prims[i].mode); - - if (u_trim_pipe_prim(prims[i].mode, &vcount)) { - if (prims[i].num_instances == 1) { - pipe->draw_elements(pipe, indexBuf, - indexSize, - prims[i].basevertex, - prim, - prims[i].start + indexOffset, - vcount); - } - else { - pipe->draw_elements_instanced(pipe, indexBuf, - indexSize, - prims[i].basevertex, - prim, - prims[i].start + indexOffset, - vcount, - 0, /* startInstance */ - prims[i].num_instances); - } - } - } + /* do actual drawing */ + for (i = 0; i < nr_prims; i++) { + info.mode = translate_prim( ctx, prims[i].mode ); + info.start = prims[i].start; + info.count = prims[i].count; + info.instance_count = prims[i].num_instances; + info.index_bias = prims[i].basevertex; + if (!ib) { + info.min_index = info.start; + info.max_index = info.start + info.count - 1; } - pipe_resource_reference(&indexBuf, NULL); + if (u_trim_pipe_prim(info.mode, &info.count)) + pipe->draw_vbo(pipe, &info); } - else { - /* non-indexed */ - GLuint i; - - for (i = 0; i < nr_prims; i++) { - unsigned vcount = prims[i].count; - unsigned prim = translate_prim(ctx, prims[i].mode); - if (u_trim_pipe_prim(prims[i].mode, &vcount)) { - if (prims[i].num_instances == 1) { - pipe->draw_arrays(pipe, prim, prims[i].start, vcount); - } - else { - pipe->draw_arrays_instanced(pipe, prim, - prims[i].start, - vcount, - 0, /* startInstance */ - prims[i].num_instances); - } - } - } - } + pipe_resource_reference(&ibuffer.buffer, NULL); /* unreference buffers (frees wrapped user-space buffer objects) */ for (attr = 0; attr < num_vbuffers; attr++) { diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h index 3e0face656b..f36184487a6 100644 --- a/src/mesa/state_tracker/st_draw.h +++ b/src/mesa/state_tracker/st_draw.h @@ -34,8 +34,13 @@ #ifndef ST_DRAW_H #define ST_DRAW_H -struct _mesa_prim; +#include "main/compiler.h" +#include "main/glheader.h" +#include "main/mtypes.h" + struct _mesa_index_buffer; +struct _mesa_prim; +struct st_context; void st_init_draw( struct st_context *st ); diff --git a/src/mesa/state_tracker/st_extensions.h b/src/mesa/state_tracker/st_extensions.h index 2994f16dd33..aa9b2b2b914 100644 --- a/src/mesa/state_tracker/st_extensions.h +++ b/src/mesa/state_tracker/st_extensions.h @@ -30,6 +30,8 @@ #define ST_EXTENSIONS_H +struct st_context; + extern void st_init_limits(struct st_context *st); extern void st_init_extensions(struct st_context *st); diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index 29768f296d6..841c58cadc8 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -31,7 +31,12 @@ #define ST_FORMAT_H #include "main/formats.h" +#include "main/mtypes.h" +#include "pipe/p_defines.h" +#include "pipe/p_format.h" + +struct pipe_screen; extern GLenum st_format_datatype(enum pipe_format format); diff --git a/src/mesa/state_tracker/st_gen_mipmap.h b/src/mesa/state_tracker/st_gen_mipmap.h index 00fbae93026..016bf3f4bba 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.h +++ b/src/mesa/state_tracker/st_gen_mipmap.h @@ -30,6 +30,10 @@ #define ST_GEN_MIPMAP_H +#include "main/mtypes.h" + +struct st_context; + extern void st_init_generate_mipmap(struct st_context *st); diff --git a/src/mesa/state_tracker/st_gl_api.h b/src/mesa/state_tracker/st_gl_api.h index fe1aec207ea..57c6d9f24d2 100644 --- a/src/mesa/state_tracker/st_gl_api.h +++ b/src/mesa/state_tracker/st_gl_api.h @@ -2,8 +2,6 @@ #ifndef ST_GL_API_H #define ST_GL_API_H -#include "state_tracker/st_api.h" - struct st_api *st_gl_api_create(void); struct st_api *st_gl_api_create_es1(void); struct st_api *st_gl_api_create_es2(void); diff --git a/src/mesa/state_tracker/st_manager.h b/src/mesa/state_tracker/st_manager.h index cd2887b1e0f..48a9d4d99a6 100644 --- a/src/mesa/state_tracker/st_manager.h +++ b/src/mesa/state_tracker/st_manager.h @@ -29,8 +29,11 @@ #ifndef ST_MANAGER_H #define ST_MANAGER_H -#include "state_tracker/st_api.h" -#include "st_context.h" +#include "main/mtypes.h" + +#include "pipe/p_compiler.h" + +struct st_context; struct pipe_surface * st_manager_get_egl_image_surface(struct st_context *st, diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c index bacd091853b..a19dcc92534 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -44,6 +44,15 @@ #include "util/u_math.h" #include "util/u_memory.h" + +#define PROGRAM_ANY_CONST ((1 << PROGRAM_LOCAL_PARAM) | \ + (1 << PROGRAM_ENV_PARAM) | \ + (1 << PROGRAM_STATE_VAR) | \ + (1 << PROGRAM_NAMED_PARAM) | \ + (1 << PROGRAM_CONSTANT) | \ + (1 << PROGRAM_UNIFORM)) + + struct label { unsigned branch_target; unsigned token; @@ -205,7 +214,7 @@ src_register( struct st_translate *t, return ureg_src_undef(); case PROGRAM_TEMPORARY: - ASSERT(index >= 0); + assert(index >= 0); if (ureg_dst_is_undef(t->temps[index])) t->temps[index] = ureg_DECL_temporary( t->ureg ); assert(index < Elements(t->temps)); @@ -215,7 +224,7 @@ src_register( struct st_translate *t, case PROGRAM_ENV_PARAM: case PROGRAM_LOCAL_PARAM: case PROGRAM_UNIFORM: - ASSERT(index >= 0); + assert(index >= 0); return t->constants[index]; case PROGRAM_STATE_VAR: case PROGRAM_CONSTANT: /* ie, immediate */ @@ -738,9 +747,11 @@ emit_adjusted_wpos( struct st_translate *t, struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg); struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; - ureg_ADD(ureg, - ureg_writemask(wpos_temp, TGSI_WRITEMASK_X | TGSI_WRITEMASK_Y), - wpos_input, ureg_imm1f(ureg, value)); + /* Note that we bias X and Y and pass Z and W through unchanged. + * The shader might also use gl_FragCoord.w and .z. + */ + ureg_ADD(ureg, wpos_temp, wpos_input, + ureg_imm4f(ureg, value, value, 0.0f, 0.0f)); t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); } @@ -1057,6 +1068,16 @@ st_translate_mesa_program( t->address[0] = ureg_DECL_address( ureg ); } + if (program->IndirectRegisterFiles & (1 << PROGRAM_TEMPORARY)) { + /* If temps are accessed with indirect addressing, declare temporaries + * in sequential order. Else, we declare them on demand elsewhere. + */ + for (i = 0; i < program->NumTemporaries; i++) { + /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */ + t->temps[i] = ureg_DECL_temporary( t->ureg ); + } + } + /* Emit constants and immediates. Mesa uses a single index space * for these, so we put all the translated regs in t->constants. */ @@ -1067,7 +1088,7 @@ st_translate_mesa_program( ret = PIPE_ERROR_OUT_OF_MEMORY; goto out; } - + for (i = 0; i < program->Parameters->NumParameters; i++) { switch (program->Parameters->Parameters[i].Type) { case PROGRAM_ENV_PARAM: @@ -1078,13 +1099,14 @@ st_translate_mesa_program( t->constants[i] = ureg_DECL_constant( ureg, i ); break; - /* Emit immediates only when there is no address register - * in use. FIXME: Be smarter and recognize param arrays: + /* Emit immediates only when there's no indirect addressing of + * the const buffer. + * FIXME: Be smarter and recognize param arrays: * indirect addressing is only valid within the referenced * array. */ case PROGRAM_CONSTANT: - if (program->NumAddressRegs > 0) + if (program->IndirectRegisterFiles & PROGRAM_ANY_CONST) t->constants[i] = ureg_DECL_constant( ureg, i ); else t->constants[i] = diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h index e3c5bd1d94d..ca076ce3622 100644 --- a/src/mesa/state_tracker/st_mesa_to_tgsi.h +++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h @@ -30,8 +30,10 @@ #define ST_MESA_TO_TGSI_H #include "main/mtypes.h" -#include "tgsi/tgsi_ureg.h" +#include "pipe/p_compiler.h" + +struct ureg_program; #if defined __cplusplus extern "C" { diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 6f3ecdbce11..91528c227b2 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -41,6 +41,7 @@ #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" #include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_ureg.h" #include "st_debug.h" #include "st_context.h" diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index d779d5a6dde..3805b9a725e 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -36,11 +36,8 @@ #include "main/mtypes.h" #include "program/program.h" -#include "pipe/p_shader_tokens.h" - - -struct cso_fragment_shader; -struct cso_vertex_shader; +#include "pipe/p_state.h" +#include "st_context.h" /** diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c index dbdf1ea1ad0..add6e949dfb 100644 --- a/src/mesa/state_tracker/st_texture.c +++ b/src/mesa/state_tracker/st_texture.c @@ -25,14 +25,14 @@ * **************************************************************************/ +#include <stdio.h> + #include "st_context.h" #include "st_format.h" #include "st_texture.h" #include "st_cb_fbo.h" #include "main/enums.h" -#undef Elements /* fix re-defined macro warning */ - #include "pipe/p_state.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" diff --git a/src/mesa/swrast/s_aaline.h b/src/mesa/swrast/s_aaline.h index f1d708ec801..922eb230e51 100644 --- a/src/mesa/swrast/s_aaline.h +++ b/src/mesa/swrast/s_aaline.h @@ -28,7 +28,7 @@ #define S_AALINE_H -#include "swrast.h" +#include "main/mtypes.h" extern void diff --git a/src/mesa/swrast/s_aatriangle.h b/src/mesa/swrast/s_aatriangle.h index 4b57fa73a27..9aed41a1915 100644 --- a/src/mesa/swrast/s_aatriangle.h +++ b/src/mesa/swrast/s_aatriangle.h @@ -28,7 +28,7 @@ #define S_AATRIANGLE_H -#include "swrast.h" +#include "main/mtypes.h" extern void diff --git a/src/mesa/swrast/s_alpha.h b/src/mesa/swrast/s_alpha.h index 7a5b72e650a..239484a9743 100644 --- a/src/mesa/swrast/s_alpha.h +++ b/src/mesa/swrast/s_alpha.h @@ -28,7 +28,8 @@ #define S_ALPHA_H -#include "s_context.h" +#include "main/mtypes.h" +#include "s_span.h" extern GLint diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c index fa280e72e40..1338b6802d4 100644 --- a/src/mesa/swrast/s_atifragshader.c +++ b/src/mesa/swrast/s_atifragshader.c @@ -21,10 +21,10 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "main/atifragshader.h" #include "swrast/s_atifragshader.h" +#include "swrast/s_context.h" /** diff --git a/src/mesa/swrast/s_atifragshader.h b/src/mesa/swrast/s_atifragshader.h index 871a0c04559..cce455a0465 100644 --- a/src/mesa/swrast/s_atifragshader.h +++ b/src/mesa/swrast/s_atifragshader.h @@ -27,7 +27,8 @@ #define S_ATIFRAGSHADER_H -#include "s_context.h" +#include "main/mtypes.h" +#include "s_span.h" extern void diff --git a/src/mesa/swrast/s_blend.h b/src/mesa/swrast/s_blend.h index 8d5a81635d5..9cedde3bf20 100644 --- a/src/mesa/swrast/s_blend.h +++ b/src/mesa/swrast/s_blend.h @@ -27,7 +27,8 @@ #define S_BLEND_H -#include "s_context.h" +#include "main/mtypes.h" +#include "s_span.h" extern void diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 6d2d17c61d9..d8d8a80b7d7 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -28,7 +28,6 @@ #include "main/imports.h" #include "main/bufferobj.h" -#include "main/context.h" #include "main/colormac.h" #include "main/mtypes.h" #include "main/teximage.h" diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index c9755e6da18..6d81f74768f 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -43,6 +43,7 @@ #ifndef S_CONTEXT_H #define S_CONTEXT_H +#include "main/compiler.h" #include "main/mtypes.h" #include "program/prog_execute.h" #include "swrast.h" diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c index ed637cac124..f952fd6baa7 100644 --- a/src/mesa/swrast/s_depth.c +++ b/src/mesa/swrast/s_depth.c @@ -30,7 +30,6 @@ #include "main/imports.h" #include "s_depth.h" -#include "s_context.h" #include "s_span.h" diff --git a/src/mesa/swrast/s_depth.h b/src/mesa/swrast/s_depth.h index 7eae3667428..878d242f5e5 100644 --- a/src/mesa/swrast/s_depth.h +++ b/src/mesa/swrast/s_depth.h @@ -27,7 +27,8 @@ #define S_DEPTH_H -#include "s_context.h" +#include "main/mtypes.h" +#include "s_span.h" extern GLuint diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c index 373b1416e28..6ac8ac73b0b 100644 --- a/src/mesa/swrast/s_feedback.c +++ b/src/mesa/swrast/s_feedback.c @@ -24,7 +24,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/feedback.h" #include "main/macros.h" diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c index 3fc84392133..689500a613a 100644 --- a/src/mesa/swrast/s_fog.c +++ b/src/mesa/swrast/s_fog.c @@ -25,7 +25,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "s_context.h" diff --git a/src/mesa/swrast/s_fog.h b/src/mesa/swrast/s_fog.h index 06107de3f9d..a496746d106 100644 --- a/src/mesa/swrast/s_fog.h +++ b/src/mesa/swrast/s_fog.h @@ -28,7 +28,8 @@ #define S_FOG_H -#include "swrast.h" +#include "main/mtypes.h" +#include "s_span.h" extern GLfloat diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 413f136cd59..9facb44d9bf 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -24,9 +24,9 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "program/prog_instruction.h" +#include "s_context.h" #include "s_fragprog.h" #include "s_span.h" diff --git a/src/mesa/swrast/s_fragprog.h b/src/mesa/swrast/s_fragprog.h index e1b7e679185..92b9d01e173 100644 --- a/src/mesa/swrast/s_fragprog.h +++ b/src/mesa/swrast/s_fragprog.h @@ -27,7 +27,8 @@ #define S_FRAGPROG_H -#include "s_context.h" +#include "main/mtypes.h" +#include "s_span.h" extern void diff --git a/src/mesa/swrast/s_logic.h b/src/mesa/swrast/s_logic.h index e8cfae33f23..d609513348d 100644 --- a/src/mesa/swrast/s_logic.h +++ b/src/mesa/swrast/s_logic.h @@ -27,7 +27,8 @@ #define S_LOGIC_H -#include "swrast.h" +#include "main/mtypes.h" +#include "s_span.h" extern void _swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, diff --git a/src/mesa/swrast/s_masking.h b/src/mesa/swrast/s_masking.h index 3ba4f8356cb..cb000da0fd8 100644 --- a/src/mesa/swrast/s_masking.h +++ b/src/mesa/swrast/s_masking.h @@ -27,7 +27,8 @@ #define S_MASKING_H -#include "swrast.h" +#include "main/mtypes.h" +#include "s_span.h" extern void diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index 1663ece8294..12431662c47 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -25,7 +25,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "s_context.h" #include "s_feedback.h" diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 6ad9aceec77..553fd9a76d8 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -27,7 +27,6 @@ #include "main/bufferobj.h" #include "main/colormac.h" #include "main/convolve.h" -#include "main/context.h" #include "main/feedback.h" #include "main/formats.h" #include "main/image.h" diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 687c8eb0bf8..8931cdec1bc 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -33,7 +33,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "main/imports.h" #include "main/image.h" @@ -971,6 +970,10 @@ shade_texture_span(GLcontext *ctx, SWspan *span) if (span->primitive == GL_BITMAP && span->array->ChanType != GL_FLOAT) { convert_color_type(span, GL_FLOAT, 0); } + else { + span->array->rgba = (void *) span->array->attribs[FRAG_ATTRIB_COL0]; + } + if (span->primitive != GL_POINT || (span->interpMask & SPAN_RGBA) || ctx->Point.PointSprite) { @@ -1222,9 +1225,22 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) GLchan rgbaSave[MAX_WIDTH][4]; const GLuint fragOutput = multiFragOutputs ? buf : 0; + /* set span->array->rgba to colors for render buffer's datatype */ if (rb->DataType != span->array->ChanType || fragOutput > 0) { convert_color_type(span, rb->DataType, fragOutput); } + else { + if (rb->DataType == GL_UNSIGNED_BYTE) { + span->array->rgba = span->array->rgba8; + } + else if (rb->DataType == GL_UNSIGNED_SHORT) { + span->array->rgba = (void *) span->array->rgba16; + } + else { + span->array->rgba = (void *) + span->array->attribs[FRAG_ATTRIB_COL0]; + } + } if (!multiFragOutputs && numBuffers > 1) { /* save colors for second, third renderbuffer writes */ diff --git a/src/mesa/swrast/s_stencil.h b/src/mesa/swrast/s_stencil.h index cd6cbc57b0b..c076ebbe2a1 100644 --- a/src/mesa/swrast/s_stencil.h +++ b/src/mesa/swrast/s_stencil.h @@ -27,7 +27,8 @@ #define S_STENCIL_H -#include "swrast.h" +#include "main/mtypes.h" +#include "s_span.h" diff --git a/src/mesa/swrast/s_texcombine.h b/src/mesa/swrast/s_texcombine.h index 9ed96efb879..4f5dfbe1afe 100644 --- a/src/mesa/swrast/s_texcombine.h +++ b/src/mesa/swrast/s_texcombine.h @@ -27,7 +27,8 @@ #define S_TEXCOMBINE_H -#include "swrast.h" +#include "main/mtypes.h" +#include "s_span.h" extern void _swrast_texture_span( GLcontext *ctx, SWspan *span ); diff --git a/src/mesa/swrast/s_texfilter.h b/src/mesa/swrast/s_texfilter.h index 2e265d685c5..eceab59658e 100644 --- a/src/mesa/swrast/s_texfilter.h +++ b/src/mesa/swrast/s_texfilter.h @@ -27,7 +27,8 @@ #define S_TEXFILTER_H -#include "swrast.h" +#include "main/mtypes.h" +#include "s_context.h" extern texture_sample_func diff --git a/src/mesa/swrast/s_zoom.h b/src/mesa/swrast/s_zoom.h index 43917be65fc..09f624efad5 100644 --- a/src/mesa/swrast/s_zoom.h +++ b/src/mesa/swrast/s_zoom.h @@ -25,7 +25,8 @@ #ifndef S_ZOOM_H #define S_ZOOM_H -#include "swrast.h" +#include "main/mtypes.h" +#include "s_span.h" extern void diff --git a/src/mesa/swrast_setup/ss_context.h b/src/mesa/swrast_setup/ss_context.h index 1ec293fade1..56551ab273c 100644 --- a/src/mesa/swrast_setup/ss_context.h +++ b/src/mesa/swrast_setup/ss_context.h @@ -28,9 +28,8 @@ #ifndef SS_CONTEXT_H #define SS_CONTEXT_H -#include "main/mtypes.h" +#include "main/glheader.h" #include "swrast/swrast.h" -#include "swrast_setup.h" #include "tnl/t_context.h" typedef struct { diff --git a/src/mesa/swrast_setup/ss_triangle.h b/src/mesa/swrast_setup/ss_triangle.h index 007fa2e9141..ac553cbd018 100644 --- a/src/mesa/swrast_setup/ss_triangle.h +++ b/src/mesa/swrast_setup/ss_triangle.h @@ -29,7 +29,7 @@ #ifndef SS_TRIANGLE_H #define SS_TRIANGLE_H -#include "ss_context.h" +#include "main/mtypes.h" void _swsetup_trifuncs_init( GLcontext *ctx ); diff --git a/src/mesa/swrast_setup/ss_vb.h b/src/mesa/swrast_setup/ss_vb.h index 2ad1f56f396..944a3b78d8c 100644 --- a/src/mesa/swrast_setup/ss_vb.h +++ b/src/mesa/swrast_setup/ss_vb.h @@ -30,7 +30,6 @@ #define SS_VB_H #include "main/mtypes.h" -#include "swrast_setup.h" void _swsetup_vb_init( GLcontext *ctx ); void _swsetup_choose_rastersetup_func( GLcontext *ctx ); diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index ebaae6335b9..258906f7956 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -53,9 +53,7 @@ #include "main/bitset.h" #include "main/mtypes.h" -#include "math/m_matrix.h" #include "math/m_vector.h" -#include "math/m_xform.h" #include "vbo/vbo.h" diff --git a/src/mesa/tnl/t_rasterpos.c b/src/mesa/tnl/t_rasterpos.c index 3596d162b23..d82d5b50736 100644 --- a/src/mesa/tnl/t_rasterpos.c +++ b/src/mesa/tnl/t_rasterpos.c @@ -25,7 +25,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/feedback.h" #include "main/light.h" #include "main/macros.h" diff --git a/src/mesa/tnl/t_vb_cull.c b/src/mesa/tnl/t_vb_cull.c index 712901acf30..22df7166735 100644 --- a/src/mesa/tnl/t_vb_cull.c +++ b/src/mesa/tnl/t_vb_cull.c @@ -28,7 +28,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "main/imports.h" #include "main/mtypes.h" diff --git a/src/mesa/tnl/t_vb_fog.c b/src/mesa/tnl/t_vb_fog.c index 4a0e6ad4f99..9faae24ec6d 100644 --- a/src/mesa/tnl/t_vb_fog.c +++ b/src/mesa/tnl/t_vb_fog.c @@ -28,7 +28,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "main/imports.h" #include "main/mtypes.h" diff --git a/src/mesa/tnl/t_vb_normals.c b/src/mesa/tnl/t_vb_normals.c index 61ac4095733..c2aa655674c 100644 --- a/src/mesa/tnl/t_vb_normals.c +++ b/src/mesa/tnl/t_vb_normals.c @@ -28,7 +28,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "main/imports.h" #include "main/mtypes.h" diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c index 614c67d05eb..f3a338ef1ed 100644 --- a/src/mesa/tnl/t_vb_program.c +++ b/src/mesa/tnl/t_vb_program.c @@ -33,9 +33,9 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "main/imports.h" +#include "math/m_xform.h" #include "program/prog_instruction.h" #include "program/prog_statevars.h" #include "program/prog_execute.h" diff --git a/src/mesa/tnl/t_vb_render.c b/src/mesa/tnl/t_vb_render.c index c1bebc99423..7d991009a14 100644 --- a/src/mesa/tnl/t_vb_render.c +++ b/src/mesa/tnl/t_vb_render.c @@ -44,6 +44,7 @@ #include "main/macros.h" #include "main/imports.h" #include "main/mtypes.h" +#include "math/m_xform.h" #include "t_pipeline.h" diff --git a/src/mesa/tnl/t_vb_texgen.c b/src/mesa/tnl/t_vb_texgen.c index 9ef13bc96d8..950e0f54e9f 100644 --- a/src/mesa/tnl/t_vb_texgen.c +++ b/src/mesa/tnl/t_vb_texgen.c @@ -37,7 +37,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "main/imports.h" #include "main/mtypes.h" diff --git a/src/mesa/tnl/t_vb_texmat.c b/src/mesa/tnl/t_vb_texmat.c index 83688290e59..985d137e5cc 100644 --- a/src/mesa/tnl/t_vb_texmat.c +++ b/src/mesa/tnl/t_vb_texmat.c @@ -28,7 +28,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "main/imports.h" #include "main/mtypes.h" diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c index a2753425633..453479227b7 100644 --- a/src/mesa/tnl/t_vb_vertex.c +++ b/src/mesa/tnl/t_vb_vertex.c @@ -28,7 +28,6 @@ #include "main/glheader.h" #include "main/colormac.h" -#include "main/context.h" #include "main/macros.h" #include "main/imports.h" #include "main/mtypes.h" diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 045af46da8d..84ae1b87f93 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -27,7 +27,7 @@ #include "main/glheader.h" #include "main/bufferobj.h" -#include "main/context.h" +#include "main/compiler.h" #include "main/enums.h" #include "main/state.h" diff --git a/src/mesa/vf/vf.h b/src/mesa/vf/vf.h index 83d7547619c..5fe392bbe51 100644 --- a/src/mesa/vf/vf.h +++ b/src/mesa/vf/vf.h @@ -28,7 +28,7 @@ #ifndef VF_VERTEX_H #define VF_VERTEX_H -#include "main/mtypes.h" +#include "main/glheader.h" #include "math/m_vector.h" enum { diff --git a/src/mesa/vf/vf_generic.c b/src/mesa/vf/vf_generic.c index 0af8893c302..95a317e99db 100644 --- a/src/mesa/vf/vf_generic.c +++ b/src/mesa/vf/vf_generic.c @@ -29,6 +29,7 @@ #include "main/glheader.h" #include "main/context.h" #include "main/colormac.h" +#include "main/macros.h" #include "main/simple_list.h" #include "vf/vf.h" |